简体   繁体   English

如何在Pygame中进行字符跳跃?

[英]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 .在我目前的尝试中,只要我按住SPACE v 玩家就会向上移动,而当我释放SPACE时玩家会倒下。

import pygame

pygame.init()
window = pygame.display.set_mode((300, 300))
clock = pygame.time.Clock()

rect = pygame.Rect(135, 220, 30, 30) 
vel = 5

run = True
while run:
    clock.tick(100)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False

    keys = pygame.key.get_pressed()    
    rect.centerx = (rect.centerx + (keys[pygame.K_RIGHT] - keys[pygame.K_LEFT]) * vel) % 300
    
    if keys[pygame.K_SPACE]:
        rect.y -= 1
    elif rect.y < 220:
        rect.y += 1

    window.fill((0, 0, 64))
    pygame.draw.rect(window, (64, 64, 64), (0, 250, 300, 100))
    pygame.draw.circle(window, (255, 0, 0), rect.center, 15)
    pygame.display.flip()

pygame.quit()
exit() 

However, I want the character to jump if I hit the SPACE once.但是,如果我按下SPACE一次,我希望角色跳跃。 I want a smooth jump animation to start when SPACE is pressed once.我希望 animation 在按下一次SPACE时开始平滑跳转。 How would I go about this step by step?请问我go 怎么一步步讲这个?

To make a character jump you have to use the KEYDOWN event, but notpygame.key.get_pressed() .要进行角色跳跃,您必须使用KEYDOWN事件,但不能使用pygame.key.get_pressed() pygame.key.get_pressed () is for continuous movement when a key is held down. pygame.key.get_pressed ()用于在按住某个键时进行连续移动。 The keyboard events are used to trigger a single action or to start an animation such as a jump.键盘事件用于触发单个动作或启动 animation,例如跳跃。 See alos How to get keyboard input in pygame?另请参阅如何在 pygame 中获取键盘输入?

pygame.key.get_pressed() returns a sequence with the state of each key. pygame.key.get_pressed()返回一个序列,其中每个键的 state。 If a key is held down, the state for the key is True , otherwise False .如果按住某个键,则该键的 state 为True ,否则为False Usepygame.key.get_pressed() to evaluate the current state of a button and get continuous movement.使用pygame.key.get_pressed()评估按钮的当前 state 并获得连续移动。

while True:
    for event in pygame.event.get():
        if event.type == pygame.KEYDOWN and event.key == pygame.K_SPACE:
            jump = True

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.使用pygame.time.Clock“此方法应每帧调用一次。” )您控制每秒帧数,从而控制游戏速度和跳跃的持续时间。

clock = pygame.time.Clock()
while True:
   clock.tick(100)

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.因此,应用循环中的跳转animation必须与运行游戏并行执行。

When you throw a ball or something jumps, the object makes a parabolic curve.当您扔球或跳跃时,object 会形成抛物线。 The object gains height quickly at the beginning, but this slows down until the object begins to fall faster and faster again. object 在开始时迅速增加高度,但这种速度会减慢,直到 object 再次开始越来越快地下降。 The change in height of a jumping object can be described with the following sequence:跳跃的 object 的高度变化可以用以下顺序描述:

[10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, -1, -2, -3, -4, -5, -6, -7, -8, -9, -10]

Such a series can be generated with the following algorithm ( y is the y coordinate of the object):可以使用以下算法生成这样的系列( y是对象的 y 坐标):

jumpMax = 10
if jump:
    y -= jumpCount
    if jumpCount > -jumpMax:
        jumpCount -= 1
    else:
        jump = False 

A more sophisticated approach is to define constants for the gravity and player's acceleration as the player jumps:一种更复杂的方法是为玩家跳跃时的重力和玩家加速度定义常量:

acceleration = 10
gravity = 0.5

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:在每一帧中施加在玩家身上的加速度是重力常数,如果玩家跳跃,那么加速度将变为单帧的“跳跃”加速度:

acc_y = gravity
for event in pygame.event.get():
    if event.type == pygame.KEYDOWN: 
        if vel_y == 0 and event.key == pygame.K_SPACE:
            acc_y = -acceleration

In each frame the vertical velocity is changed depending on the acceleration and the y-coordinate is changed depending on the velocity.在每一帧中,垂直速度根据加速度而改变,而 y 坐标根据速度而改变。 When the player touches the ground, the vertical movement will stop:当玩家接触地面时,垂直运动将停止:

vel_y += acc_y
y += vel_y
if y > ground_y:
    y = ground_y
    vel_y = 0
    acc_y = 0

See also Jump参见跳转


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

import pygame

pygame.init()
window = pygame.display.set_mode((300, 300))
clock = pygame.time.Clock()

rect = pygame.Rect(135, 220, 30, 30) 
vel = 5
jump = False
jumpCount = 0
jumpMax = 15

run = True
while run:
    clock.tick(50)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False
        if event.type == pygame.KEYDOWN: 
            if not jump and event.key == pygame.K_SPACE:
                jump = True
                jumpCount = jumpMax

    keys = pygame.key.get_pressed()    
    rect.centerx = (rect.centerx + (keys[pygame.K_RIGHT] - keys[pygame.K_LEFT]) * vel) % 300
    
    if jump:
        rect.y -= jumpCount
        if jumpCount > -jumpMax:
            jumpCount -= 1
        else:
            jump = False 

    window.fill((0, 0, 64))
    pygame.draw.rect(window, (64, 64, 64), (0, 250, 300, 100))
    pygame.draw.circle(window, (255, 0, 0), rect.center, 15)
    pygame.display.flip()

pygame.quit()
exit() 

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

import pygame

pygame.init()
window = pygame.display.set_mode((300, 300))
clock = pygame.time.Clock()

player = pygame.sprite.Sprite()
player.image = pygame.Surface((30, 30), pygame.SRCALPHA)
pygame.draw.circle(player.image, (255, 0, 0), (15, 15), 15)
player.rect = player.image.get_rect(center = (150, 235))
all_sprites = pygame.sprite.Group([player])

y, vel_y = player.rect.bottom, 0
vel = 5
ground_y = 250
acceleration = 10
gravity = 0.5

run = True
while run:
    clock.tick(100)
    acc_y = gravity
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False
        if event.type == pygame.KEYDOWN: 
            if vel_y == 0 and event.key == pygame.K_SPACE:
                acc_y = -acceleration

    keys = pygame.key.get_pressed()    
    player.rect.centerx = (player.rect.centerx + (keys[pygame.K_RIGHT] - keys[pygame.K_LEFT]) * vel) % 300
    
    vel_y += acc_y
    y += vel_y
    if y > ground_y:
        y = ground_y
        vel_y = 0
        acc_y = 0
    player.rect.bottom = round(y)

    window.fill((0, 0, 64))
    pygame.draw.rect(window, (64, 64, 64), (0, 250, 300, 100))
    all_sprites.draw(window)
    pygame.display.flip()

pygame.quit()
exit() 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM