Eine ansteigende Geschwindigkeit
Teil des Abschnitts Spielregeln der Pygame-Journey von Coddy. Lektion 15 von 29.
Ein Spiel, das sich nie verändert, wird langweilig, und wer mit einem hohen Schwierigkeitsgrad beginnt, vergrault neue Spieler. Beginne sanft und erhöhe den Schwierigkeitsgrad, je länger der Spieler durchhält.
Die Zeit seit Spielbeginn bestimmt die Geschwindigkeit. reset() merkt sich, wann das war, und jeder Frame berechnet daraus die Geschwindigkeit:
seconds = (pygame.time.get_ticks() - start_time) // 1000
speed = 3 + seconds // 5seconds // 5 erhöht sich alle fünf Sekunden um 1. So fallen die Felsen anfangs mit 3 Pixeln pro Frame, nach fünf Sekunden mit 4 und nach zehn Sekunden mit 5. Ganze Schritte halten die Geschwindigkeit ganzzahlig, was ein Rect benötigt: Es speichert ganze Pixel, sodass bei rock.y += 3.5 der halbe Pixel verloren ginge.
Sowohl Enter als auch R rufen reset() auf, sodass die Uhr bei jedem Spiel neu startet, unabhängig davon, wie lange das Menü angezeigt wurde.
Aufgabe
Mittel- Setze in
reset()start_timeaufpygame.time.get_ticks(). - Berechne in
play_frame()die seitstart_timevergangenensecondsundspeed = 3 + seconds // 5. - Bewege jeden Felsen mit
speedstatt mit 3 nach unten.
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()
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
player = pygame.Rect(220, 300, 40, 40)
rocks = []
score = 0
lives = 3
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))
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)
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 rocks, lives, 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())
kept = []
for rock in rocks:
rock.y += 3
if rock.colliderect(player):
lives -= 1
elif rock.top <= 360:
kept.append(rock)
rocks = kept
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":
rocks.append(pygame.Rect(random.randint(0, 456), -24, 24, 24))
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_RETURN and state == "menu":
reset()
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()
Alle Lektionen in Spielregeln
1Spielzustände
Eine ZustandsvariableEin MenübildschirmDrücke R, um erneut zu spielenEine Reset-FunktionEine Funktion pro Zustand4Schwierigkeitsgrad
Eine ansteigende GeschwindigkeitEine Mindestgröße für die LückeNormal oder SchwerGewichtete AuswahlÜbe selbstständig: Pygame-Playground