Pygame как сделать прыжок

от admin

pygame

In this article you will learn how to implement jump and run logic in Pygame. To do so, we will implement the player logic.

Movement
Moving left and right is similar to the previous tutorial and simply mean changing the (x,y) position of the player. For jumping, we use a formula from classical mechanics:

Where F is the force up/down, m is the mass of your object and v is the velocity. The velocity goes down over time because when the player jumps the velocity will not increase more in this simulation. If the player reaches the ground, the jump ends. In Python, we set a variable isjump to indicate if the player is jumping or not. If the player is, its position will be updated according to the above formula.

If you want to jump on objects, simply add them to the screen, do collision detection and reset the jump variables if collision is true.

Leave a Reply:

Thanks, this is a rock-solid foundation to start with 🙂

Very helpful tutorial for understanding pygame programming.

Your physics is a little off. Force, F = ma. The expression 1/2 * m * v^2 is kinetic energy not force. But what you really want to do is calculate the change in the vertical y-coordinate for constant gravity acceleration while jumping. The change in y-coordinate is given by dy = v * dt, where dt is the constant time step. The vertical velocity, v, does decrease linearly due to constant acceleration (because v = at) as your example program does. But the F term should be proportional to v not v^2. If you change (self.v*self.v) to (self.v) you don’t need the if/else because the expression proportional to self.v changes sign with self.v. Mass doesn’t play into vertical velocity (ignoring air drag) as all objects are accelerated by gravity at the same rate.

To keep changes to a minimum, I replaced the «if self.v>0» expression for F with one line:
F = ( self.m * self.v)
Then I changed self.m = 8 to make jump height about same as original.

Changing the code that handles the jump physics results in a nice parabolic jump as in real world physics. The velocity squared physics rises quickly initially and hovers at the top of the arc longer. That may be desirable for some games, but it isn’t how jumping works in the real world.

How to make a character jump in Pygame?

I want to make my character jump. In my current attempt, the player moves up as long as I hold down SPACE v and falls down when I release SPACE .

However, I want the character to jump if I hit the SPACE once. I want a smooth jump animation to start when SPACE is pressed once. How would I go about this step by step?

Rabbid76's user avatar

1 Answer 1

To make a character jump you have to use the KEYDOWN event, but not pygame.key.get_pressed() . pygame.key.get_pressed () is for continuous movement when a key is held down. The keyboard events are used to trigger a single action or to start an animation such as a jump. See alos How to get keyboard input in pygame?

pygame.key.get_pressed() returns a sequence with the state of each key. If a key is held down, the state for the key is True , otherwise False . Use pygame.key.get_pressed() to evaluate the current state of a button and get continuous movement.

Use pygame.time.Clock ("This method should be called once per frame.") you control the frames per second and thus the game speed and the duration of the jump.

The jumping should be independent of the player’s movement or the general flow of control of the game. Therefore, the jump animation in the application loop must be executed in parallel to the running game.

When you throw a ball or something jumps, the object makes a parabolic curve. The object gains height quickly at the beginning, but this slows down until the object begins to fall faster and faster again. The change in height of a jumping object can be described with the following sequence:

Such a series can be generated with the following algorithm ( y is the y coordinate of the object):

A more sophisticated approach is to define constants for the gravity and player’s acceleration as the player jumps:

The acceleration exerted on the player in each frame is the gravity constant, if the player jumps then the acceleration changes to the "jump" acceleration for a single frame:

In each frame the vertical velocity is changed depending on the acceleration and the y-coordinate is changed depending on the velocity. When the player touches the ground, the vertical movement will stop:

Example 1: replit.com/@Rabbid76/PyGame-Jump

Example 2: replit.com/@Rabbid76/PyGame-JumpAcceleration

Pygame – adding Gravity and Jumping

report this ad report this ad report this ad

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.

Moving on, the only change you have to do is to the first line in the move() function of the player. You simply have to change the value of the second parameter from 0 to 0.5 .

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.

  • The first parameter takes a single sprite as input, like our Player sprite, P1 .
  • The second parameter takes a sprite_group like all_sprites . This function then checks to see if the sprite in first parameter, is touching any of the sprites in the sprite_group .
  • The last parameter takes a True or False value, depending on if you want the sprite to be deleted or not after a collision. (Keep this False for most cases).

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.

Back to the update method. The spritecollide() function returns it’s value into hits . We now use an if statement that will activate if a collision has occurred.

Two things are necessary in order to stop the effect of gravity on platforms. One, we need to set the velocity of the Player to zero, using self.vel.y = 0 . Note, we only set the vertical velocity to zero, otherwise we wouldn’t be able to move horizontally on platforms. Secondly, we relocate the player on top of the platform by updating the self.pos.y variable with the top y-coordinate of the platform.

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.

Читать:
Чипсет intel hm65 express какие процессоры поддерживает

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.

Пишем платформер на Python, используя pygame

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

Давно хотел попробовать себя в качестве игродела, и недавно выпал случай изучить 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», которая должна располагаться в каталоге с исходными кодами.

Вот, что получилось

Теперь переходим к нашему герою. Для движущегося объекта нужна не статическая картинка, а анимация. Дабы облегчить себе эту задачу, воспользуемся замечательной библиотекой pyganim . Приступим.

Сперва добавим в блок констант.

Тут, думаю, понятно, анимация разных действий героя.

Теперь добавим следующее в метод __init__

Здесь для каждого действия мы создаем набор анимаций, и включаем их(т.е. Включаем смену кадров).
))
Каждый кадр имеет картинку и время показа.

Осталось в нужный момент показать нужную анимацию.

Добавим смену анимаций в метод update.

Больше, нужно больше места

Ограничение в размере окна мы преодолеем созданием динамической камеры.

Для этого создадим класс Camera

Далее, добавим начальное конфигурирование камеры

Создадим экземпляр камеры, добавим перед основным циклом:

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

меньший прямоугольник, размером, идентичным размеру окна.

Меньший прямоугольник центрируется относительно главного персонажа(метод update), и все объекты рисуются в меньшем прямоугольнике (метод apply), за счет чего создаётся впечатление движения камеры.

Для работы вышеописанного, нужно изменить рисование объектов.

Заменим строчку
entities.draw(screen) # отображение
На

И перед ней добавим

Теперь можем изменить уровень.

Вот, собственно, и результат

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

upd pygame можно скачать отсюда, спасибо, Chris_Griffin за замечание
upd1 Вторая часть

Related Posts