
Тетрис, классическая игра с падающими фигурами, идеально подходит для изучения базовых принципов программирования на Python. В процессе разработки вы освоите работу с библиотекой pygame, создание игровых сеток, обработку коллизий и управление скоростью падения фигур.
Прежде чем приступать к коду, необходимо определить структуру игрового поля. Рекомендуется использовать двумерный список размером 20×10, где каждая ячейка хранит состояние: пусто или занято. Это позволит легко реализовать проверку столкновений и удаление заполненных линий без избыточных вычислений.
Для управления фигурами используйте набор массивов, описывающих все возможные вращения каждой формы. Оптимально заранее подготовить 7 стандартных фигур Тетриса с четырьмя состояниями поворота, чтобы минимизировать вычисления во время игры и ускорить отклик на нажатия клавиш.
Логику падения лучше реализовать через таймер, который изменяет координату Y фигуры с заданной периодичностью. Частота обновления должна зависеть от текущего уровня игры: начните с интервала 500 мс и постепенно уменьшайте до 100 мс для ускорения динамики.
Обработка пользовательского ввода включает перемещение влево, вправо, ускоренное падение и поворот. Для точного контроля состояния поля рекомендуется проверять допустимость каждого действия перед его выполнением. Это предотвращает «залипание» фигур и ошибки коллизий.
Настройка среды Python и установка Pygame
Для разработки Тетриса на Python необходимо использовать версию Python 3.10 или выше. Проверить текущую версию можно командой:
python --version
Если Python не установлен, скачайте официальный установщик с python.org. При установке обязательно отметьте опцию «Add Python to PATH».
Рекомендуется создать виртуальное окружение для проекта, чтобы изолировать зависимости. Для этого используйте:
python -m venv tetris_env
Для активации окружения на Windows:
tetris_env\Scripts\activate
На macOS/Linux:
source tetris_env/bin/activate
Установка библиотеки Pygame выполняется через pip. Рекомендуется использовать конкретную версию для стабильности:
pip install pygame==2.5.2
Проверить успешную установку можно запуском интерпретатора Python и выполнением:
import pygame
print(pygame.ver)
Для удобства управления зависимостями создайте файл requirements.txt с содержимым:
| Пакет | Версия |
|---|---|
| pygame | 2.5.2 |
Установка всех зависимостей из файла выполняется командой:
pip install -r requirements.txt
После этих шагов среда готова для разработки Тетриса с Pygame.
Создание игрового окна и базовой сетки поля
Для создания игрового окна используем библиотеку pygame. Размер окна рекомендуется установить как 300×600 пикселей, чтобы сохранить пропорцию блока 30×30 пикселей при стандартной сетке 10×20.
Инициализация окна выполняется через pygame.init() и pygame.display.set_mode((300, 600)). Установка заголовка окна делается функцией pygame.display.set_caption("Tetris").
Базовая сетка поля представлена двумерным списком размером 20×10, где каждая ячейка хранит цвет блока или None для пустой клетки. Создание сетки реализуется так: grid = [[None for _ in range(10)] for _ in range(20)].
Отрисовка сетки осуществляется циклом по строкам и столбцам. Каждой ячейке присваивается прямоугольник через pygame.Rect(col*30, row*30, 30, 30). Цвет блока определяется значением в сетке: если None, используется фон, иначе цвет фигуры.
Для визуального разделения ячеек полезно добавить обводку 1 пиксель, используя pygame.draw.rect(screen, (128,128,128), rect, 1). Это создаёт чёткое отображение каждой ячейки без использования сложных стилей или графических ресурсов.
Главный цикл игры должен содержать обновление окна с pygame.display.update() и обработку событий pygame.event.get() для корректного закрытия игры.
Определение форм фигур и их координат
В Тетрисе используются семь стандартных фигур: I, O, T, S, Z, J и L. Каждая фигура описывается набором координат её блоков относительно центральной точки поворота. Для удобства задаём координаты как список кортежей (x, y).
Фигура I: [(0, -1), (0, 0), (0, 1), (0, 2)] – вертикальная линия из четырёх блоков. При вращении координаты меняются на [(-1, 0), (0, 0), (1, 0), (2, 0)].
Фигура O: [(0, 0), (1, 0), (0, 1), (1, 1)] – квадрат 2×2. Вращение не изменяет координаты.
Фигура T: [(0, 0), (-1, 0), (1, 0), (0, 1)] – Т-образная форма. Вращения задаются последовательной перестановкой координат по часовой стрелке: [(0,0),(0,-1),(0,1),(1,0)], [(0,0),(-1,0),(1,0),(0,-1)], [(0,0),(0,-1),(0,1),(-1,0)].
Фигура S: [(0, 0), (1, 0), (0, 1), (-1, 1)] – S-образная. При повороте на 90° координаты становятся [(0,0),(0,1),(1,0),(1,-1)].
Фигура Z: [(0, 0), (-1, 0), (0, 1), (1, 1)] – зеркальная S. Поворот на 90°: [(0,0),(0,1),(-1,0),(-1,-1)].
Фигура J: [(0, 0), (-1, 0), (0, 1), (0, 2)] – угол с выступающим блоком слева. Вращения: [(0,0),(0,1),(1,0),(2,0)], [(0,0),(0,-1),(0,-2),(1,0)], [(0,0),(-2,0),(-1,0),(0,1)].
Фигура L: [(0, 0), (1, 0), (0, 1), (0, 2)] – угол с выступающим блоком справа. Вращения: [(0,0),(0,1),(-1,0),(-2,0)], [(0,0),(0,-1),(0,-2),(-1,0)], [(0,0),(2,0),(1,0),(0,1)].
Для хранения фигур в коде удобно использовать словарь с ключами по названиям фигур и значениями – списками координат для каждого состояния вращения. Это позволяет быстро получать новые координаты при повороте и проверять столкновения с границами игрового поля.
Для начала отрисовки фигуры в игровом поле выбирается верхняя центральная позиция, к которой прибавляются координаты блоков фигуры. Проверка доступности позиции проводится до отрисовки, чтобы избежать наложений и выхода за границы.
Реализация движения фигур по горизонтали и вертикали

