
Тетрис – классическая игра с падающими фигурами, которая идеально подходит для освоения основ программирования на Python. В этом руководстве будет показан точный порядок действий для реализации игры, включая генерацию фигур, управление движением и проверку столкновений. Код будет построен исключительно на стандартных возможностях Python, без использования Canvas и внешних графических библиотек.
В качестве основы рекомендуется использовать модуль curses для работы с текстовым интерфейсом терминала. Это позволит обновлять игровое поле в реальном времени и обрабатывать ввод пользователя без задержек. Вы узнаете, как создавать сетку 10×20, где каждая ячейка будет хранить состояние: пусто или заполнено частью фигуры.
Особое внимание будет уделено алгоритму вращения фигур. В Тетрисе есть семь стандартных форм, каждая из которых представлена в виде матрицы 4×4. Мы подробно разберем, как реализовать поворот на 90 градусов по часовой стрелке, проверку выхода за границы поля и столкновения с другими фигурами, чтобы движения оставались корректными.
Также руководство включает оптимальные методы подсчета очков и ускорения игры при достижении определенного уровня. Вы получите конкретные формулы для начисления очков за удаленные линии и правила увеличения скорости падения фигур по мере прогресса. В итоге вы сможете собрать полностью рабочую версию Тетриса с текстовым интерфейсом, готовую к расширению и модификации.
Создание игры Тетрис на Python: пошаговое руководство
Для разработки Тетриса на Python рекомендуется использовать библиотеку Pygame. Она обеспечивает работу с графикой, событиями клавиатуры и игровым циклом. Начнем с установки:
pip install pygame
1. Создание игрового окна:
Определяем размеры поля и размер блока. Например, поле 10×20 блоков, каждый блок 30 пикселей:
| Ширина поля | 10 блоков |
| Высота поля | 20 блоков |
| Размер блока | 30 px |
Инициализация Pygame и создание окна:
pygame.init()
screen = pygame.display.set_mode((300, 600))
2. Определение фигур:
Фигуры хранятся в виде матриц 4×4, где 1 – часть фигуры, 0 – пустое место. Пример для квадрата и линии:
| Фигура | Матрица |
| Квадрат | [[1,1],[1,1]] |
| Линия | [[1,1,1,1]] |
3. Игровой цикл:
Создается бесконечный цикл, который выполняет следующие действия: обработка событий клавиатуры, перемещение фигур, проверка столкновений, обновление экрана и задержка для контроля скорости игры.
Пример управления клавишами:
| Действие | Клавиша |
| Сдвиг влево | LEFT |
| Сдвиг вправо | RIGHT |
| Ускоренное падение | DOWN |
| Поворот | UP |
4. Проверка столкновений:
Для каждой фигуры проверяется, не выходит ли она за границы поля и не накладывается ли на уже упавшие фигуры. Используется функция, которая возвращает True при столкновении.
5. Очистка заполненных линий:
После установки фигуры проверяем каждую строку. Если строка полностью заполнена, удаляем ее и сдвигаем верхние строки вниз. Количество удаленных линий можно использовать для подсчета очков.
6. Рисование на экране:
Для каждого блока вызывается pygame.draw.rect, указываются координаты, размеры и цвет. Обновление экрана выполняется через pygame.display.update().
7. Контроль скорости игры:
Используем pygame.time.Clock() и clock.tick(FPS), где FPS задает скорость падения фигур. Для увеличения сложности FPS можно постепенно увеличивать.
8. Подсчет очков и завершение игры:
Подсчет очков ведется за каждую удаленную линию. Игра завершается, когда новая фигура не помещается на верхнюю линию поля.
Настройка среды разработки и установка необходимых библиотек
Для разработки Тетриса на Python рекомендуем использовать Python версии 3.11 или выше. Установить последнюю версию можно с официального сайта python.org. Убедитесь, что при установке активирован флажок Add Python to PATH, чтобы команды Python и pip были доступны в терминале.
В качестве среды разработки оптимально использовать Visual Studio Code или PyCharm Community Edition. В VS Code установите расширения Python и Pylance для подсветки синтаксиса и проверки типов. В PyCharm достаточно выбрать интерпретатор Python 3.11 при создании проекта.
Для работы с графикой в Тетрисе потребуется библиотека pygame. Установку выполняют через терминал командой:
pip install pygame
Проверить корректность установки можно запуском Python и вводом:
import pygame; print(pygame.ver). Если версия отображается без ошибок, библиотека готова к использованию.
Для управления зависимостями создайте виртуальное окружение командой:
python -m venv tetris_env, затем активируйте его:
tetris_env\Scripts\activate на Windows или
source tetris_env/bin/activate на macOS/Linux. Все библиотеки рекомендуется устанавливать внутри этого окружения.
Дополнительно можно использовать pylint для проверки кода на ошибки и black для автоматического форматирования. Установка:
pip install pylint black
Создание игровой сетки и визуального окна с помощью Pygame
Для начала необходимо инициализировать Pygame и задать размеры окна, соответствующие количеству блоков в сетке и размеру каждого блока. В Тетрисе стандартно используют сетку 10×20 и размер блока 30 пикселей.
import pygame
pygame.init()
block_size = 30
grid_width = 10
grid_height = 20
window_width = block_size * grid_width
window_height = block_size * grid_height
screen = pygame.display.set_mode((window_width, window_height))
pygame.display.set_caption("Тетрис")
Создание сетки выполняется с помощью двухмерного списка, где каждый элемент представляет ячейку: пустую или занятую.
grid = [[0 for _ in range(grid_width)] for _ in range(grid_height)]
Для визуализации сетки рекомендуется отдельная функция, которая рисует линии и блоки в зависимости от состояния ячеек.
def draw_grid(surface, grid):
for y in range(len(grid)):
for x in range(len(grid[y])):
rect = pygame.Rect(x * block_size, y * block_size, block_size, block_size)
if grid[y][x] != 0:
pygame.draw.rect(surface, grid[y][x], rect)
pygame.draw.rect(surface, (40, 40, 40), rect, 1) # линии сетки
Функция `draw_grid` обеспечивает четкую визуальную структуру и позволяет динамически обновлять положение фигур при их движении.
Для поддержания стабильной работы окна важно использовать игровой цикл с ограничением FPS:
clock = pygame.time.Clock()
running = True
while running:
screen.fill((0, 0, 0))
draw_grid(screen, grid)
pygame.display.update()
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
pygame.quit()
Рекомендуется хранить цвета блоков в словаре или списке, чтобы легко назначать их фигурам и обеспечивать визуальную консистентность.
- Определите цвет для каждого типа тетромино.
- Используйте отдельные константы для фона и линий сетки.
- Обновляйте экран только после внесения изменений в сетку, чтобы уменьшить нагрузку на процессор.
Такой подход создает четкую и масштабируемую основу для отображения всех элементов Тетриса и управления их визуальными изменениями.
Определение фигур Тетриса и их поворотов в коде
Каждая фигура Тетриса представлена матрицей 4×4, где 1 обозначает занятую клетку, а 0 – пустую. Для удобства реализации все фигуры сохраняются как список из нескольких состояний, отражающих повороты на 90°.
Пример кода для определения фигур:
figures = {
"I": [
[[0, 0, 0, 0],
[1, 1, 1, 1],
[0, 0, 0, 0],
[0, 0, 0, 0]],
[[0, 1, 0, 0],
[0, 1, 0, 0],
[0, 1, 0, 0],
[0, 1, 0, 0]]
],
"O": [
[[0, 0, 0, 0],
[0, 1, 1, 0],
[0, 1, 1, 0],
[0, 0, 0, 0]]
],
"T": [
[[0, 0, 0, 0],
[1, 1, 1, 0],
[0, 1, 0, 0],
[0, 0, 0, 0]],
[[0, 1, 0, 0],
[1, 1, 0, 0],
[0, 1, 0, 0],
[0, 0, 0, 0]],
[[0, 1, 0, 0],
[1, 1, 1, 0],
[0, 0, 0, 0],
[0, 0, 0, 0]],
[[0, 1, 0, 0],
[0, 1, 1, 0],
[0, 1, 0, 0],
[0, 0, 0, 0]]
]
}
Для поворота фигуры используется циклический переход между элементами списка. Индекс текущего состояния увеличивается на 1 и берется по модулю длины списка состояний. Это исключает необходимость динамического вычисления поворотов и предотвращает ошибки смещения.
Для проверки коллизий при повороте достаточно временно применить следующий индекс состояния и проверить, не выходит ли фигура за границы поля или не пересекается с другими фигурами. Если проверка не проходит, индекс откатывается.
Рекомендуется хранить фигуры в виде констант, чтобы ускорить доступ и исключить случайное изменение структуры. Каждое состояние матрицы должно быть квадратным 4×4, даже если фигура занимает меньше ячеек, чтобы упростить алгоритмы отображения и поворота.
Реализация падения фигур и управления ими с клавиатуры

