Как сделать коллизию в pygame

Добавил пользователь Евгений Кузнецов
Обновлено: 04.10.2024

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

if xigrok+igrokhirota/2 >= xstena and xigrok-igrokhirota/2 = ystena and yigrok+igrokvusota/2 1 год назад

Мы постоянно добавляем новый функционал в основной интерфейс проекта. К сожалению, старые браузеры не в состоянии качественно работать с современными программными продуктами. Для корректной работы используйте последние версии браузеров Chrome, Mozilla Firefox, Opera, Microsoft Edge или установите браузер Atom.

Спрайты имеют встроенное обнаружение столкновений. Это одна из целей спрайта. Если вы не используете спрайты, вам придется изобрести собственное обнаружение столкновений (или найти библиотеку, которая вам поможет). См. это ТАК для получения дополнительной помощи.

Ответы 1

Чтобы использовать функции обнаружения столкновений pygame (например, pygame.sprite.spritecollide ), ваш класс не обязательно должен быть подклассом Sprite pygame.

Учитывая такой простой класс:

мы можем использовать pygame.sprite.spritecollide так:

Также посмотрите, что второй аргумент - это не Group , а простой List , но питон не заботится, поскольку единственное, что имеет значение в этом случае, - это то, что вы можете перебирать объект. Если вы передадите True в качестве третьего аргумента, это не удастся, поскольку spritecollide попытается вызвать sprites() и второй аргумент, а также kill() для элементов внутри.

Аналогичным образом, если вы хотите, например, используйте идеальное обнаружение столкновений пикселей, вам нужен атрибут mask и т. д. Так что вам все равно следует использовать класс Sprite , поскольку он предлагает еще кое-что, например, управление группами. Кроме того, каждый раз, когда вы хотите сохранить позицию или размер, подумайте об использовании класса pygame Rect , поскольку он довольно мощный и используется / ожидается во многих функциях pygame.

tl; dr: Используйте класс pygame Sprite . Вероятно, у вас нет веской причины не делать этого, и есть куча веских причин, чтобы на самом деле ее использовать.

Я очень ценю ваш помощник, и я воспользуюсь вашим советом и заменю свои классы на классы Sprite. Большое спасибо !(:

Продолжаем создание игры с 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

Первая строка импортирует класс 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.jpg
|_ spaceship.jpg

Теперь изменим space_rocks/game.py файл:

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 ):


Методы работы с Rect

pygame.Rect.copy Возвращает новый прямоугольник, имеющий ту же позицию и размер, что и оригинал.
pygame.Rect.move Возвращает новый прямоугольник, перемещаемый данным смещением. Аргументы x и y могут быть любым целочисленным значением, положительным или отрицательным.
pygame.Rect.move_ip То же, что и метод Rect.move (), но работает на месте.
pygame.Rect.inflate увеличивать или уменьшать размер прямоугольника, на месте
pygame.Rect.inflate_ip увеличивать или уменьшать размер прямоугольника, на месте
pygame.Rect.clamp перемещает прямоугольник внутри другого
pygame.Rect.clamp_ip перемещает прямоугольник внутри другого, на месте
pygame.Rect.clip обрезает прямоугольник внутри другого
pygame.Rect.union соединяет два прямоугольника в один
pygame.Rect.union_ip соединяет два прямоугольника в один, на месте
pygame.Rect.unionall объединение многих прямоугольников
pygame.Rect.unionall_ip объединение многих прямоугольников, на месте
pygame.Rect.fit изменить размер и переместить прямоугольник учмиывая соотношение сторон
pygame.Rect.normalize корректировать отрицательные размеры
pygame.Rect.contains проверить, находится ли один прямоугольник внутри другого
pygame.Rect.collidepoint проверить, находится ли точка внутри прямоугольника
pygame.Rect.colliderect тест, пересекаются ли два прямоугольника
pygame.Rect.collidelist проверить, пересекается ли хоть один прямоугольник в списке
pygame.Rect.collidelistall пересекаются ли все прямоугольники в списке
pygame.Rect.collidedict проверить, если один прямоугольник в словаре пересекается
pygame.Rect.collidedictall пересекаются ли все прямоугольники в словаре

Обработка событий

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

Функция get в модуле pygame.event возвращает последнее событие, ожидающее в очереди и удаляет его из очереди.

Объект event

Модуль pygame.event для обработки очереди событий

pygame.event.pump Если вы не используете другие функции событий в своей игре, вы должны вызвать pygame.event.pump (), чтобы позволить pygame обрабатывать внутренние действия
pygame.event.get получает события из очереди
pygame.event.poll получить одно событие из очереди
pygame.event.wait ждёт одиночного события из очереди
pygame.event.peek проверить, ждут ли очереди события определённого типа
pygame.event.clear удалить все события из очереди
pygame.event.event_name возвращает имя для типа события. Строка находится в стиле WordCap
pygame.event.set_blocked проверяет, какие события не разрешены в очереди
pygame.event.set_allowed проверяет, какие события разрешены в очереди
pygame.event.get_blocked проверить, заблокирован ли тип события из очереди
pygame.event.set_grab проверяет совместное использование устройств ввода с другими приложениями
pygame.event.get_grab проверить, работает ли программа на устройствах ввода данных
pygame.event.post поместить новое событие в очередь
pygame.event.Event создать новый объект события
pygame.event.EventType Объект Python, представляющий событие SDL. Экземпляры пользовательских событий создаются с вызовом функции Event. Тип EventType не может быть напрямую вызван. Экземпляры EventType поддерживают назначение и удаление атрибутов.

Существует множество способов доступа к очереди событий. Просто проверять существование событий, захватывать их непосредственно из стека.

Модуль pygame.mouse для работы с мышью

pygame.mouse.get_pressed получить состояние кнопок мыши
pygame.mouse.get_pos получить позицию курсора мыши
pygame.mouse.get_rel получить количество движений мыши
pygame.mouse.set_pos установить позицию курсора мыши
pygame.mouse.set_visible скрыть или показать курсор мыши
pygame.mouse.get_focused проверяет, принимает ли дисплей ввод мыши
pygame.mouse.set_cursor установить изображение для курсора мыши
pygame.mouse.get_cursor получить изображение для курсора мыши

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

Когда режим отображения (display) установлен, очередь событий начнет принимать события мыши. Кнопки мыши генерируют события pygame.MOUSEBUTTONDOWN и pygame.MOUSEBUTTONUP , когда они нажимаются и отпускаются. Эти события содержат атрибут кнопки, указывающий, какая кнопка была нажата. Колесо мыши будет генерировать pygame.MOUSEBUTTONDOWN и pygame.MOUSEBUTTONUP события при прокрутке.

Когда колесо повернуто вверх, кнопка будет установлена на 4, вниз -5. Всякий раз, когда мышь перемещается, генерируется событие pygame.MOUSEMOTION . Движение мыши разбито на небольшие и точные события движения. По мере перемещения мыши многие события движения будут помещены в очередь. События движения мыши, которые неправильно очищены от очереди событий, являются основной причиной того, что очередь событий заполняется.

Пример. Нарисовать курсор под текущей позицией мыши.

Определить какая кнопка была нажата на мышке можно используя значение event.button:

Координаты курсора при нажатии кнопки мыши находятся в event.pos .

Пример. Перемещать картинку курсором мыши.

Клавиатура

Модуль pygame.key

Этот модуль содержит функции для работы с клавиатурой.Очередь событий получает события pygame.KEYDOWN и pygame.KEYUP при нажатии и отпускании клавиш клавиатуры.

Оба события имеют ключевой атрибут, который представляет собой целочисленный идентификатор, представляющий каждую клавишу на клавиатуре.Событие pygame.KEYDOWN имеет дополнительные атрибуты: unicode и scancode. unicode представляет собой одну символьную строку, которая соответствует введённому символу. Scancode представляет собой код для конкретной платформы.

Получить код клавиши:


Существует много клавиатурных констант, они используются для представления клавиш на клавиатуре. Ниже приведен список всех клавиатурных констант:

Направленное движение с помощью клавиш

Можно перемещать изображение на экране с клавиатуры, назначая клавиши для перемещений: вверх, вниз, влево, вправо.

Создать картинку, например:

Проверить очередь событий:

Проверить, является ли полученное событие нажатием на клавиши со стрелками:

Если — да, то получмить код нажатой клавиши и сформировать новые координаты для картинки:

И нарисовать картинку в новом месте:

Объект Surface

pygame.Surface — объект pygame для представления изображений


Наложение поверхностей, прозрачность.

Управление временем

Модуль pygame.time содержит объект Clock, который можно использовать для отслеживания
времени. Чтобы создать объект типа: время, вызывается конструктор pygame.time.Clock:
clock = pygame.time.Clock()

Когда создан объект clock, можно вызвать его функцию tick один раз за кадр,
которая возвращает время, прошедшее со времени предыдущего вызова в миллисекундах:
time_passed = clock.tick ()

Функция tick может использовать необязательный параметр для установления максимальной частоты кадров. Этот параметр нужен, если игра запущена на рабочем компьютере и необходимо контролировать, чтобы она не использовала всю его вычислительная мощность на 100%:

time_passed = clock.tick (30)

Звуки

Для управления звуком используется модуль pygame.mixer . Он отвечает за любые действия со звуками.

Загружаем звуковой файл в формате *.wav

sound = pygame.mixer.Sound("sound.wav")
(загружаем до игрового цикла, т.к. это очень долгая операция)

Столкновения (collisions)

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

Читайте также: