Создание игры Тетрис на Python пошаговое руководство

Как сделать тетрис на python

Как сделать тетрис на python

Тетрис – классическая игра с падающими фигурами, которая идеально подходит для освоения основ программирования на 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

Рекомендации при реализации:

  1. Проверять столкновение перед каждым перемещением фигуры вниз, влево, вправо или при вращении.
  2. Использовать отдельную копию фигуры для проверки вращения, чтобы избежать изменения исходной матрицы при невозможном повороте.
  3. Оптимизировать проверку, ограничивая её только областью, куда фигура может попасть при текущем действии, чтобы не проверять весь массив поля.
  4. Сохранять последовательность проверок: сначала границы, затем столкновение с другими блоками, чтобы избежать ошибок при одновременном выходе за границу и пересечении с другими фигурами.

Корректная проверка столкновений обеспечивает стабильное поведение игры и предотвращает наложение блоков или выход за пределы поля.

Удаление заполненных линий и подсчет очков

Для удаления заполненных линий в Тетрисе создайте функцию, которая проверяет каждую строку игрового поля на наличие полного заполнения блоками. Используйте цикл от нижней строки к верхней, чтобы корректно сдвигать оставшиеся линии вниз после удаления. Например, если игровое поле представлено списком списков: 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-образных, если координаты неправильно пересчитываются. Ещё одной проблемой бывает неправильная очистка полных рядов, что нарушает логику игры.

Ссылка на основную публикацию