Для движения фигур в Тетрисе необходимо поддерживать текущие координаты блока в виде пары значений (x, y), где x – горизонтальное смещение, y – вертикальное. Каждое обновление состояния игры начинается с проверки возможности перемещения фигуры на одну позицию вниз или влево/вправо.
Горизонтальное движение реализуется через функции сдвига x: при нажатии клавиши влево x уменьшается на 1, при нажатии вправо – увеличивается на 1. Перед изменением координаты нужно проверить коллизии с границами игрового поля и уже зафиксированными фигурами. Для этого используют функцию проверки столкновений, которая принимает новую позицию фигуры и возвращает True при невозможности движения.
Вертикальное движение осуществляется автоматически с определенной частотой времени или при нажатии клавиши «вниз». При каждом шаге y увеличивается на 1, после чего выполняется проверка столкновения. Если движение невозможно, фигура фиксируется в текущем положении, и создается новая фигура сверху.
Для ускоренного падения удобно вводить переменную скорости падения, задаваемую интервалом обновления координаты y. Например, базовая скорость равна 500 миллисекундам, при удержании клавиши «вниз» интервал уменьшается до 100 миллисекунд. Это позволяет реализовать плавное и управляемое движение по вертикали.
Рекомендуется вынести проверку границ поля и столкновений в отдельную функцию, чтобы избежать дублирования кода при горизонтальном и вертикальном перемещении. Функция должна проверять каждый элемент фигуры на выход за пределы массива игрового поля и на совпадение с уже занятыми клетками.
Для горизонтального движения также важно учитывать размеры фигуры: при сдвиге нужно проверять не только позицию центрального блока, но все составляющие клетки, чтобы фигура не «врезалась» в стенки или другие фигуры. Аналогично проверяется вертикальное падение для корректного завершения движения и фиксации фигуры.
Добавление вращения фигур и проверка столкновений

Для реализации вращения фигур в Тетрисе используйте представление фигуры как двумерного массива 4×4. Каждый элемент массива может быть 0 (пустая клетка) или 1 (занятая). Вращение выполняется путем транспонирования матрицы и последующего отражения по вертикали: rotated = [list(row) for row in zip(*shape[::-1])].
Проверка столкновений проводится после каждого перемещения или вращения. Для этого создайте функцию, которая перебирает все клетки фигуры и проверяет, не выходит ли координата за пределы игрового поля и не пересекается ли с уже размещенными блоками: if field[y+dy][x+dx]: return True. Если функция возвращает True, отмените вращение или движение.
Для предотвращения застревания фигуры у стен используйте смещение по горизонтали при вращении. Сначала пробуйте вращение без смещения, затем сдвиг на ±1 и ±2 ячейки. Если ни один вариант не проходит проверку столкновений, вращение отменяется.
Оптимально хранить для каждой фигуры все четыре состояния после вращения заранее, чтобы ускорить проверку столкновений и снизить нагрузку на CPU.
Обработка удаления заполненных линий и подсчета очков

