Eine Mindestgröße für die Lücke
Teil des Abschnitts Spielregeln der Pygame-Journey von Coddy. Lektion 16 von 29.
Die Felsen fallen schneller, aber sie kommen immer noch alle 800 ms. Felsen, die häufiger kommen, machen das Spiel ebenfalls schwieriger. Beginne mit einem Abstand von einer Sekunde und verkleinere ihn mit der Zeit:
interval = 1000 - seconds * 60Nach 10 Sekunden sind es 400 ms, nach 17 Sekunden liegt der Wert unter 0, und ein Timer mit einem Abstand von 0 oder weniger wird angehalten. Das Spiel braucht eine Untergrenze: einen kleinsten Abstand, den es nie unterschreitet. max gibt die größere der Zahlen zurück, sodass der Abstand nie unter den ersten Wert fällt:
interval = max(400, 1000 - seconds * 60)Ein Timer behält den Abstand bei, mit dem er gestartet wurde. Um ihn zu ändern, starte ihn erneut: Berechne jedes Mal, wenn ein Felsen fällt, den neuen Abstand und rufe set_timer damit auf. Der nächste Felsen kommt nach diesem Abstand.
if event.type == SPAWN and state == "play":
rocks.append(...)
seconds = (pygame.time.get_ticks() - start_time) // 1000
interval = max(400, 1000 - seconds * 60)
pygame.time.set_timer(SPAWN, interval)Aufgabe
Mittel- Starte in
reset()denSPAWN-Timer mit 1000 ms. - Setze jedes Mal, wenn ein Felsbrocken herunterfällt,
interval = max(400, 1000 - seconds * 60)und starte denSPAWN-Timer damit erneut.
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, start_time
player = pygame.Rect(220, 300, 40, 40)
rocks = []
score = 0
lives = 3
start_time = pygame.time.get_ticks()
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())
seconds = (pygame.time.get_ticks() - start_time) // 1000
speed = 3 + seconds // 5
kept = []
for rock in rocks:
rock.y += speed
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()
Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
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