Menu
CoddyTech

Eine Funktion pro Zustand

Teil des Abschnitts Spielregeln der Pygame-Journey von Coddy. Lektion 5 von 29.

Die Schleife mischte drei Bildschirme, und jeder neue Zustand hätte eine weitere Ebene von if in der Zeichen- und Aktualisierungslogik hinzugefügt. Stattdessen erhält jeder Zustand in der Vorlage eine eigene Funktion, und die Schleife wählt eine davon aus:

if state == "menu":
    draw_menu()
elif state == "play":
    play_frame()
else:
    draw_over()

play_frame() bewegt die Objekte, prüft die Kollision und zeichnet. draw_menu() und draw_over() zeichnen nur. Der Spielende-Bildschirm zeigt das eingefrorene Spiel unter seiner Nachricht, deshalb verwenden beide eine gemeinsame Funktion draw_game() für den Spieler, den Felsen und den Punktestand.

Eine Funktion, die den Zustand oder den Punktestand ändert, benötigt diese nach global:

def play_frame():
    global score, state

Zum Verschieben von player.x ist kein global nötig: Es ändert das Rect, weist ihm aber keinen neuen Wert zu.

Mit diesem Aufbau besteht ein neuer Zustand aus einer Funktion und einem elif. Füge auf diese Weise einen Pausenbildschirm hinzu.

challenge icon

Aufgabe

Mittel
  1. Füge den Zustand "paused" hinzu: Während des Spiels pausiert P das Spiel; ein erneuter Druck auf P setzt das Spiel fort.
  2. Schreibe draw_paused(): das eingefrorene Spiel mit Paused zentriert bei (240, 160).
  3. Rufe die Funktion in der Schleife auf, solange der Zustand "paused" ist, mit einem weiteren elif.

Probier es selbst

import random
import pygame

pygame.init()
screen = pygame.display.set_mode((480, 360))
pygame.display.set_caption("Meteor Dodge")
clock = pygame.time.Clock()
font = pygame.font.Font(None, 32)
WHITE = (240, 240, 240)


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


def draw_menu():
    screen.fill((30, 30, 46))
    title = font.render("Meteor Dodge", True, WHITE)
    screen.blit(title, title.get_rect(center=(240, 140)))
    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))
    pygame.draw.rect(screen, (255, 196, 0), player)
    pygame.draw.rect(screen, (235, 80, 80), rock)
    score_text = font.render(f"Score: {score}", True, WHITE)
    screen.blit(score_text, (10, 10))


def play_frame():
    global score, state
    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
    if rock.colliderect(player):
        state = "over"
    draw_game()


def draw_over():
    draw_game()
    message = 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 iconTeste dich selbst

Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.

Alle Lektionen in Spielregeln

Übe selbstständig: Pygame-Playground