¿Cómo hacer que un personaje salte en Pygame?
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?
Para hacer que un personaje salte tienes que usar el KEYDOWN
evento, 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 ( y
es 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()