Как сделать прыжок в pygame

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

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

Перед стартом

Для начала нужно сохранить файл pygame template.py с новым именем. Таким образом вы сможете использовать этот шаблон в будущем для других игр. Можно назвать файл просто как shmup.py.

В первую очередь, необходимо отредактировать настройки, добавив некоторые значения в игру:

Спрайт игрока

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

Это начало спрайта игрока:

Метод update() спрайта запускается в каждом кадре. Он будет перемещать спрайт с конкретной скоростью:

Теперь нужно показать спрайт, чтобы убедиться, что он отображается на экране:

Не забывайте, что каждый созданный спрайт должен быть добавлен в группу all_sprites , так чтобы он обновлялся и прорисовывался на экране.

Движение/управление

Управлять в этой игре нужно будет с помощью клавиатуры, поэтому игрок должен будет двигаться при нажатии кнопок Влево или Вправо (это могут быть a или d ).

Когда речь заходит об использовании кнопок в игре, есть выбор, а это значит, что речь идет о Событиях:

1 вариант: в этой очереди событий можно определить два события (по одному для каждой кнопки), каждое из которых будет менять скорость игрока, соответственно:

Проблема с этим методом в том, что после нажатия кнопки Игрок двигается, но не останавливается. Нужно также добавить два события KEYUP , которые будут возвращать скорость к значению 0 .

2 вариант: установить скорость спрайта по умолчанию на значение 0 , за исключением случаев, когда нажимаются кнопки Влево или Вправо. В результате движение будет более плавным, а код проще.

Этот код устанавливает скорость speedx на значении 0 для каждого кадра, а затем проверяет, не нажата ли кнопка. pygame.key.get_pressed() возвращает словарь со всеми клавишами клавиатуры и значениями True или False , которые указывают на то, нажата ли какая-то из них. Если одна из кнопок нажимается, скорость меняется соответственно.

В пределах экрана

Наконец, нужно сделать так, чтобы спрайт не пропадал с экрана. Для этого нужно добавить этот код к update() игрока:

Теперь если rect попробует двигаться за пределы экрана, он остановится. Второй вариант — телепортировать спрайт с одного края экрана ко второму, когда он туда доберется. Но в этой игре предпочтительнее тормозить игрока.

Вот весь код этого шага:

В следующем уроке в игру будут добавлены спрайты врагов, от которых игрок будет уклоняться.

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

Мы с вами уже знакомы с методом получения всех произошедших событий - pygame.event.get() , который возвращает события, произошедшие с последнего обращения.

Помимо событий выхода из приложения pygame.QUIT , есть множество других - например, нажатия клавиш pygame.KEYDOWN или отпускания pygame.KEYUP .

Рассмотрим взаимодействие с событиями на примере небольшой программы, в которой по нажатию клавиш показывается квадрат:

В данном блоке программа занимется обработкой нажатия клавиш. Сначала мы получаем список всех событий, после чего начинаем последовательно проверять их. Если одно из событий соответствует сигналу к завершению программы, закрываем окно. Если же это нажатие клавиши - перекрашиваем прямоугольник в белый цвет.

Я пытаюсь сделать игру, подобную геометрической тире в pygame. У меня есть все, кроме прыгающей части. Мне это нужно, так что, когда персонаж находится на квадратном блоке, он может вскочить, но не может дважды прыгать в воздухе. Прямо сейчас у меня это так, что персонаж может прыгать на землю, но как только персонаж касается прыжков на множестве блоков, он начинает отскакивать вверх и вниз и не может прыгать, пока он скользит по блокам. Может ли кто-нибудь помочь?

Другая возможная проблема может заключаться в том, что вы помещаете свой персонаж на 1 пиксель выше платформы, когда происходит столкновение. Это означает, что при следующем проверке на столкновение персонаж не будет опираться на блок, и поэтому он будет False.

Первую проблему легко устранить, удалив последнюю строку onblocks = False . Вторая проблема может быть исправлена ​​с помощью player_rect.bottom = i.top без +1.

Смотрите talk для получения дополнительной информации, особенно около this timestamp.


Методы работы с 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)

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

Я новичок в программировании и Python, а также Pygame. Как таковой, я еще не знаком со спрайтами в Pygame. Я пытаюсь сделать игру, в которой блок прыгает всякий раз, когда нажимается пробел, - похоже на Марио.

Мой код не работает должным образом, потому что всякий раз, когда нажимается пробел, блок постепенно увеличивается (я добавил компонент гравитации), а не "прыгает".

Я знаю, что мне нужно как-то заставить y_pos постоянно обновляться в цикле while, пока speed >= 0 но я не уверен, как это реализовать.

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