Cuenta atrás para empezar
Parte de la sección Reglas del juego del Journey de Pygame de Coddy. Lección 14 de 29.
Al presionar Enter, el jugador cae directamente entre rocas que se desploman. Una cuenta regresiva, 3, 2, 1, le da un momento para prepararse. Es un estado más, "countdown", que dibuja el juego sin moverlo, con un número en la parte superior.
El número se obtiene a partir del tiempo transcurrido desde que comenzó la cuenta regresiva:
left = 3 - (pygame.time.get_ticks() - countdown_start) // 1000Durante el primer segundo, // da 0, así que left es 3; después 2 y luego 1. Cuando llega a 0, comienza el juego:
def countdown_frame():
global state
left = 3 - (pygame.time.get_ticks() - countdown_start) // 1000
draw_game()
if left > 0:
number = big_font.render(str(left), True, WHITE)
screen.blit(number, number.get_rect(center=(240, 170)))
else:
state = "play"Tanto Enter como R inician una cuenta regresiva, así que una pequeña función establece el estado y recuerda la hora de inicio:
def start_countdown():
global state, countdown_start
state = "countdown"
countdown_start = pygame.time.get_ticks()Desafío
Intermedio- Escribe
start_countdown()ycountdown_frame()como se muestra, y llama acountdown_frame()cuando el estado sea"countdown". - Enter en el menú y R en la pantalla de fin de partida llaman a
start_countdown()en lugar de establecer"play". - La cuenta regresiva muestra
3,2y1durante un segundo cada uno, centrados en (240, 170).
Pruébalo tú mismo
import random
import pygame
pygame.init()
screen = pygame.display.set_mode((480, 360))
pygame.display.set_caption("Meteor Dodge")
clock = pygame.time.Clock()
heart = pygame.image.load("assets/images/heart.png").convert_alpha()
heart_empty = pygame.image.load("assets/images/heart_empty.png").convert_alpha()
font = pygame.font.Font("assets/fonts/pixel.ttf", 24)
big_font = pygame.font.Font("assets/fonts/pixel.ttf", 48)
WHITE = (240, 240, 240)
PLATE = (60, 60, 90)
POINT = pygame.USEREVENT + 1
SPAWN = pygame.USEREVENT + 2
def reset():
global player, rocks, score, lives, hit_time, wave, to_spawn
player = pygame.Rect(220, 300, 40, 40)
rocks = []
wave = 1
to_spawn = 3
score = 0
lives = 3
hit_time = -2000
pygame.time.set_timer(POINT, 1000)
pygame.time.set_timer(SPAWN, 800)
def draw_menu():
screen.fill((30, 30, 46))
title = big_font.render("Meteor Dodge", True, WHITE)
title_rect = title.get_rect(center=(240, 140))
pygame.draw.rect(screen, PLATE, title_rect.inflate(24, 12))
screen.blit(title, title_rect)
hint = font.render("Press Enter to play", True, WHITE)
screen.blit(hint, hint.get_rect(center=(240, 200)))
def draw_game():
screen.fill((30, 30, 46))
safe = pygame.time.get_ticks() - hit_time < 1000
if not safe or pygame.time.get_ticks() // 100 % 2 == 0:
pygame.draw.rect(screen, (255, 196, 0), player)
for rock in rocks:
pygame.draw.rect(screen, (235, 80, 80), rock)
score_text = font.render(f"{score:05}", True, WHITE)
score_rect = score_text.get_rect(topright=(470, 10))
pygame.draw.rect(screen, PLATE, score_rect.inflate(12, 8))
screen.blit(score_text, score_rect)
wave_text = font.render(f"Wave {wave}", True, WHITE)
screen.blit(wave_text, wave_text.get_rect(midtop=(240, 10)))
for i in range(3):
if i < lives:
screen.blit(heart, (10 + i * 40, 10))
else:
screen.blit(heart_empty, (10 + i * 40, 10))
def play_frame():
global score, lives, state, hit_time, rocks, wave, to_spawn
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
player.x -= 6
if keys[pygame.K_RIGHT]:
player.x += 6
player.clamp_ip(screen.get_rect())
for rock in rocks:
rock.y += 4
rocks = [rock for rock in rocks if rock.top <= 360]
if to_spawn == 0 and not rocks:
wave += 1
to_spawn = wave + 2
now = pygame.time.get_ticks()
for rock in rocks:
if rock.colliderect(player) and now - hit_time > 1000:
hit_time = now
lives -= 1
if lives == 0:
state = "over"
draw_game()
def draw_over():
draw_game()
message = big_font.render("Game over", True, WHITE)
screen.blit(message, message.get_rect(center=(240, 160)))
hint = font.render("Press R to play again", True, WHITE)
screen.blit(hint, hint.get_rect(center=(240, 200)))
reset()
state = "menu"
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == POINT and state == "play":
score += 1
if event.type == SPAWN and state == "play" and to_spawn > 0:
rocks.append(pygame.Rect(random.randint(0, 456), -24, 24, 24))
to_spawn -= 1
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_RETURN and state == "menu":
state = "play"
elif event.key == pygame.K_r and state == "over":
reset()
state = "play"
if state == "menu":
draw_menu()
elif state == "play":
play_frame()
else:
draw_over()
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 empezarPractica por tu cuenta: Playground de Pygame