Pygame — мини-игры на Python

Приветствую! Здесь вы наверняка найдете, что ищете. Примеры в лаборатории рассчитаны на то, что мы разбираем что-то конкретное.

Текущая статья посвящена примерам: игр на Pygame для Python 3 — змейка, Pong, Breakout, Flappy, шарик. Готовый код с построчным разбором для школьников, студентов и самоучки.

Поэтому за теорией по текущей теме вам — в энциклопедию. Если ещё не погружались, то маршрут прост:

  1. Основы
  2. Система и сеть
  3. Данные и разметка
  4. Код и разработка
  5. Языки
  6. Искусственный интеллект
  7. Проект
  8. Инфраструктура и безопасность
  9. Спин-офф

Обязательно пройдитесь.

А теперь приступим к нашему предмету.

Теория и соседние материалы

Перед запуском примеров изучите главу Разработка игр на Python — там игровой цикл, события, спрайты и столкновения.

Пошаговые большие проекты (Tetris, Match-3, аркады) — в Практикуме разработки игр.

Для рисования без игровой логики — Turtle (Python) или p5.js (браузер); для 3D — Panda3D.


Основы мини-игр на Pygame

Как запустить любой пример

pip install pygame
python bounce.py

Сохраните фрагмент кода в файл с латинским именем (snake.py, pong.py). Окно откроется на вашем компьютере — в браузере эти игры не запускаются. Закрытие: крестик окна, Esc (где указано) или остановка в IDE.

Частый запрос в поиске Раздел ниже
pygame пример, первое окно Обязательный каркас
шарик отскакивает pygame Отскакивающий шар
змейка на python pygame Змейка
pong на python Pong
breakout pygame Breakout
flappy bird python Flappy

Управление в большинстве игр: стрелки или WASD. В меню перезапуска часто Пробел.

Чем Pygame отличается от Turtle

Turtle Pygame
Задача Рисовать фигуры по шагам Игра: ввод, время, столкновения
Окно Черепашка на холсте Полноценное игровое окно
Цикл turtle.done() ждёт while running — десятки кадров в секунду
Координаты Часто от центра Левый верхний угол экрана — (0, 0)

И Turtle, и Pygame учат алгоритмам; для мини-игр нужен именно игровой цикл из трёх шагов на каждом кадре.

flowchart LR
  A[События] --> B[Обновить состояние]
  B --> C[Нарисовать кадр]
  C --> D[flip + tick]
  D --> A
  1. События — клик, клавиша, закрытие окна (pygame.event.get()).
  2. Обновление — новые координаты, счёт, проверка столкновений.
  3. Отрисовка — заливка фона, фигуры, текст; pygame.display.flip() показывает кадр.
  4. clock.tick(60) — пауза до следующего кадра (~60 FPS).

Обязательный каркас

Любая мини-игра на Pygame повторяет один шаблон. Без init, цикла while и flip() окно либо не откроется, либо «зависнет» без перерисовки.

Разбор по блокам:

Строка / блок Зачем нужна
pygame.init() Подготавливает SDL: без этого set_mode может упасть
set_mode((w, h)) Создаёт окно; screen — холст, на который рисуем
while running Игровой цикл: повторяется, пока игра не закончена
event.get() Очередь событий ОС: мышь, клавиатура, закрытие
QUIT Единственный корректный способ выйти по крестику
screen.fill(..) Стирает прошлый кадр (иначе останутся «шлейфы»)
display.flip() Двойная буферизация: показать нарисованное
clock.tick(60) Ограничение скорости; без tick цикл жрёт 100% CPU
Цвет в Pygame

Кортеж `(R, G, B)` от 0 до 255: `(255, 0, 0)` — красный, `(0, 0, 0)` — чёрный.

В примерах ниже фон тёмный, объекты яркие — так проще видеть столкновения на уроке.

Константы (W, H, SPEED, цвета) держите вверху файла. Несколько персонажей удобно оформлять через pygame.sprite.Sprite и Group — см. шутер.


