Продолжаем создание игры с Pygame и Python
В предыдущей статье мы создали и отобразили красивое игровое поле с помощью Pygame и Python. И на данный момент наша программа отображает фоновое изображение небольшого кусочка космоса, где будет проходить наша игра. Сейчас он немного пуст, поэтому мы займемся его заполнением. В сегодняшней статье мы создадим класс, представляющий другие рисованные игровые объекты, и будем использовать его для отображения космического корабля.
Мы уже использовали поверхности, но Pygame также предлагает другой класс, Sprite, который предназначен в качестве базового класса для видимых объектов.
В первую очередь нам понадобится создать класс с названием GameObject, который будет инкапсулировать некоторое общее поведение и данные для всех других игровых объектов. Классы, представляющие определенные объекты (например, космический корабль), наследуют от него и расширяют его своим собственным поведением и данными.
Класс GameObject будет хранить следующие данные:
position (положение): Точка в центре объекта на 2D-экране
sprite (спрайт): изображение, используемое для отображения объекта
radius (радиус): значение, представляющее зону столкновения вокруг положения объекта
velocity (скорость): Значение, используемое для движения
Вот графическое представление игрового объекта:
Спрайтом будет поверхность, загруженная load_sprite() из предыдущих примеров. Радиус-это целое число, указывающее количество пикселей от центра объекта до края зоны столкновения. Однако для самого положения и скорости потребуется новый тип: вектор.
Векторы похожи на кортежи. В 2D - мире (например, в вашей игре) векторы представлены двумя значениями, указывающими координаты x и y. Эти координаты могут указывать на положение, но они также могут представлять движение или ускорение в заданном направлении. Векторы можно добавлять, вычитать или даже умножать, чтобы быстро обновить положение спрайта. Вы можете прочитать больше о векторах в Векторах в 2-мерном пространстве.
Из-за того, насколько полезны векторы в играх, у Pygame уже есть класс для них: Vector2 в модуле pygame.math. Он предлагает некоторые дополнительные функции, такие как вычисление расстояния между векторами и добавление или вычитание векторов. Эти функции значительно облегчат реализацию вашей игровой логики.
В каталоге space_rocks создайте новый файл с именем models.py. На данный момент он будет хранить класс GameObject, но позже мы добавим классы для астероидов, пуль и космического корабля. Файл должен выглядеть следующим образом:
from pygame.math import Vector2
class GameObject:
def __init__(self, position, sprite, velocity):
self.position = Vector2(position)
self.sprite = sprite
self.radius = sprite.get_width() / 2
self.velocity = Vector2(velocity)
def draw(self, surface):
blit_position = self.position - Vector2(self.radius)
surface.blit(self.sprite, blit_position)
def move(self):
self.position = self.position + self.velocity
def collides_with(self, other_obj):
distance = self.position.distance_to(other_obj.position)
return distance < self.radius + other_obj.radius
Первая строка импортирует класс Vector2.
В строке class GameObject создается класс GameObject, который вы будете использовать для представления всех игровых объектов в игре.
Строка def init() конструктор класса GameObject. Для этого нужны три аргумента:
position: Центр объекта
sprite: изображение, используемое для рисования этого объекта
velocity: обновляет положение объекта в каждом кадре
Метод Vector2() гарантируют, что положение и скорость всегда будут представлены в виде векторов для будущих вычислений, даже если кортежи передаются конструктору. Вы делаете это, вызывая конструктор Vector2(). Если ему задан кортеж, то он создаст из него новый вектор. Если ему задан вектор, то он создаст копию этого вектора.
В строке self.radius радиус вычисляется как половина ширины изображения спрайта. В этой программе спрайты игровых объектов всегда будут квадратами с прозрачным фоном. Вы также можете использовать высоту изображения—это не будет иметь никакого значения.
Функция draw(), которая будет рисовать спрайт объекта на поверхности, переданной в качестве аргумента.
Строка blit_position вычисляет правильное положение для размытия изображения. Этот процесс более подробно описан ниже. Обратите внимание, что конструктор Vector2() получает одно число вместо кортежа. В этом случае он будет использовать это число для обоих значений. Таким образом, Vector2(self.radius) является эквивалентом Vector2((self.radius, self.radius)).
Добавим космический корабль. Для чего скопируем изображение космического корабля в assets/sprites:
Структура нашего проекта должна выглядеть следующим образом:
game_project/
|
+-- space_rocks/
+-- __main__.py
+-- game.py
+-- models.py
L-- utils.py
|_
assets/
|
L-- sprites/
L-- space.png
|_ spaceship.png
Теперь изменим space_rocks/game.py файл:
import pygame
from models import GameObject
from utils import load_sprite
class SpaceRocks:
def __init__(self):
self._init_pygame()
self.screen = pygame.display.set_mode((800, 600))
self.background = load_sprite("space", False)
self.spaceship = GameObject(
(400, 300), load_sprite("spaceship"), (0, 0)
)
# пропущенный код
def _process_game_logic(self):
self.spaceship.move()
def _draw(self):
self.screen.blit(self.background, (0, 0))
self.spaceship.draw(self.screen)
pygame.display.flip()
Объект помещаются в середине экрана, используя координаты (400, 300). Положение будет обновляться каждый кадр с помощью _process_game_logic(), и он будет нарисован с помощью _draw().
Запустите эту программу, и вы увидите космический корабль, неподвижно стоящий в середине экрана:
Таким образом мы добавили в проект новый класс на основе которого можно отображать объекты игрового пространства.
-
- Михаил Русаков
Комментарии (0):
Для добавления комментариев надо войти в систему.
Если Вы ещё не зарегистрированы на сайте, то сначала зарегистрируйтесь.