Тетрис — классическая игра, созданная Алексеем Пажитновым. Она остается актуальной и интересной до сих пор. Почему бы нам ее не реализовать в качестве развлечения?
Я уже подготовил некий прототип, поэтому предлагаю cкачать исходники тетриса на C++, чтобы вы могли с ними экспериментировать. Проект демонстрирует общую механику игры без лишних деталей. Внешний вид приложения вы можете оценить на скриншоте слева.
Управление стандартное:
- Стрелки влево/вправо — движение в соответствующих направлениях;
- Стрелка вверх — поворот текущего элемента против часовой стрелки;
- Стрелка вниз — ускорить падение текущего элемента;
- Space — вкл/выкл паузу.
- Escape — начать игру заново.
Архитектура приложения строится на основе паттерна MVC, с помощью которого мы уже разрабатывали игру Сапер на Python.
Чтобы обойтись без лишних сложностей, с учетом масштабов игры, использована самая примитивная структура проекта, сгенерированная прямо в QtCreator.
В скачанном архиве вы найдете следующие файлы:
- Tetris.pro — файл описания проекта;
- main.cpp — точка запуска, в которой создается и выводится на экран виджет;
- tetrismodel.(h|cpp) — реализация Модели с логикой игры. Самое интересное именно здесь;
- tetriscontroller.(h|cpp) — реализация Контроллера. Здесь вы найдете логику управления;
- tetrisview.(h|cpp) — реализация Представления. Вывод графики реализован стандартными средствами Qt на основе QPainter. Возможно, в будущем для интереса перепишем этот модуль с использованием OpenGL.
Взаимодействие между Моделью и Представлением реализовано таким образом, что при каждом изменении Модели Представление полностью перерисовывается. Это позволяет существенно упростить реализацию, поскольку на уровне Представления игра является полностью неподвижной в каждый момент времени. Конечно, можно было заняться оптимизацией и сделать перерисовку лишь тех участков, которые изменились с прошлого раза. Однако это лишь добавит нам проблем без заметного увеличения производительности на современных компьютерах.
Тетрис является динамичной игрой, поэтому необходимо предусмотреть механизм автоматического вызова функции обновления состояния. Возможно, более правильным подходом было бы использование потока с учетом приращений времени для подстраивания скорости игры под FPS. Однако в представленном проекте мы обходимся простым таймером QTimer, который срабатывает через равные интервалы. Недостатком выбранного подхода является то, что на медленных компьютерах игра будет идти медленно. Однако в первом случае мы бы получили результат не намного лучше. Игра бы шла с гарантированной скоростью, но рывками.
Важно заметить, что в коде проекта использованы некоторые возможности C++11, поэтому если возникнут проблемы, то попробуйте другой компилятор. Я собирал проект под Linux с помощью gcc 4.9.2 и Qt 4.8.6. С другой стороны, вы можете убрать фрагмент кода с использованием лямбда-функции, а также упрощенные инициализации массивов. Тогда проект соберется практически где угодно.
На этом пока что закончим. В следующий раз разберем статическую модель игры.