¿Cómo hacer que un personaje salte en Pygame?

Resuelto Rabbid76 asked hace 2 años • 1 respuestas

Quiero hacer que mi personaje salte. En mi intento actual, el jugador sube mientras mantengo presionado SPACEv y cae cuando lo suelto 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() 

Sin embargo, quiero que el personaje salte si lo golpeo SPACEuna vez. Quiero que comience una animación de salto suave cuando SPACEse presiona una vez. ¿Cómo haría esto paso a paso?

Rabbid76 avatar Jan 05 '22 17:01 Rabbid76
Aceptado

Para hacer que un personaje salte tienes que usar el KEYDOWNevento, pero no pygame.key.get_pressed(). pygame.key.get_pressed ()es para movimiento continuo cuando se mantiene presionada una tecla. Los eventos del teclado se utilizan para desencadenar una única acción o para iniciar una animación como un salto. Ver también ¿Cómo obtener entrada de teclado en pygame?

pygame.key.get_pressed()devuelve una secuencia con el estado de cada clave. Si se mantiene presionada una tecla, el estado de la clave es True; en caso contrario False. Úselo pygame.key.get_pressed()para evaluar el estado actual de un botón y obtener un movimiento continuo.

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

Utilice pygame.time.Clock( "Este método debe llamarse una vez por cuadro." ) controla los cuadros por segundo y, por lo tanto, la velocidad del juego y la duración del salto.

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

El salto debe ser independiente del movimiento del jugador o del flujo general de control del juego. Por lo tanto, la animación de salto en el bucle de la aplicación debe ejecutarse en paralelo al juego en ejecución.

Cuando lanzas una pelota o algo salta, el objeto forma una curva parabólica. El objeto gana altura rápidamente al principio, pero esto se ralentiza hasta que el objeto comienza a caer cada vez más rápido. El cambio de altura de un objeto que salta se puede describir con la siguiente secuencia:

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

Dicha serie se puede generar con el siguiente algoritmo ( yes la coordenada y del objeto):

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

Un enfoque más sofisticado es definir constantes para la gravedad y la aceleración del jugador cuando salta:

acceleration = 10
gravity = 0.5

La aceleración ejercida sobre el jugador en cada cuadro es la constante de gravedad, si el jugador salta entonces la aceleración cambia a la aceleración de "salto" para un solo cuadro:

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

En cada cuadro, la velocidad vertical cambia según la aceleración y la coordenada y cambia según la velocidad. Cuando el jugador toque el suelo, el movimiento vertical se detendrá:

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

Ver también Saltar


Ejemplo 1: 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() 

Ejemplo 2: 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() 
Rabbid76 avatar Jan 05 '2022 10:01 Rabbid76