Поиск по сайту:

Реализация базовой физики и обнаружения столкновений в Pygame


Экономьте время и избегайте ошибок благодаря встроенной в Pygame системе обработки столкновений.

Pygame предоставляет несколько встроенных функций для обнаружения столкновений между игровыми объектами. Это бесценно, поскольку определение того, когда и как движущиеся объекты перекрываются, может оказаться сложной задачей.

Узнайте, как добавить базовую физику и столкновения в вашу игру с помощью модуля pygame.

Встроенные функции обнаружения столкновений Pygame

Самая базовая встроенная функция обнаружения столкновений — spritecollide. Он принимает спрайт, группу спрайтов и логическое значение, указывающее, должны ли спрайты «умирать» (удаляться) при столкновении. Эта функция возвращает список спрайтов, которые столкнулись. Вот пример того, как его использовать:

collided_sprites = pygame.sprite.spritecollide(sprite1, sprite_group, True)

Еще одна полезная функция обнаружения столкновений — groupcollide, которая также принимает две группы спрайтов и логическое значение. Эта функция возвращает словарь со столкнувшимися спрайтами в качестве ключей и спрайтами, с которыми они столкнулись, в качестве значений. Вот пример того, как его использовать:

collision_dict = pygame.sprite.groupcollide(group1, group2, True, True)

Создание базовой игры-платформера с использованием функции spritecollide

Чтобы создать базовый платформер с использованием Pygame, вам потребуется создать спрайт игрока, которым сможет управлять пользователь, и спрайт платформы, на котором игрок сможет стоять. Вы можете использовать функцию spritecollide, чтобы обнаружить, когда спрайт игрока сталкивается со спрайтом платформы, и предотвратить падение игрока сквозь платформу.

Для начала установите модуль pygame с помощью pip:

pip install pygame

После этого создайте простые классы для Player и Platform, оба из которых должны наследовать от класса Sprite Pygame. Класс Player должен иметь метод обновления для обработки положения игрока в зависимости от скорости. Кроме того, у него должна быть переменная y_velocity для применения эффекта гравитации. Класс Platform должен иметь метод __init__, который берет координаты платформы и создает поверхность такого размера.

Класс игрока

Вы можете создать класс Player, используя модуль pygame.sprite.Sprite. Этот класс инициализирует игрока с заданными координатами x и y. Затем метод update обновит положение игрока, увеличивая значение y_velocity.

import pygame
class Player(pygame.sprite.Sprite):
    def __init__(self, x, y):
        super().__init__()
        self.image = pygame.Surface((32, 32))
        self.rect = self.image.get_rect(topleft=(x, y))
        self.y_velocity = 0
    def update(self):
        self.rect.y += self.y_velocity

Класс платформы

Класс Platform также использует модуль pygame.sprite.Sprite. Этот класс инициализирует платформу с заданными координатами x и y, а также шириной и высотой.

class Platform(pygame.sprite.Sprite):
    def __init__(self, x, y, width, height):
        super().__init__()
        self.image = pygame.Surface((width, height))
        self.rect = self.image.get_rect(topleft=(x, y))

Игровой цикл

Игровой цикл позволит вам создать окно размером 640x480. Затем он запустит цикл, который проверит наличие любых событий, таких как команда выхода. Он также будет проверять наличие столкновений между игроком и платформой. Наконец, он заполнит экран белым цветом, нарисует игрока и платформу, а затем перевернет дисплей.

player = Player(100, 300)
player_group = pygame.sprite.Group()
player_group.add(player)
platform = Platform(50, 400, 100, 20)
platform_group = pygame.sprite.Group()
platform_group.add(platform)
# Initialize pygame and create window
pygame.init()
screen = pygame.display.set_mode((640, 480))
# Main game loop
running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
    
    player_group.update()
    collided = pygame.sprite.spritecollide(player, platform_group, False)
    if collided:
        player.y_velocity = 0
    screen.fill((255, 255, 255))
    player_group.draw(screen)
    platform_group.draw(screen)
    pygame.display.flip()
pygame.quit()

Ниже приведен результат:

Реализация гравитации и прыжкового поведения

Чтобы реализовать гравитацию и прыжковое поведение в платформере, вам нужно будет добавить скорость по оси Y к спрайту игрока и обновлять ее положение по оси Y в каждом кадре. Для этого вы можете использовать метод update внутри класса Player и добавить следующий фрагмент кода:

class Player(pygame.sprite.Sprite):
    def __init__(self, x, y):
        super().__init__()
        self.image = pygame.Surface((32, 32))
        self.rect = self.image.get_rect(topleft=(x, y))
        self.y_velocity = 0
    def update(self):
        self.rect.y += self.y_velocity
        self.y_velocity += GRAVITY # Apply gravity to y velocity

Теперь каждый раз, когда вы вызываете метод update, он будет обновлять положение игрока в соответствии с его скоростью и гравитацией.

Чтобы спрайт игрока прыгал, вы можете привязать действие прыжка к определенной клавише или кнопке и обновить скорость игрока по оси Y, присвоив ей отрицательное значение. Следующий фрагмент кода является примером того, как прыгать, когда игрок нажимает пробел.

JUMP_VELOCITY = -10
# inside the game loop
if event.type == pygame.KEYDOWN and event.key == pygame.K_SPACE:
    player.y_velocity = JUMP_VELOCITY

Обратите внимание, что вам нужно будет проверить event.type, чтобы убедиться, что событие является событием KEYDOWN, прежде чем проверять значение ключа.

Добавление базовой физики, такой как трение и ускорение

Чтобы добавить базовую физику, такую как трение и ускорение, в ваш платформер, вам нужно будет обновить скорость x спрайта вашего игрока в каждом кадре. Вы можете добавить скорость x в класс игрока и обновить ее так же, как и скорость y. Чтобы реализовать трение, вы можете немного уменьшить скорость x спрайта игрока в каждом кадре. Например, вы можете добавить следующий фрагмент кода в метод обновления класса Player:

FRICTION = 0.9
class Player(pygame.sprite.Sprite):
    def __init__(self, x, y):
        super().__init__()
        self.image = pygame.Surface((32, 32))
        self.rect = self.image.get_rect(topleft=(x, y))
        self.y_velocity = 0
        self.x_velocity = 0
    def update(self):
        self.rect.y += self.y_velocity
        self.rect.x += self.x_velocity
        self.y_velocity += GRAVITY # Apply gravity to y velocity
        self.x_velocity *= FRICTION # Apply friction to x velocity

Чтобы реализовать ускорение, вы можете установить переменную player_movement для горизонтального движения и обновить скорость x спрайта игрока в соответствии со значением player_movement. Вы можете сделать это, привязав движение к определенным клавишам или кнопкам и обновив скорость игрока по оси X в цикле событий, например:

ACCELERATION = 0.5
player_movement = 0
if event.type == pygame.KEYDOWN:
    if event.key == pygame.K_LEFT:
        player_movement = -1
    elif event.key == pygame.K_RIGHT:
        player_movement = 1
elif event.type == pygame.KEYUP:
    if event.key in (pygame.K_LEFT, pygame.K_RIGHT):
        player_movement = 0
        
player.x_velocity += player_movement * ACCELERATION

Используя эти методы, вы можете создать простой, но увлекательный платформер, используя встроенные в Pygame функции обнаружения столкновений и базовую физику. Проявив немного творчества и экспериментов, вы можете использовать эти методы для создания множества различных игр и игровых механик.

Полный код вы можете найти в репозитории GitHub.

Ниже приведен результат:

Улучшите взаимодействие с пользователем с помощью столкновений

Многие игры требуют той или иной формы обнаружения столкновений. Вы можете использовать столкновения для создания самых разных игровых механик: от простых платформеров до сложных симуляций, основанных на физике.

Реализация базовой физики, такой как гравитация, трение и ускорение, также может значительно улучшить взаимодействие с пользователем, добавив реализма и ощущения веса игровым объектам.

Статьи по данной тематике: