Тетрис на C++ с библиотекой SFML2

Содержание
Введение
Код
Другие статьи о С++

Введение

Banner image

Код

#include <SFML/Graphics.hpp> #include <iostream> #include <time.h> #include <string> const int field_height = 25; // высота игрового поля const int field_width = 15; // ширина игрового поля int field[field_height][field_width] { }; // игровое поле // Массив фигурок-тетрамино int figures[7][4] = { 1,3,5,7, // I 2,4,5,7, // S 3,5,4,6, // Z 3,5,4,7, // T 2,3,5,7, // L 3,5,7,6, // J 2,3,4,5, // O }; int checkLine(int& userPoints) { //----ПРОВЕРКА ЛИНИИ----// int k = field_height - 1; // строка k - самая нижняя for (int i = field_height - 1; i > 0; i--) // i пробегает все строки снизу вверх. // в начале k и i совпадают { int count = 0; for (int j = 0; j < field_width; j++) { if (field[i][j]) { count++; } field[k][j] = field[i][j]; } if (count < field_width) { k--; } else { userPoints += 1; } // k уменьшится только если линия не занята полностью // если линия занята полностью, то следующее i // уже соответствует более высокой строке // а k всё ещё на полной строке // строка k будет перезаписана следующей строкой i } return userPoints; } class Tetramino { public: int color { }; int type { }; int blockPositions[4] { }; struct Coordinates { int x; int y; }; Coordinates coordinates[4]{ }; int figures[7][4] = { 1,3,5,7, // I 2,4,5,7, // S 3,5,4,6, // Z 3,5,4,7, // T 2,3,5,7, // L 3,5,7,6, // J 2,3,4,5, // O }; void create() { std::cout << "new tetramino created" << std::endl; color = 1 + rand() % 7; type = rand() % 7; for (int i = 0; i < 4; i++) { blockPositions[i] = figures[type][i]; } for (int i = 0; i < 4; i++) { coordinates[i].x = blockPositions[i] % 2 + 7; // сдвигаем стартовую позицию ближе к центру с помощью + 7 coordinates[i].y = blockPositions[i] / 2; } }; void draw(sf::RenderWindow& thatWindow, sf::Sprite& thatSprite, int marginLeft, int marginTop) { // Рисуем тетрамино из класса Tetramino for (int i = 0; i < 4; i++) { // Разукрашиваем тетрамино thatSprite.setTextureRect(sf::IntRect(color * 18, 0, 18, 18)); // Устанавливаем позицию каждого кусочка тетрамино thatSprite.setPosition(coordinates[i].x * 18, coordinates[i].y * 18); thatSprite.move(marginLeft, marginTop); // смещение // Отрисовка спрайта thatWindow.draw(thatSprite); } }; bool check() { for (int i = 0; i < 4; i++) { if (coordinates[i].x < 0 || coordinates[i].x >= field_width || coordinates[i].y >= field_height) { std::cout << std::endl << "field X" << coordinates[i].x << "Y " << coordinates[i].y << "is out of board" << std::endl; return false; } else if (field[coordinates[i].y][coordinates[i].x]) { std::cout << std::endl << "field X" << coordinates[i].x << "Y " << coordinates[i].y << "is occupied" << std::endl; return false; } } return true; } void moveDown(sf::RenderWindow& thatWindow) { int x[4]{}; int y[4]{}; for (int i = 0; i < 4; i++) { y[i] = coordinates[i].y; x[i] = coordinates[i].x; } for (int i = 0; i < 4; i++) { coordinates[i].y += 1; } if (check() == false) { std::cout << "stop here" << std::endl; for (int i = 0; i < 4; i++) { coordinates[i].y = y[i]; std::cout << "coloring the field" << std::endl; field[y[i]][x[i]] = color; } create(); if (check() == false) { std::cout << "GAME OVER " << std::endl; thatWindow.close(); } } else { ; } } void moveHoriz(sf::RenderWindow& thatWindow, int direction) { int x[4]{}; int y[4]{}; for (int i = 0; i < 4; i++) { y[i] = coordinates[i].y; x[i] = coordinates[i].x; } for (int i = 0; i < 4; i++) { coordinates[i].x += direction; } if (check() == false) { for (int i = 0; i < 4; i++) { coordinates[i].x = x[i]; } } else { ; } } void rotate() { int x[4]{}; int y[4]{}; for (int i = 0; i < 4; i++) { y[i] = coordinates[i].y; x[i] = coordinates[i].x; } int originX = coordinates[1].x; // указываем X центра вращения int originY = coordinates[1].y; // указываем Y центра вращения for (int i = 0; i < 4; i++) { int dy = coordinates[i].y - originY; // y - y0 int dx = coordinates[i].x - originX; // x - x0 coordinates[i].x = originX - dy; // x_2 = x_0 - dy coordinates[i].y = originY + dx; // y_2 = y_0 + dx } if (check() == false) { for (int i = 0; i < 4; i++) { coordinates[i].x = x[i]; } } else { ; } } }; int main() { srand(time(0)); int window_width{ 640 }; int window_height{ 960 }; int userPoints{ 0 }; Tetramino tetramino; tetramino.create(); sf::RenderWindow window(sf::VideoMode(window_width, window_height), "HH Tetris!"); // Создание и загрузка текстуры sf::Texture texture, texture_background, texture_frame; texture.loadFromFile("C:\Users\andrei\source\repos\tetris\images\corona_tiles.png"); texture_background.loadFromFile("C:\Users\andrei\source\repos\tetris\images\background.png"); texture_frame.loadFromFile("C:\Users\andrei\source\repos\tetris\images\frame.png"); // Создание спрайта sf::Sprite sprite(texture), sprite_background(texture_background), sprite_frame(texture_frame); // Вырезаем из спрайта отдельный квадратик размером 18х18 пикселей sprite.setTextureRect(sf::IntRect(0, 0, 18, 18)); // Переменные для таймера и задержки float timer = 0; float delay = 0.3; // Часы (таймер) sf::Clock clock; // Главный цикл приложения: выполняется, пока открыто окно while (window.isOpen()) { // Получаем время, прошедшее с начала отсчёта, и конвертируем его в секунды float time = clock.getElapsedTime().asSeconds(); clock.restart(); timer += time; // Обрабатываем события в цикле sf::Event event; while (window.pollEvent(event)) { // Пользователь нажал на «крестик» и хочет закрыть окно? if (event.type == sf::Event::Closed) // тогда закрываем его window.close(); // Была ли нажата клавиша на клавиатуре? if (event.type == sf::Event::KeyPressed) { // Эта кнопка – стрелка влево? if (event.key.code == sf::Keyboard::Left) { tetramino.moveHoriz(window, -1); } // Или стрелка вправо? else if (event.key.code == sf::Keyboard::Right) { tetramino.moveHoriz(window, 1); } // Или может стрелка вверх? else if (event.key.code == sf::Keyboard::Up) { tetramino.rotate(); } } // Нажали на кнопку "Вниз" ? Ускоряем падение тетрамино if (sf::Keyboard::isKeyPressed(sf::Keyboard::Down)) delay = 0.05; } // Движение тетрамино вниз («тик» таймера) if (timer > delay) { tetramino.moveDown(window); timer = 0; } checkLine(userPoints); delay = 0.3; //----ОТРИСОВКА----// // Задаём цвет фона - белый window.clear(sf::Color::White); // Отрисовка фона //window.draw(sprite_background); int tetrisFeildTop{ 150 }; int tetrisFeildLeft{ 185 }; for (int varHeight = 0; varHeight < field_height; varHeight++) { for (int j = 0; j < field_width; j++) { if (field[varHeight][j] == 0) { //std::cout << "empty field" << std::endl; sprite.setTextureRect(sf::IntRect(8 * 18, 0, 18, 18)); sprite.setPosition(tetrisFeildLeft + j * 18, tetrisFeildTop + varHeight * 18); // Отрисовка спрайта window.draw(sprite); } else { sprite.setTextureRect(sf::IntRect(field[varHeight][j] * 18, 0, 18, 18)); // значение каждого поля field[varHeight][j] это цвет, его мы используем //для выбора цветного квадратика из спрайта } sprite.setPosition(tetrisFeildLeft + j * 18, tetrisFeildTop + varHeight * 18); //sprite.move(28, 31); // смещение window.draw(sprite); } } // Рисуем тетрамино с помощью метода draw из класса Tetramino tetramino.draw(window, sprite, tetrisFeildLeft, tetrisFeildTop); // Отрисовка фрейма //window.draw(sprite_frame); sf::Font font; if (!font.loadFromFile("C:\Development\Fonts\Roboto\Roboto-Regular.ttf")) { // error... } sf::Text text; // select the font text.setFont(font); // font is a sf::Font std::string userPointsString = "Score: " + std::to_string(userPoints); // set the string to display text.setString(userPointsString); // set the character size text.setCharacterSize(24); // in pixels, not points! // set the color text.setFillColor(sf::Color::Blue); // set the text style text.setStyle(sf::Text::Bold | sf::Text::Underlined); text.setPosition(190.f, 10.f); window.draw(text); // Отрисовка окна window.display(); } return 0; }

Article author: Andrei Olegovich

Похожие статьи
Перегрузка функций
-c: Компиляция
Разбиение кода на части
Вектор
Указатели
Классы
SFML
Тетрис на C++ с библиотекой SFML2
SDL
Массив Структур
Как узнать тип переменной C++
Решение задач на C++
Как создать пустую строку в C++
Запросы к REST API на C++
Ошибки C++
Make

Search this site

Subscribe to Telegram channel @aofeed to follow new articles and updates to old ones

Go to channel

@aofeed

Ask a question in the Telegram group

@aofeedchat

Contacts and cooperation:
I recommend our hosting beget.ru
Write to info@urn.su if you:
1. Want to write an article for our site or translate an article into your native language.
2. Want to place thematically relevant ads on the site.
3. Ads on my site pass maximum censorship. If you see an ad block unsuitable for school-age children, shocking or misleading - please contact us by e-mail
4. Found a mistake, inaccuracy, bug, etc. on the site. ... .......
5. Articles can be shared on social media by clicking a network icon: