Практическое руководство по созданию игр с Pygame

Раздел: Разработка на Python -> Примеры игр на Python

Основы создания игры на Pygame

В этом разделе рассматривается минимальная программа на Pygame, которая создает окно, обрабатывает нажатия клавиш и перемещает прямоугольник. Код снабжен комментариями, поясняющими каждый шаг.

import pygame
pygame.init()
screen = pygame.display.set_mode((800, 600))
clock = pygame.time.Clock()

x, y = 100, 100
running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
    keys = pygame.key.get_pressed()
    if keys[pygame.K_LEFT]:
        x -= 5
    if keys[pygame.K_RIGHT]:
        x += 5
    if keys[pygame.K_UP]:
        y -= 5
    if keys[pygame.K_DOWN]:
        y += 5
    screen.fill((255, 255, 255))
    pygame.draw.rect(screen, (0, 0, 0), (x, y, 50, 50))
    pygame.display.flip()
    clock.tick(60)
pygame.quit()

Python pygame game (игра на pygame в python)

После запуска откроется окно с белым фоном. Черный квадрат можно перемещать стрелками. Цикл завершается при закрытии окна.

Типичные проблемы:

  • Окно не отвечает – забыли вызвать pygame.event.get() внутри цикла.
  • Движение прерывистое – не установлен FPS через clock.tick().
  • Изображения не загружаются – проверьте путь к файлам и используйте convert_alpha() для PNG с прозрачностью.

Как добавить спрайт с изображением вместо прямоугольника?

Для отображения картинки загрузите изображение через pygame.image.load() и нарисуйте его методом blit().

player_img = pygame.image.load('player.png').convert_alpha()
screen.blit(player_img, (x, y))
# Вместо pygame.draw.rect(...)

Убедитесь, что файл 'player.png' находится в папке с программой. Если изображение не отображается, проверьте формат (поддерживаются PNG, JPG, GIF).

Распространенные ошибки:

  • Ошибка pygame.error: Couldn't open – неверный путь. Используйте полный путь или проверьте, что файл лежит рядом со скриптом.
  • Изображение отображается с черным фоном – у PNG отключена альфа-канал. Вызовите convert_alpha().

Как реализовать столкновение двух объектов?

Столкновение прямоугольников вычисляется через метод colliderect() у объекта pygame.Rect.

player_rect = pygame.Rect(x, y, 50, 50)
obstacle_rect = pygame.Rect(300, 250, 100, 100)
if player_rect.colliderect(obstacle_rect):
    print("Столкновение!")
    # Здесь может быть реакция: остановка, здоровье, звук

Для множества объектов удобно использовать pygame.sprite.Sprite и группы.

Сложности:

  • Объекты проходят друг через друга при высокой скорости – используйте более частую проверку или spritecollide с dokill.
  • Неверные координаты Rect – помните, что Rect хранит левый верхний угол.

Как добавить звуковой эффект при столкновении?

Звук воспроизводится через модуль pygame.mixer. Предварительно инициализируйте микшер.

pygame.mixer.init()
collision_sound = pygame.mixer.Sound('hit.wav')
# В момент столкновения:
collision_sound.play()

Поддерживаемые форматы: WAV, MP3, OGG. Файл 'hit.wav' должен быть доступен.

Возможные неполадки:

  • Звук не инициализирован – вызовите pygame.mixer.init() до загрузки.
  • Звук зациклен – play() по умолчанию однократный, но если канал занят – используйте stop().

Как создать простое меню?

Реализация меню через состояния игры: меню, игра, пауза. Отрисовка кнопок и обработка кликов.

state = 'menu'
while running:
    if state == 'menu':
        # отрисовка фона и кнопки
        # если клик по кнопке -> state = 'game'
    elif state == 'game':
        # игровой цикл
        # если ESC -> state = 'menu'

Обработка нажатия мыши: pygame.mouse.get_pos() и проверка пересечения с Rect кнопки.

Ошибки реализации:

  • Игровой цикл останавливается при переходе – не блокируйте основной цикл, просто меняйте состояние.
  • Кнопки не реагируют – используйте событие MOUSEBUTTONDOWN с проверкой нажатия.

Как сделать анимацию персонажа из нескольких кадров?

Анимация реализуется сменой изображений через заданные промежутки времени. Кадры хранятся в списке.

frames = [pygame.image.load(f'frame{i}.png').convert_alpha() for i in range(1,5)]
current_frame = 0
last_update = pygame.time.get_ticks()
animation_speed = 100 # мс

# В игровом цикле:
now = pygame.time.get_ticks()
if now - last_update > animation_speed:
    current_frame = (current_frame + 1) % len(frames)
    last_update = now
screen.blit(frames[current_frame], (x, y))

Убедитесь, что все кадры одинакового размера, иначе возникнут смещения.

Типичные затруднения:

  • Анимация слишком быстрая или медленная – измените animation_speed.
  • Неправильный порядок кадров – назовите файлы с нумерацией.

Расширенные примеры на Pygame

Платформер с гравитацией и классами

Данный пример демонстрирует создание простого платформера с персонажем, который прыгает, перемещается по земле и взаимодействует с платформами. Используется объектно-ориентированный подход.

Пример
import pygame
pygame.init()

WIDTH, HEIGHT = 800, 600
screen = pygame.display.set_mode((WIDTH, HEIGHT))
clock = pygame.time.Clock()

class Player(pygame.sprite.Sprite):
    def __init__(self):
        super().__init__()
        self.image = pygame.Surface((50, 50))
        self.image.fill((0, 255, 0))
        self.rect = self.image.get_rect(midbottom=(100, 500))
        self.gravity = 0
        self.speed = 5
        self.jump_strength = -15

    def update(self):
        # Горизонтальное движение
        keys = pygame.key.get_pressed()
        dx = 0
        if keys[pygame.K_LEFT]:
            dx = -self.speed
        if keys[pygame.K_RIGHT]:
            dx = self.speed
        # Вертикальное движение (гравитация)
        self.gravity += 0.8
        dy = self.gravity
        # Прыжок
        if keys[pygame.K_SPACE] and self.rect.bottom >= HEIGHT - 50:
            self.gravity = self.jump_strength

        # Ограничение по краям
        self.rect.x += dx
        if self.rect.left < 0:
            self.rect.left = 0
        if self.rect.right > WIDTH:
            self.rect.right = WIDTH
        self.rect.y += dy
        # Простая проверка земли
        if self.rect.bottom > HEIGHT - 50:
            self.rect.bottom = HEIGHT - 50
            self.gravity = 0

player = Player()
all_sprites = pygame.sprite.Group(player)

running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

    screen.fill((135, 206, 235))  # Небесный фон
    pygame.draw.rect(screen, (34, 139, 34), (0, HEIGHT-50, WIDTH, 50))  # Земля

    all_sprites.update()
    all_sprites.draw(screen)

    pygame.display.flip()
    clock.tick(60)

pygame.quit()
Результат: Открывается окно с голубым небом и зеленой полосой земли внизу. Управляемый зеленый квадрат перемещается стрелками, на пробел подпрыгивает. При достижении краев земли останавливается.

Использование спрайтовых групп и столкновений

Пример
class Platform(pygame.sprite.Sprite):
    def __init__(self, x, y, w, h):
        super().__init__()
        self.image = pygame.Surface((w, h))
        self.image.fill((139, 69, 19))  # Коричневый
        self.rect = self.image.get_rect(topleft=(x, y))

platform_group = pygame.sprite.Group()
platform_group.add(Platform(200, 300, 150, 20))
platform_group.add(Platform(400, 200, 150, 20))

# В игровом цикле после обновления:
if pygame.sprite.spritecollide(player, platform_group, False):
    player.rect.bottom = platform.rect.top
    player.gravity = 0
Результат: Персонаж теперь может стоять на платформах. Если он приземляется на платформу, его вертикальная скорость обнуляется и он останавливается сверху.

Создание клона игры Pong с помощью Pygame

Пример
import pygame
pygame.init()

WIDTH, HEIGHT = 800, 600
screen = pygame.display.set_mode((WIDTH, HEIGHT))
clock = pygame.time.Clock()

class Ball(pygame.sprite.Sprite):
    def __init__(self):
        super().__init__()
        self.image = pygame.Surface((20,20))
        self.image.fill((255,255,255))
        self.rect = self.image.get_rect(center=(WIDTH//2, HEIGHT//2))
        self.dx = 5
        self.dy = 5

    def update(self):
        self.rect.x += self.dx
        self.rect.y += self.dy
        # Отскок от стен
        if self.rect.top <= 0:
            self.dy = -self.dy
        if self.rect.bottom >= HEIGHT:
            self.dy = -self.dy
        # Выход за левый/правый край - очко
        if self.rect.left <= 0 or self.rect.right >= WIDTH:
            self.rect.center = (WIDTH//2, HEIGHT//2)
            self.dx = -self.dx

ball = Ball()
all_sprites = pygame.sprite.Group(ball)

running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

    screen.fill((0,0,0))
    all_sprites.update()
    all_sprites.draw(screen)
    pygame.display.flip()
    clock.tick(60)
pygame.quit()
Результат: Белый круг прыгает по черному полю, отскакивая от верхней и нижней границ. При касании левой или правой границы мяч возвращается в центр.

Игра на Pygame в Python - comments

En
Python pygame game (python)