Как сделать прыжок в pygame
Pygame – adding Gravity and Jumping
This article covers the concepts of gravity and jumping in Pygame.
Welcome to Part 2 of game programming with Pygame. In this section we’ll be covering two major topics, giving our player the ability to jump and the implementation of gravity.
This article is part of a series called Game programming with Pygame with each part a direct sequel to the other. Since the code carries over, you might get confused if you haven’t read the previous sections. You can read Part 1 using this link.
Part 1 – Code
Here’s the code from Part 1 which we’ll be using as reference for the rest of the article. The pygame code for Gravity and Jumping will simply be added onto this code.
Implementing Gravity
If you’ve been following the changes we’ve been doing since Part 1, adding the concept of gravity in a simple one line edit. If you landed directly on this page without going through the prequel to this article, stop right here and go read Part 1. In Part 1 of this game programming series we used concepts like acceleration, velocity and friction which are essential for us to have gravity.
Remember that the first parameter represents horizontal acceleration and the second represents vertical. What we’re doing here is giving our player a permanent vertical acceleration of 0.5. In other words, we have created the constant force of gravity.
Note: The value of 0.5 we gave for gravity is designed specifically for this game, given the size of the player and the display screen. You may want to change this value a bit depending on the type of game you are making.
The effects of Gravity
Generally, adding gravity is an easy task. What comes after adding gravity however if difficult. Perhaps you realized this in the previous section, but if we give the Player constant vertical acceleration a.k.a Gravity, won’t he go flying out of the page? If you thought so, you were right.
The GIF above demonstrates this problem perfectly. The solution is to create a set of “rules”. These rules will define nullify the effect of gravity in certain scenarios. For instance, while standing on a platform the player should not be accelerating downwards.
This is where Collision detection comes in. To those who don’t know, Collision detection involves detecting the intersection of two or more objects with each other. In this case, we need to detect when our Player object comes into contact with a platform.
Thankfully the solution is simple. Using the spritecollide() function, we’re able to determine whether a sprite has collided with others sprites. The syntax of this function is show below.
Using all of these concepts, we create the following piece of code. It’s a new method to be added to the Player class.
We have two individual pieces of code here. One of them creates a new sprite group called platforms and adds platform 1 ( PT1 ) into it. You may not see the importance of this yet with only one platform, but as we start adding in more platforms later you’ll understand.
Using hits[0] checks the first collision in the list that’s returned.
Once again, here’s a short video demonstrating the new additions.
Player Jumping
Now that we’ve successfully added gravity, we can add the jumping mechanic to our player. There’s no point in having a jump feature without gravity so implementing gravity always comes first.
The jump method is extremely simple. All you have to do is assign a vertical velocity to the player object. It has to be negative since we want to go up.
-15 is an arbitrary value that we picked. You may wish to alter this slightly depending on the style and environment of your game.
Next up we actually have to call the method we just created. It’s not so simple as just passing jump() into the Game Loop. We want this method() to trigger only when press a specific button. In this case, we’ll be mapping the “Space” button as the trigger for jumping.
All you have to do is create a new set of if statements in the game loop. You need to check for two things. The first if statements checks to see if a button has been pressed on the keyboard. If yes, it checks to see if that button press was the space-bar. If yes, it will call the jump method of the Player.
However, this results in a small problem or “loop hole”. If the person keeps pressing space bar, the player will jump again in mid air. We’ve shown this problem in the GIF below.
Now, some of you may be looking for this kind of jumping system, but fixing this problem is important for the kind of game we are developing here.
To achieve the output shown above, you will have to modify your update function slightly.
The new addition is a single line, an if statement. This makes sure that the velocity is not set to zero unless there is already some initial velocity. This avoids a bug where the effect of the jump function is nullified due to the update function.
Now to actually fix the double jumping problem.
To sum up, this new jump method() checks to see if the Player object is in contact with an platform. If so, only then it will allow the jump to be carried out. This automatically ensures the player cannot jump again until he is in contact with the floor again.
If you think that our Jumping mechanic is lacking in it’s implementation, don’t worry. This isn’t the end of it. We’re taking things slowly, putting in the major features first, and then improving upon them. You can expect to see an upgrade to the Jumping mechanic around Part 4 of this series.
In the next part, we’re finally going to get around to level generation in Pygame. This section is probably going to be the hardest from this entire series. As usual, you will find the complete pygame code for our Gravity and Jumping section in the next part.
This marks the end of the Pygame, Gravity and Jumping article. Any suggestions or contributions for CodersLegacy are more than welcome. Questions regarding the article content can be asked in comments section.
Двойной прыжок в Pygame
Всем доброго времени суток. Очень нужна помощь. Вопрос касается Pygame. Я работаю над созданием простенькой игры. В данный момент столкнулся со следующей ситуацией. Персонаж должен сделать двойной прыжок в небе чтобы перепрыгнуть объекты, которые невозможно перепрыгнуть одиночным прыжком. Сейчас у меня есть код в котором персонаж делает только один прыжок. Отрывки кода связанные с прыжком указаны ниже:
Pygame ошибка module ‘pygame’ has no ‘init’ member
Всем здравствуйте. Недавно начал работать с VS code и выдает такая ошибка. Прикрепляю полностью.
pygame.error: cannot convert without pygame.display initialized
Только начал изучать спрайты Выдаёт ошибку: Traceback (most recent call last): File.
Двойной прыжок игрока
Приветствую, возникла такая проблема что при запрыгивании моего объекта игрока на другой физический.
Jayyy, можно весь код?
Добавлено через 1 минуту
скорее всего нужно будет высчитывать тайминг одиночного прыжка (если не встречены препятствия) и если в это время нажата кнопка прыжка, то вызвать функцию прыжка, так же потребуется новая переменная\лимит рекурсий для запрета тройных прыжков
user-ganz, Здравствуйте. Спасибо что откликнулись. Надеюсь на вашу помощь.
Вот блок кода прыжка вместе с механикой игры:
Добавлено через 34 минуты
user-ganz,
Я добавил и объекты к коду, так как насколько я понимаю есть необходимость, чтобы в условии было прописано что персонаж не встретил на своем пути никаких объектов. На самом деле код очень большой, но думаю эта часть является достаточной для имплементации двойного прыжка. Сколько уже бьюсь над этим и никак не могу решить. Помогите пожалуйста)
Здравствуйте. Спасибо большое за направление и за предоставленный код, но что-то не выходит. Возможно я что то не так делаю вновь. Можете глянуть мой код + ваше дополнение ниже? Не могу понять почему не получается(
Как сделать двойной прыжок?
Я пытаюсь создать двойной прыжок + прыжок по времени нажатия кнопки. Двойной прыжок должен.
Двойной и не полный прыжок на Unity C#
Можно ли на unity сделать одновременно и двойной прыжок, и что-бы при зажатии клавиши можно было.
Таблица содержит результаты спортивных соревнований: Ф.И.О., время на 100 м, время на 1 км, прыжок в высоту, прыжок в длину. Составить массив записей
Таблица содержит результаты спортивных соревнований: Ф.И.О., время на 100 м, время на 1 км, прыжок.
Pygame.mixer.music.set_pose() не меняет pygame.mixer.music.get_pose()
Доброго времени суток, друзья! Пишу что-то среднее между часами и музыкальным плеером. Решил, что.
Прыжок
Сделал прыжок, но проблема в том что когда платформа крутиться, ГГ может прыгнуть как пробка.
Пишем платформер на Python, используя pygame
Сразу оговорюсь, что здесь написано для самых маленькихначинающих.
Давно хотел попробовать себя в качестве игродела, и недавно выпал случай изучить Python и исполнить давнюю мечту.
Что такое платформер?
Платформер(platformer)— жанр компьютерных игр, в которых основной чертой игрового процесса является прыгание по платформам, лазанье по лестницам, собирание предметов, обычно необходимых для завершения уровня.
Вики
Одними из моих любимых игр данного жанра являются «Super Mario Brothers» и «Super Meat Boy». Давайте попробуем создать нечто среднее между ними.
Самое — самое начало.
Внимание! Используем python ветки 2.х, с 3.х обнаружены проблемы запуска нижеописанных скриптов!
Наверное, не только игры, да и все приложения, использующие pygame начинаются примерно так:
Игра будет «крутиться» в цикле ( while 1), каждую итерацию необходимо перерисовывать всё (фон, платформы, монстров, цифровые сообщения и т.д). Важно заметить, что рисование идет последовательно, т.е. если сперва нарисовать героя, а потом залить фон, то героя видно не будет, учтите это на будущее.
Запустив этот код, мы увидим окно, залитое зелененьким цветом.
(Картинка кликабельна)
Ну что же, начало положено, идём дальше.
Уровень.
А как без него? Под словом «уровень» будем подразумевать ограниченную область виртуального двумерного пространства, заполненную всякой — всячиной, и по которой будет передвигаться наш персонаж.
Для построения уровня создадим двумерный массив m на n. Каждая ячейка (m,n) будет представлять из себя прямоугольник. Прямоугольник может в себе что-то содержать, а может и быть пустым. Мы в прямоугольниках будем рисовать платформы.
Добавим еще константы
Затем добавим объявление уровня в функцию main
И в основной цикл добавим следующее:
Т.е. Мы перебираем двумерный массив level, и, если находим символ «-», то по координатам (x * PLATFORM_WIDTH, y * PLATFORM_HEIGHT), где x,y — индекс в массиве level
Запустив, мы увидим следующее:
Персонаж
Просто кубики на фоне — это очень скучно. Нам нужен наш персонаж, который будет бегать и прыгать по платформам.
Создаём класс нашего героя.
Для удобства, будем держать нашего персонажа в отдельном файле player.py
Что тут интересного?
Начнём с того, что мы создаём новый класс, наследуясь от класса pygame.sprite.Sprite, тем самым наследую все характеристики спрайта.
Cпрайт — это движущееся растровое изображение. Имеет ряд полезных методов и свойств.
self.rect = Rect(x, y, WIDTH, HEIGHT), в этой строчке мы создаем фактические границы нашего персонажа, прямоугольник, по которому мы будем не только перемещать героя, но и проверять его на столкновения. Но об этом чуть ниже.
Метод update(self, left, right)) используется для описания поведения объекта. Переопределяет родительский update(*args) → None. Может вызываться в группах спрайтов.
Метод draw(self, screen) используется для вывода персонажа на экран. Далее мы уберем этот метод и будем использовать более интересный способ отображения героя.
Добавим нашего героя в основную часть программы.
Перед определением уровня добавим определение героя и переменные его перемещения.
В проверку событий добавим следующее:
Т.е. Если нажали на клавишу «лево», то идём влево. Если отпустили — останавливаемся. Так же с кнопкой «право»
Само передвижение вызывается так: (добавляем после перерисовки фона и платформ)
Но, как мы видим, наш серый блок слишком быстро перемещается, добавим ограничение в количестве кадров в секунду. Для этого после определения уровня добавим таймер
И в начало основного цикла добавим следующее:
Завис в воздухе
Да, наш герой в безвыходном положении, он завис в воздухе.
Добавим гравитации и возможности прыгать.
И так, работаем в файле player.py
Добавим еще констант
В метод _init_ добавляем строки:
Добавляем входной аргумент в метод update
def update(self, left, right, up):
И в начало метода добавляем:
И перед строчкой self.rect.x += self.xvel
Добавляем
И добавим в основную часть программы:
После строчки left = right = False
Добавим переменную up
В проверку событий добавим
И изменим вызов метода update, добавив новый аргумент up:
hero.update(left, right)
на
Здесь мы создали силу гравитации, которая будет тянуть нас вниз, постоянно наращивая скорость, если мы не стоим на земле, и прыгать в полете мы не умеем. А мы пока не можем твердо встать на что-то, поэтому на следующей анимации наш герой падает далеко за границы видимости.
Встань обеими ногами на землю свою.
Как узнать, что мы на земле или другой твердой поверхности? Ответ очевиден — использовать проверку на пересечение, но для этого изменим создание платформ.
Создадим еще один файл blocks.py, и перенесем в него описание платформы.
Дальше создадим класс, наследуясь от pygame.sprite.Sprite
Тут нет ни чего нам уже не знакомого, идём дальше.
В основной файле произведем изменения, перед описанием массива level добавим
Группа спрайтов entities будем использовать для отображения всех элементов этой группы.
Массив platforms будем использовать для проверки на пересечение с платформой.
Т.е. создаём экземплр класса Platform, добавляем его в группу спрайтов entities и массив platforms. В entities, чтобы для каждого блока не писать логику отображения. В platforms добавили, чтобы потом проверить массив блоков на пересечение с игроком.
Дальше, весь код генерации уровня выносим из цикла.
И так же строчку
hero.draw(screen) # отображение
Заменим на
Запустив, мы увидим, что ни чего не изменилось. Верно. Ведь мы не проверяем нашего героя на столкновения. Начнём это исправлять.
Работаем в файле player.py
Удаляем метод draw, он нам больше не нужен. И добавляем новый метод collide
В этом методе происходит проверка на пересечение координат героя и платформ, если таковое имеется, то выше описанной логике происходит действие.
Ну, и для того, что бы это всё происходило, необходимо вызывать этот метод.
Изменим число аргументов для метода update, теперь он выглядит так:
И не забудьте изменить его вызов в основном файле.
Т.е. передвинули героя вертикально, проверили на пересечение по вертикали, передвинули горизонтально, снова проверили на пересечение по горизонтали.
Вот, что получится, когда запустим.
Фу[у]! Движущийся прямоугольник — не красиво!
Давайте немного приукрасим нашего МариоБоя.
Начнем с платформ. Для этого в файле blocks.py сделаем небольшие изменения.
Заменим заливку цветом на картинку, для этого строчку
self.image.fill(Color(PLATFORM_COLOR))
Заменим на
Мы загружаем картинку вместо сплошного цвета. Разумеется, файл «platform.png» должен находиться в папке «blocks», которая должна располагаться в каталоге с исходными кодами.
Вот, что получилось
Сперва добавим в блок констант.
Тут, думаю, понятно, анимация разных действий героя.
Теперь добавим следующее в метод __init__
Здесь для каждого действия мы создаем набор анимаций, и включаем их(т.е. Включаем смену кадров).
))
Каждый кадр имеет картинку и время показа.
Осталось в нужный момент показать нужную анимацию.
Добавим смену анимаций в метод update.
Вуаля!
Больше, нужно больше места
Ограничение в размере окна мы преодолеем созданием динамической камеры.
Для этого создадим класс Camera
Далее, добавим начальное конфигурирование камеры
Создадим экземпляр камеры, добавим перед основным циклом:
Мы создали внутри большого прямоугольника, размеры которого вычисляются так:
меньший прямоугольник, размером, идентичным размеру окна.
Меньший прямоугольник центрируется относительно главного персонажа(метод update), и все объекты рисуются в меньшем прямоугольнике (метод apply), за счет чего создаётся впечатление движения камеры.
Для работы вышеописанного, нужно изменить рисование объектов.
Заменим строчку
entities.draw(screen) # отображение
На
И перед ней добавим
Теперь можем изменить уровень.
Вот, собственно, и результат
Результат можно скачать, ссылка на GitHub
В следующей части, если будет востребовано сообществом, мы создадим свой генератор уровней с блэкджеком и шлюхами с разными типами платформ, монстрами, телепортами, и конечно же, принцессой.
upd pygame можно скачать отсюда, спасибо, Chris_Griffin за замечание
upd1 Вторая часть
Физика в Python с использованием Pymunk
Физика. Кто-то её любит, кто-то нет, но определённо это неотъемлемая часть нашего существования. В этой статье мы рассмотрим как самому создавать физические симуляции используя всего 2 библиотеки Python.
К концу статьи мы сделаем интерактивную симуляцию взаимодействия тел и поймём основы использования библиотеки Pymunk.
Подготовимся для начала работы
И так, создадим новый файл Python в удобной для вас IDE
Теперь нам нужно установить Pymunk и Pygame. А так же настроить их для совместной работы.
Не забудьте установить их в консоли проекта через команду pip install
Система координат PyGame отличается от системы координат PyMunk, нам нужно подогнать их под одну систему координат
PyGame
PyMunk
Добавим код в «импорт модулей» для исправления этого
Ура, мы подогнали систему координат и теперь наши библиотеки могут работать друг с другом.
Отрисовка в Pygame
Чтобы визуализировать нашу симуляцию мы будем использовать не сложный код
Зададим разрешение экрана и количество FPS.
WIDTH и HEIGHT это параметры разрешения окна Pygame.
Теперь создадим цикл отрисовки. Он будет всегда находиться в самом конце кода.
Код на данный момент выглядит так:
Наконец мы можем посмотреть что выходит.
Наше окно готово к созданию симуляции.
Создаём Пространство
Но для начала разберёмся с основными понятиями библиотеки PyMunk.
Создаём новый комментарий «Переменные PyMunk» который будет находиться после нашего раздела «Настройки PyGame» и создаём там space
Пространство есть, пора создать гравитацию.
Теперь наш раздел «Переменные PyMunk» выглядит так:
После добавления нужных переменных важно сделать следующее:
Добавим пару строк в отрисовку чтобы она рисовала наши тела созданные в PyMunk:
Код на данный момент выглядит так:
Создаём физические тела
В PyMunk есть 3 типа физических объектов: Динамические, Статические и Кинематические
Создадим Статическую платформу:
Пишем вот такой код после раздела «настройки Pymunk»
Интерактивные квадраты и их взаимодействие
Вы добрались до ключевого раздела статьи, поздравляю!
Сейчас мы разберёмся как создавать динамические тела и как сделать для них правильное взаимодействие.
Идея:
Кликая на экран программа будет добавлять новые квадраты поддающиеся законам физики.
Приступаем к реализации:
Время для первой фичи: Cделаем так, чтобы квадраты появлялись на месте где стоит курсор
Фича под номером два: цвет кубиков будет рандомен.
Сделать это можно так:
Наконец дописываем функцию, в итоге она выглядит так:
напоминаю что space.add добавляет тело в пространств
Мы на финишной прямой! Осталось только обновить отрисовку.
В итоге отрисовка выглядит так:
Проверяем
Считаю что получилось отлично 🙂
Результат
Весь исходный код:
Мы создали небольшую программу на PyGame и PyMunk с симуляцией физики.
Дальше вы можете сами изучать документацию, статьи и видео с ютюба.
Но я тоже не собираюсь заканчивать на одной статье по этой теме.
Материалы: Standalone Coder, форумы, официальная документация.
Библиотека Pygame / Часть 1. Введение
Это первая часть серии руководств « Разработка игр с помощью Pygame ». Она предназначена для программистов начального и среднего уровней, которые заинтересованы в создании игр и улучшении собственных навыков кодирования на Python.
Что такое Pygame?
Pygame — это «игровая библиотека», набор инструментов, помогающих программистам создавать игры. К ним относятся:
Графика и анимация
Звук (включая музыку)
Управление (мышь, клавиатура, геймпад и так далее)
Игровой цикл
В сердце каждой игры лежит цикл, который принято называть «игровым циклом». Он запускается снова и снова, делая все, чтобы работала игра. Каждый цикл в игре называется кадром.
В каждом кадре происходит масса вещей, но их можно разбить на три категории:
1.Обработка ввода (события)
Речь идет обо всем, что происходит вне игры — тех событиях, на которые она должна реагировать. Это могут быть нажатия клавиш на клавиатуре, клики мышью и так далее.
2.Обновление игры
Изменение всего, что должно измениться в течение одного кадра. Если персонаж в воздухе, гравитация должна потянуть его вниз. Если два объекта встречаются на большой скорости, они должны взорваться.
3.Рендеринг (прорисовка)
В этом шаге все выводится на экран: фоны, персонажи, меню. Все, что игрок должен видеть, появляется на экране в нужном месте.
Время
Еще один важный аспект игрового цикла — скорость его работы. Многие наверняка знакомы с термином FPS, который расшифровывается как Frames Per Second (или кадры в секунду). Он указывает на то, сколько раз цикл должен повториться за одну секунду. Это важно, чтобы игра не была слишком медленной или быстрой. Важно и то, чтобы игра не работала с разной скоростью на разных ПК. Если персонажу необходимо 10 секунд на то, чтобы пересечь экран, эти 10 секунд должны быть неизменными для всех компьютеров.
Создание шаблона Pygame
Теперь, зная из каких элементов состоит игра, можно переходить к процессу написания кода. Начать стоит с создания простейшей программы pygame, которая всего лишь открывает окно и запускает игровой цикл. Это отправная точка для любого проекта pygame.
В начале программы нужно импортировать необходимые библиотеки и задать базовые переменные настроек игры:
Дальше необходимо открыть окно игры:
Теперь необходимо создать игровой цикл:
Раздел рендеринга (отрисовки)
Начнем с раздела отрисовки. Персонажей пока нет, поэтому экран можно заполнить сплошным цветом. Чтобы сделать это, нужно разобраться, как компьютер обрабатывает цвета.
Экраны компьютеров сделаны из пикселей, каждый из которых содержит 3 элемента: красный, зеленый и синий. Цвет пикселя определяется тем, как горит каждый из элементов:
Каждый из трех основных цветов может иметь значение от 0 (выключен) до 255 (включен на 100%), так что для каждого элемента есть 256 вариантов.
Узнать общее количество отображаемых компьютером цветов можно, умножив:
Теперь, зная, как работают цвета, можно задать их в начале программ:
А после этого — заполнить весь экран.
Но этого недостаточно. Дисплей компьютера работает не так. Изменить пиксель — значит передать команду видеокарте, чтобы она передала соответствующую команду экрану. По компьютерным меркам это очень медленный процесс. Если нужно нарисовать на экране много всего, это займет много времени. Исправить это можно оригинальным способом, который называется — двойная буферизация. Звучит необычно, но вот что это такое.
Представьте, что у вас есть двусторонняя доска, которую можно поворачивать, показывая то одну, то вторую сторону. Одна будет дисплеем (то, что видит игрок), а вторая — оставаться скрытой, ее сможет «видеть» только компьютер. С каждым кадром рендеринг будет происходить на задней части доски. Когда отрисовка завершается, доска поворачивается и ее содержимое демонстрируется игроку.
А это значит, что процесс отрисовки происходит один раз за кадр, а не при добавлении каждого элемента.
В pygame это происходит автоматически. Нужно всего лишь сказать доске, чтобы она перевернулась, когда отрисовка завершена. Эта команда называется flip() :
Главное — сделать так, чтобы функция flip() была в конце. Если попытаться отрисовать что-то после поворота, это содержимое не отобразится на экране.
Раздел ввода (событий)
Игры еще нет, поэтому пока сложно сказать, какие кнопки или другие элементы управления понадобятся. Но нужно настроить одно важное событие. Если попытаться запустить программу сейчас, то станет понятно, что нет возможности закрыть окно. Нажать на крестик в верхнем углу недостаточно. Это тоже событие, и необходимо сообщить программе, чтобы она считала его и, соответственно, закрыла игру.
События происходят постоянно. Что, если игрок нажимает кнопку прыжка во время отрисовки? Это нельзя игнорировать, иначе игрок будет разочарован. Для этого pygame сохраняет все события, произошедшие с момента последнего кадра. Даже если игрок будет лупить по кнопкам, вы не пропустите ни одну из них. Создается список, и с помощью цикла for можно пройтись по всем из них.
Контроль FPS
Пока что нечего поместить в раздел Update (обновление), но нужно убедиться, что настройка FPS контролирует скорость игры. Это можно сделать следующим образом:
Команда tick() просит pygame определить, сколько занимает цикл, а затем сделать паузу, чтобы цикл (целый кадр) длился нужно время. Если задать значение FPS 30, это значит, что длина одного кадра — 1/30, то есть 0,03 секунды. Если цикл кода (обновление, рендеринг и прочее) занимает 0,01 секунды, тогда pygame сделает паузу на 0,02 секунды.
Наконец, нужно убедиться, что когда игровой цикл завершается, окно игры закрывается. Для этого нужно поместить функцию pygame.quit() в конце кода. Финальный шаблон pygame будет выглядеть вот так:
В следующем руководстве этот шаблон будет использован как отправная точка для изучения процесса отрисовки объектов на экране и их движения.