Для реализации падения фигур в Тетрис на Python используйте матрицу игрового поля и объект текущей фигуры с координатами верхнего левого угла. Каждую итерацию игрового цикла проверяйте возможность смещения фигуры на одну клетку вниз. Если смещение невозможно из-за границ поля или уже занятых клеток, фиксируйте фигуру в матрице и создавайте новую.
Для управления фигурами с клавиатуры применяйте библиотеку keyboard или pynput. Обработчики событий должны реагировать на стрелки: ← и → для горизонтального перемещения, ↑ для вращения, ↓ для ускоренного падения. Перед перемещением проверяйте столкновения с границами и другими фигурами.
Вращение реализуйте через поворот матрицы фигуры на 90° по часовой стрелке. После вращения проверяйте корректность положения: при столкновении откатывайте фигуру в исходное положение или применяйте смещение влево/вправо на ближайшие свободные клетки, чтобы избежать застревания у стены.
Для плавного падения используйте таймер или задержку в основном цикле. Например, метод time.sleep() с интервалом 0.5 секунды для стандартного падения и меньшим интервалом при удержании клавиши вниз. Состояние нажатых клавиш сохраняйте в словаре, чтобы можно было одновременно обрабатывать горизонтальное смещение и ускоренное падение.
После фиксации фигуры проверяйте строки на заполнение. Удаляйте полные строки и сдвигайте верхние вниз. Это влияет на скорость падения новых фигур: увеличивайте интервал времени падения по мере прогрессирования игры для повышения сложности.
Проверка столкновений фигур с границами и другими блоками