В Тетрисе ключевой механизм – проверка заполненных линий после размещения фигуры. Для этого обычно используется двумерный список (матрица) размером 20×10, где 0 обозначает пустую ячейку, а любое другое число – занятую.
Алгоритм удаления линий:
- Итерируем по каждой строке с низа вверх.
- Проверяем, содержит ли строка только ненулевые значения. Если да, она считается полной.
- Удаляем полную строку с помощью
del field[row]. - Добавляем сверху пустую строку
[0]*10, чтобы сохранить размер матрицы.
Для подсчета очков применяется стандартная схема:
- 1 линия – 100 очков
- 2 линии – 300 очков
- 3 линии – 500 очков
- 4 линии (Тетрис) – 800 очков
Если используется множитель уровня, итоговые очки умножаются на текущий уровень.
Пример функции на Python для обработки линий:
def clear_lines(field, score, level):
lines_cleared = 0
for row in range(len(field)-1, -1, -1):
if 0 not in field[row]:
del field[row]
field.insert(0, [0]*10)
lines_cleared += 1
if lines_cleared == 1:
score += 100 * level
elif lines_cleared == 2:
score += 300 * level
elif lines_cleared == 3:
score += 500 * level
elif lines_cleared == 4:
score += 800 * level
return score
Рекомендации по оптимизации:
- Итерируйте с низа вверх, чтобы корректно обрабатывать несколько последовательных полных строк.
- Используйте отдельный счетчик
lines_clearedдля вычисления очков и контроля повышения уровня. - Минимизируйте удаление и вставку строк, заменяя их срезами при больших матрицах.
- Не храните фигуры в матрице после их «замораживания», это ускоряет проверку линий.
Настройка скорости игры и уровней сложности

В Тетрисе скорость падения фигур напрямую влияет на сложность. Для точного контроля скорости используйте переменную fall_speed, которая задается в миллисекундах между перемещениями фигуры вниз.
Пример базовой настройки скорости по уровням:
- Уровень 1: 800 мс
- Уровень 2: 650 мс
- Уровень 3: 500 мс
- Уровень 4: 400 мс
- Уровень 5: 300 мс
Уровень повышается после очистки определенного числа линий, например, каждые 10 линий:
- Следите за счетчиком очищенных линий
lines_cleared. - После достижения порога увеличивайте уровень и уменьшайте
fall_speedна 10–20%. - Обеспечьте минимальное значение скорости, например, 100 мс, чтобы игра оставалась управляемой.
Для плавного увеличения сложности можно использовать формулу:
fall_speed = max(100, 800 - (level - 1) * 75)
Это снижает скорость на 75 мс с каждым уровнем, но не ниже 100 мс.
Дополнительно можно вводить отдельные параметры для «мягкого» и «жесткого» режимов:
- Мягкий режим: стартовая скорость 1000 мс, шаг изменения 50 мс.
- Жесткий режим: стартовая скорость 600 мс, шаг изменения 100 мс.
Обработка завершения игры и отображение результатов

В Тетрисе игра завершается, когда новая фигура не помещается на стартовой позиции. Для отслеживания этого создайте функцию check_game_over(), которая проверяет заполнение верхних строк поля. Возврат True означает конец игры.
Для отображения результатов используйте отдельную переменную score и счётчик lines_cleared. При завершении игры сохраните текущие значения и выведите их через print() в консоль или в текстовую область интерфейса.
Рекомендуется фиксировать рекорд за сессию. Для этого создайте файл highscore.txt, читайте его при запуске игры и обновляйте при достижении нового максимума. Пример проверки рекорда: если score > highscore, перезаписываем файл и уведомляем игрока.
Дополнительно полезно реализовать опцию перезапуска игры без выхода из программы. При этом обнуляйте score, lines_cleared и поле, а рекорд сохраняйте отдельно.
Вопрос-ответ:
Какие библиотеки нужны для создания Тетриса на Python?
Для разработки Тетриса чаще всего используют библиотеку Pygame, которая упрощает работу с графикой и обработкой событий клавиатуры. Pygame предоставляет функции для отображения фигур, отрисовки сетки, а также управления скоростью падения блоков. Иногда также применяют стандартные модули Python, такие как random для случайного выбора фигур и time для контроля времени между падениями.
Как реализовать движение фигур влево и вправо?
Для движения блоков по горизонтали обычно создают переменную, хранящую координату X текущей фигуры. При нажатии клавиш влево или вправо эта координата изменяется на единицу или на ширину одного блока. После изменения координаты важно проверить, не вышла ли фигура за пределы игрового поля и не пересекает ли она уже установленные фигуры. Если пересечения нет, позиция фигуры обновляется на экране.
Как сделать проверку на заполнение линии и её удаление?
Проверка заполнения линии выполняется по каждой строке игрового поля. Строка считается заполненной, если все её ячейки заняты блоками. Когда обнаруживается заполненная строка, её удаляют, а все блоки выше опускают на одну строку вниз. Такой подход позволяет поддерживать непрерывный процесс игры и добавляет сложность по мере увеличения скорости падения фигур.
Каким образом можно увеличить скорость падения фигур по мере прогресса игры?
Скорость падения можно регулировать с помощью переменной, задающей интервал времени между обновлениями позиции фигуры. Например, на начальном этапе фигура опускается на одну строку каждые 500 миллисекунд. После набора определённого количества очков или пройденных линий интервал уменьшают, например до 400 или 300 миллисекунд. Это создаёт постепенное усложнение игры, требуя от игрока более быстрого реагирования. При этом важно следить, чтобы минимальный интервал оставался комфортным для управления, иначе игра может стать нечитаемой.