Стартовые мини-игры

Простые сцены без сложной физики: хватит одного файла и базового цикла.


Отскакивающий шар

Классический учебный пример: позиция (x, y) и скорость (vx, vy). Удар о стенку — смена знака скорости по оси.

Разбор:

  • vx, vy — на сколько пикселей сдвигаем шар каждый кадр; это проще, чем физика с ускорением.
  • Проверка x - radius учитывает радиус: центр не должен заходить за край.
  • vx = -vx разворачивает движение по горизонтали (закон отражения в одну строку).
  • int(x)draw.circle ждёт целые координаты; без int на старых версиях бывают предупреждения.

Что попробовать: измените vx, vy на 8, 6 — шар станет быстрее; radius = 40 — крупнее и чаще бьётся о края.


След за курсором

Список последних позиций мыши — простейшая структура данных в игре: очередь из точек, старые удаляем.

Разбор:

  • get_pos() читает мышь без событий — каждый кадр, плавный след.
  • pop(0) — FIFO: фиксированная длина хвоста, память не растёт.
  • enumerate(trail) даёт индекс i: по нему рисуем «свежие» точки ярче и крупнее.

Кликер — очки за попадание

Здесь появляются pygame.Rect (прямоугольник-мишень) и collidepoint — попадание по клику. Текст рисуем через font.render и blit.

Разбор:

Элемент Смысл
Rect(x, y, w, h) Прямоугольник: позиция левого верхнего угла и размер
collidepoint(event.pos) True, если координаты клика внутри прямоугольника
MOUSEBUTTONDOWN Событие один раз на нажатие (не «зажатая» кнопка)
font.render(.., True, color) Картинка-буквы; True — сглаживание
blit Вставить картинку текста на screen

random.randint(r, W - r) не даёт мишени вылезти за край экрана.


Реакция — нажми, когда зелёный

Учебная машина состояний: WAITREADY (ждём) → GO (жми) → DONE. Время в миллисекундах — pygame.time.get_ticks().

Разбор состояний:

Состояние Экран Что ждём от игрока
WAIT Серый Пробел — начать раунд
READY Красный Случайная пауза 1.2–3.5 с, ранний пробел = ошибка
GO Зелёный Пробел — засечь react_ms = now - start_ms
DONE Синий Показ времени, пробел — снова WAIT

start_ms = now + random.randint(..) планирует момент смены цвета в будущем, без time.sleep — цикл игры не блокируется.


Примеры мини-игр