Основные моменты проверки:
- Границы поля: игровое поле обычно представлено матрицей размером 20×10. Проверка заключается в том, что ни один блок фигуры не выходит за пределы индексов матрицы (0 ≤ x < 10, 0 ≤ y < 20).
- Другие фигуры: каждая ячейка матрицы содержит 0, если пустая, и 1, если занята. Столкновение происходит, когда блок фигуры перемещается в ячейку с значением 1.
Пример функции проверки столкновений для фигуры:
def collision_check(shape, offset, board):
off_x, off_y = offset
for y, row in enumerate(shape):
for x, cell in enumerate(row):
if cell:
new_x = x + off_x
new_y = y + off_y
if new_x < 0 or new_x >= len(board[0]) or new_y >= len(board):
return True
if board[new_y][new_x]:
return True
return False
Рекомендации при реализации:
- Проверять столкновение перед каждым перемещением фигуры вниз, влево, вправо или при вращении.
- Использовать отдельную копию фигуры для проверки вращения, чтобы избежать изменения исходной матрицы при невозможном повороте.
- Оптимизировать проверку, ограничивая её только областью, куда фигура может попасть при текущем действии, чтобы не проверять весь массив поля.
- Сохранять последовательность проверок: сначала границы, затем столкновение с другими блоками, чтобы избежать ошибок при одновременном выходе за границу и пересечении с другими фигурами.
Корректная проверка столкновений обеспечивает стабильное поведение игры и предотвращает наложение блоков или выход за пределы поля.
Удаление заполненных линий и подсчет очков
Для удаления заполненных линий в Тетрисе создайте функцию, которая проверяет каждую строку игрового поля на наличие полного заполнения блоками. Используйте цикл от нижней строки к верхней, чтобы корректно сдвигать оставшиеся линии вниз после удаления. Например, если игровое поле представлено списком списков: board[y][x], строка считается полной, если all(cell != 0 for cell in board[y]).
Удаление строки выполняется через del board[y] и вставку пустой строки сверху: board.insert(0, [0]*width). Это обеспечивает сохранение размеров поля и корректное смещение всех блоков выше удаленной линии.
Подсчет очков лучше реализовать через зависимость от количества одновременно удаленных линий. Классическая система начисления очков: 1 линия – 100, 2 линии – 300, 3 линии – 500, 4 линии (Тетрис) – 800. Такой подход стимулирует стратегическое планирование комбинаций.
Для учета прогрессии сложности можно умножать очки на текущий уровень игрока: score += points * level. После удаления линий рекомендуется обновлять счет и проверять возможность повышения уровня, чтобы ускорять падение фигур и повышать сложность.
Оптимизация функции удаления линий возможна через генераторы списков: создавать новое игровое поле, включающее только неполные строки, а сверху добавлять пустые. Это снижает количество операций с памятью при больших полях.
Добавление уровней сложности и ускорения падения фигур

