Menú y mejor puntuación
Parte de la sección Reglas del juego del Journey de Pygame de Coddy. Lección 29 de 29.
Sky Runner obtiene las reglas de esta sección: un menú, una partida nueva al pulsar una tecla y la mejor puntuación.
reset() crea un nuevo corredor y un grupo vacío, restablece la puntuación y la velocidad, y reinicia ambos temporizadores. El juego comienza en "menu", y best se establece una vez, fuera de reset().
La tecla Espacio ahora cumple tres funciones, una por estado:
if state == "play":
runner.jump()
elif state == "menu":
reset()
state = "play"
elif pygame.time.get_ticks() - over_time > 500:
reset()
state = "play"Espacio es la tecla para saltar, así que a menudo el jugador la está pulsando justo en el momento de chocar. Sin una espera, el juego se reiniciaría antes de que pudiera ver el resultado. Recuerda la hora del choque en over_time y acepta Espacio en la pantalla de fin de partida solo 500 ms después.
Una pequeña función show(text, text_font, y) dibuja una línea centrada en x 320, ya que el menú y la pantalla de fin de partida necesitan cinco.
Desafío
Difícil- Escribe
reset()para el corredor, el grupo,speed,scorey ambos temporizadores; llámala antes del bucle y establecestate = "menu",best = 0yover_time = 0. - En el menú, muestra
Sky Runner(tamaño 48) yPress Space to start; la barra espaciadora o la flecha hacia arriba inicia una partida. - Cuando haya una colisión, actualiza
besty estableceover_time. - En la pantalla de fin de partida, muestra
Game over,Best: 00120(cinco dígitos) yPress Space to play again; la barra espaciadora inicia una nueva partida, pero solo 500 ms después de la colisión. - Muestra la puntuación solo durante la partida y en la pantalla de fin de partida.
Pruébalo tú mismo
import random
import pygame
pygame.init()
screen = pygame.display.set_mode((640, 320))
pygame.display.set_caption("Sky Runner")
clock = pygame.time.Clock()
font = pygame.font.Font("assets/fonts/pixel.ttf", 32)
SKY = (140, 200, 240)
GROUND = (90, 160, 80)
GROUND_Y = 260
GRAVITY = 1
SPAWN = pygame.USEREVENT + 1
POINT = pygame.USEREVENT + 2
class Runner(pygame.sprite.Sprite):
def __init__(self):
super().__init__()
self.frames = [
pygame.image.load("assets/images/player.png").convert_alpha(),
pygame.image.load("assets/images/player_walk.png").convert_alpha(),
]
self.image = self.frames[0]
self.step = 0
self.rect = self.image.get_rect(midbottom=(100, GROUND_Y))
self.vy = 0
def jump(self):
if self.rect.bottom == GROUND_Y:
self.vy = -16
def update(self):
self.vy += GRAVITY
self.rect.y += self.vy
if self.rect.bottom >= GROUND_Y:
self.rect.bottom = GROUND_Y
self.vy = 0
if self.rect.bottom == GROUND_Y:
self.step += 1
self.image = self.frames[self.step // 8 % 2]
else:
self.image = self.frames[1]
class Obstacle(pygame.sprite.Sprite):
def __init__(self):
super().__init__()
self.image = random.choice(obstacle_images)
self.rect = self.image.get_rect(midbottom=(664, GROUND_Y))
def update(self):
self.rect.x -= speed
if self.rect.right < 0:
self.kill()
obstacle_images = [
pygame.image.load("assets/images/spike_ball.png").convert_alpha(),
pygame.image.load("assets/images/blob.png").convert_alpha(),
]
runner = Runner()
obstacles = pygame.sprite.Group()
speed = 6
pygame.time.set_timer(SPAWN, 1500)
pygame.time.set_timer(POINT, 100)
score = 0
state = "play"
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.KEYDOWN and event.key in (pygame.K_SPACE, pygame.K_UP):
if state == "play":
runner.jump()
if event.type == SPAWN and state == "play":
obstacles.add(Obstacle())
pygame.time.set_timer(SPAWN, random.randint(1000, 2000))
if event.type == POINT and state == "play":
score += 1
if state == "play":
speed = min(14, 6 + score // 100)
runner.update()
obstacles.update()
if pygame.sprite.spritecollideany(runner, obstacles, pygame.sprite.collide_mask):
state = "over"
screen.fill(SKY)
pygame.draw.rect(screen, GROUND, (0, GROUND_Y, 640, 60))
screen.blit(runner.image, runner.rect)
obstacles.draw(screen)
score_text = font.render(f"{score:05}", True, (40, 50, 80))
screen.blit(score_text, score_text.get_rect(topright=(630, 10)))
if state == "over":
message = font.render("Game over", True, (40, 50, 80))
screen.blit(message, message.get_rect(center=(320, 140)))
pygame.display.flip()
clock.tick(60)
pygame.quit()
Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.
Todas las lecciones de Reglas del juego
3Temporizadores y oleadas
A salvo tras un golpeUn evento de temporizadorUna roca cada 800 msOleadas que crecenCuenta atrás para empezar6Corredor del cielo
El corredorSaltarPractica por tu cuenta: Playground de Pygame