Menu
CoddyTech

Un evento del timer

Fa parte della sezione Regole di gioco del percorso Pygame di Coddy. Lezione 11 di 29.

Un punto per ogni roccia che cade oltre premia l'attesa. Un punto per ogni secondo in cui sopravvivi è più equo. pygame può inviare al tuo gioco un evento proprio ogni secondo.

I tipi di evento sono numeri. pygame.USEREVENT è il primo che pygame lascia libero per te, quindi assegna al tuo un nome a partire da questo:

POINT = pygame.USEREVENT + 1
...
pygame.time.set_timer(POINT, 1000)

Da quel momento, un evento POINT arriva ogni 1000 ms insieme agli altri eventi, e lo gestisci come la pressione di un tasto:

if event.type == POINT and state == "play":
    score += 1

Il timer continua a funzionare nel menu e nella schermata di fine partita, quindi controlla lo stato. Chiamare di nuovo set_timer lo riavvia, ecco perché va in reset(): ogni nuova partita attende un secondo intero prima del primo punto.

challenge icon

Sfida

Medio
  1. Aggiungi POINT = pygame.USEREVENT + 1 dopo i colori.
  2. In reset(), avvia un timer che invia POINT ogni 1000 ms.
  3. Durante il gioco, quando si verifica un evento POINT, aggiungi 1 al punteggio.
  4. Le rocce che cadono oltre non fanno più guadagnare punti.

Provalo tu

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)


def reset():
    global player, rock, score, lives, hit_time
    player = pygame.Rect(220, 300, 40, 40)
    rock = pygame.Rect(random.randint(0, 456), -24, 24, 24)
    score = 0
    lives = 3
    hit_time = -2000


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)
    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)
    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
    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())

    rock.y += 4
    if rock.top > 360:
        rock.y = -24
        rock.x = random.randint(0, 456)
        score += 1
    now = pygame.time.get_ticks()
    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 == 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()
quiz iconMettiti alla prova

Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.

Tutte le lezioni di Regole di gioco

Esercitati da solo: Playground Pygame