Для управления уровнем сложности создайте переменную level, которая увеличивается после каждых 10 очищенных линий. В Python это можно реализовать так: level = cleared_lines // 10 + 1.
Скорость падения фигур регулируется интервалом таймера. В библиотеке pygame используйте событие pygame.USEREVENT с таймером pygame.time.set_timer(DROP_EVENT, drop_interval). Начальный интервал можно задать 1000 мс.
Для ускорения падения с ростом уровня применяйте формулу drop_interval = max(100, 1000 - (level - 1) * 100). Это уменьшает интервал на 100 мс за каждый уровень, но не опускает ниже 100 мс, чтобы сохранить управляемость.
Чтобы реализовать ускорение при удержании клавиши вниз, добавьте проверку события KEYDOWN для K_DOWN и временно уменьшайте drop_interval на 50–70%:
if event.key == K_DOWN: drop_interval = max(50, drop_interval // 2)
После отпускания клавиши восстанавливайте интервал: drop_interval = base_interval - (level - 1) * 100. Это обеспечит плавный контроль и предотвращает мгновенное падение через весь экран.
Для визуальной обратной связи можно отображать текущий уровень и скорость падения через текстовые элементы: screen.blit(font.render(f'Level: {level}', True, (255,255,255)), (10,10)).
Комбинация автоматического увеличения уровня и ручного ускорения при удержании клавиши позволяет создать динамику, требующую реакции игрока без потери контроля над фигурами.
Вопрос-ответ:
Какие библиотеки Python используются для создания Тетриса?
Для создания Тетриса на Python чаще всего применяются Pygame или tkinter. Pygame позволяет легко работать с графикой, звуком и вводом с клавиатуры, что удобно для реализации анимации падающих фигур. Tkinter подходит для более простых версий игры с минимальными графическими эффектами, используя стандартные элементы интерфейса.
Как реализовать движение фигур в Тетрисе на Python?
Движение фигур обычно реализуется через координатную сетку, где каждая фигура представлена набором координат. При нажатии клавиш стрелок программа изменяет координаты фигуры, проверяет столкновения с границами и другими фигурами. Для падения используется цикл с таймером, который постепенно сдвигает фигуру вниз, а при столкновении фиксирует её на поле.
Как проверить заполнение линии и удаление полного ряда?
Каждый ряд игрового поля хранится как список или массив. После фиксации фигуры программа проверяет, есть ли ряд, полностью заполненный блоками. Если такой ряд найден, он удаляется, а все ряды выше смещаются вниз. Этот процесс часто реализуют с помощью функции, которая перебирает все строки и пересобирает поле без полных рядов.
Можно ли добавить счёт и уровни сложности в Тетрис?
Да, добавление счёта и уровней сложности улучшает игровой процесс. Счёт обычно увеличивается за каждый удалённый ряд, а уровень сложности повышается через определённое количество очков, ускоряя падение фигур. В Python это делается через переменные для очков и скорости, а таймер цикла падения фигур изменяет интервал в зависимости от уровня.
Какие ошибки часто встречаются при создании Тетриса на Python?
Часто встречаются ошибки с проверкой границ поля и столкновений фигур, из-за чего фигуры могут выходить за пределы или накладываться друг на друга. Также сложность может возникнуть при вращении фигур, особенно L- и Z-образных, если координаты неправильно пересчитываются. Ещё одной проблемой бывает неправильная очистка полных рядов, что нарушает логику игры.