Ниже — полноценные мини-игры: скопируйте файл целиком, запустите, затем читайте разбор под тем же заголовком. Якоря (#snake, #pong …) удобны для ссылок из тетради или чата.

1. Классические аркады

1.1. Pong (две ракетки)

Две ракетки и мяч. Скорость мяча хранится в vx, vy; ракетки двигаем через get_pressed() — удержание клавиши даёт плавное движение.

Разбор:

Идея Код
Хитбокс ракетки и мяча pygame.Rect — удобно для colliderect
Плавное движение keys = get_pressed() вне KEYDOWN — пока держим W, ракетка едет каждый кадр
Отскок от ракетки vx = -vx только если мяч летит к ракетке (vx < 0 к левой) — иначе мяч «прилипает»
Гол ball.left <= 0 — очко правому, сброс в центр reset_ball
global vx, vy В функции reset_ball меняем скорости мяча из внешней области

Управление: W/S — левая ракетка, ↑/↓ — правая.

Доработка: увеличьте SPEED до 9 — сложнее; добавьте clock.tick в заголовок окна через set_caption(f"FPS: &#123;clock.get_fps():.0f&#125;") раз в секунду.


1.2. Змейка

Самый частый запрос «змейка на python pygame». Змейка — список клеток (col, row); голова в начале списка. Движение не каждый кадр, а раз в tick_ms миллисекунд — классическая «пошаговая» скорость.

Разбор змейки:

snake = [(5,3), (4,3), (3,3)]   # голова слева — (5,3)
insert(0, new_head)             # рост: хвост не удаляем
pop()                           # обычный ход: хвост исчезает
Проверка Зачем
direction != (1, 0) при повороте влево Иначе змейка врежется в себя за один кадр
now - last_move >= tick_ms Ход по таймеру, а не 60 раз в секунду
new_head in snake Столкновение с собственным телом
tick_ms - 4 после еды Игра ускоряется — ощущение прогресса

Рисование: cx * CELL переводит номер клетки в пиксели. (0,0) — левый верхний угол поля.


1.3. Flappy — прыжок между препятствиями

Гравитация и импульс прыжка; трубы движутся влево — типичная механика для урока «физика в 2D без формул».

Суть примера: bird_vy += GRAVITY — вертикальная скорость на каждом кадре; Пробел даёт импульс JUMP. Трубы — словари &#123;"x", "gap_y"&#125;; столкновение через colliderect двух прямоугольников (верхняя и нижняя часть трубы). Счёт +1, когда труба ушла левее птицы (pipe["scored"]).


1.4. Breakout — кирпичи и платформа

Мяч, платформа и сетка кирпичей — учит colliderect, отражению скорости и флагу «кирпич ещё жив».

Разбор Breakout:

Блок Смысл
bricks — список словарей У каждого кирпича alive: можно выключать без удаления из списка
paddle.centerx = mx Платформа следует за мышью по X
Отскок от платформы vy = -abs(vy) — мяч всегда улетает вверх; offset меняет vx — угол отражения
Потеря жизни ball.bottom >= H — мяч упал вниз, не поймали

Платформа следует за мышью.


2. Ловля и уклонение

2.1. Лови падающие звёзды

Суть: корзина playerRect внизу; объекты items падают (item.y += 5). colliderect — поймали; item.top > H — промах. Счётчики score / missed — типичная домашняя работа «поймай N предметов».


2.2. Уклоняйся от машин

Суть: три «полосы» дороги (lane), машины спавнятся в случайной полосе. Очки растут, если пропустили машину вниз (obs.top > H) — мотивация рисковать, а не стоять.


3. Стрельба и действие

3.1. Вид сверху — стрельба по врагам

Разбор ООП в Pygame:

Класс Роль
Player Наследует Sprite; в update читает клавиши
Bullet Сам двигается; kill() удаляет из всех групп
Enemy Преследует игрока: нормализованный вектор (dx, dy) / length
Group all_sprites.draw(screen) рисует всех за один вызов
spritecollide Пуля + враг: True во 2-м аргументе — враг уничтожен

Стрельба — клик: угол от игрока к event.pos. Движение — WASD.


3.2. Космические захватчики (упрощённо)

Суть: стая врагов движется синхронно; при касании края — enemy_dir *= -1 и сдвиг вниз (move_down) — как в оригинальных Invaders. Пули — отдельный список bullets, не спрайты: проще для курса после списков в Python.


4. Головоломки и таймеры

4.1. Найди отличающийся квадрат

Суть: сетка 5×5; клик переводит (mx, my) в (col, row) через деление на CELL. Один квадрат другого оттенка — тренировка координат и MOUSEBUTTONDOWN.


4.2. Таймер на выживание 30 секунд

Суть: elapsed = (get_ticks() - start) / 1000 — секунды без import time. Враги спавнятся с вероятностью random.random() < 0.04 каждый кадр. Победа при elapsed >= 30.


4.3. Крестики-нолики с ИИ

Поле 3×3. Вы играете крестиками (X), компьютер — ноликами (O). Ход — клик левой кнопкой по клетке.

Как устроен код

  • Класс Board хранит сетку cells[row][col] и методы place, winner, empty_cells.
  • Функция cell_from_mouse(mx, my) переводит пиксели экрана в индексы ячейки. Смещение поля — OFFSET_X, OFFSET_Y, размер клетки — CELL.
  • Крестик и нолик рисуются через pygame.draw.line и pygame.draw.circle, без картинок.
  • После вашего хода вызывается choose_ai_moveэвристика, не полный перебор (minimax).

Логика ИИ по шагам

  1. Если есть ход, который сразу даёт победу O — сделать его.
  2. Иначе заблокировать ваш выигрышный ход X.
  3. Иначе занять центр.
  4. Иначе занять угол.
  5. Иначе любую свободную клетку.

Такой ИИ силён для поля 3×3 и хорошо читается в коде. Для произвольного размера поля смотрите алгоритм minimax в теории игр и ИИ в играх.

Управление

  • ЛКМ — поставить X в клетку.
  • R — новая партия.
  • Esc — выход.

С чем связан пример


5. Переиспользуемые заготовки

5.1. Окно эксперимента

def setup_game_window(title: str = "Pygame Lab", size=(800, 600), fps: int = 60):
    pygame.init()
    screen = pygame.display.set_mode(size)
    pygame.display.set_caption(title)
    clock = pygame.time.Clock()
    return screen, clock, fps

5.2. Машина состояний (меню → игра → конец)

MENU, PLAY, GAME_OVER = "menu", "play", "over"
state = MENU

# В цикле событий переключайте state по клавишам и условиям победы.
# В блоке отрисовки рисуйте разный UI в зависимости от state.

Тот же приём используют Match-3 и аркады в Практикуме.


5.3. Сброс и выход

def quit_game():
    pygame.quit()
    raise SystemExit

Типичные ошибки новичков

Симптом Причина Что сделать
Чёрное окно и ничего не рисуется Нет flip() или нет рисования после fill После всех draw вызовите pygame.display.flip()
Всё мерцает или оставляет следы Не вызывают screen.fill каждый кадр Заливайте фон в начале блока отрисовки
Окно «не отвечает» Долгий цикл без событий Обработайте QUIT; не используйте бесконечный while без event.get()
No module named 'pygame' Пакет в другом Python python -m pip install pygame тем же python, что запускает скрипт
Игра слишком быстрая Нет clock.tick Добавьте clock.tick(60) в конец цикла
Змейка мгновенно умирает при повороте Разворот на 180° Запретите направление противоположное текущему (см. змейку)
Координаты «не те» Путают клетки и пиксели Умножайте индекс клетки на CELL
Текст не виден Цвет текста = цвет фона Второй аргумент render: контрастный (230, 230, 240)

Словарь терминов (коротко)

Термин Объяснение
Surface Картинка в памяти; screen — главная
Rect Прямоугольник: столкновения, позиция спрайта
Sprite Класс игрового объекта с image и rect
Event Сообщение ОС: клавиша, мышь, закрытие
FPS Кадров в секунду; держим через Clock.tick
Blit «Приклейка» одной картинки на другую
HUD Счёт, жизни, подсказки на экране

Как доработать пример под отчёт или проект

  1. Переименуйте окно и заголовок в set_caption — видно, что это ваша версия.
  2. Добавьте звукpygame.mixer.Sound при поедании еды или голе (глава Разработка игр на Python).
  3. Картинки вместо квадратовimage = pygame.image.load("hero.png"), rect = image.get_rect().
  4. Меню — состояние MENU / PLAY как в реакции.
  5. Запись рекорда — сохранить score в файл scores.txt через обычный open.

Для курсовой достаточно одной игры из раздела 1 с вашим комментарием к 5–10 строкам — преподаватели ценят понимание цикла, а не объём кода.


Что дальше

Уровень Куда идти
Теория цикла и спрайтов Разработка игр на Python
Полноценные проекты Практикум разработки игр
2D-рисование без игр Turtle (Python) · p5.js (браузер)
Окна, формы, кнопки Tkinter — окна и виджеты
3D Panda3D · примеры Panda3D

Сохраняйте каждый пример в отдельный файл, подключайте venv и фиксируйте версию в requirements.txt (pygame>=2.5). Проверка установки:

python -c "import pygame; print(pygame.version.ver)"

Если версия печатается — можно запускать любой скрипт из этой статьи.