Zusammenstoß
Teil des Abschnitts Spielregeln der Pygame-Journey von Coddy. Lektion 27 von 29.
Wenn du ein Hindernis berührst, ist der Lauf zu Ende. pygame.sprite.spritecollideany(sprite, group) gibt das erste Sprite in der Gruppe zurück, das das Sprite berührt, oder None.
Standardmäßig werden die Rechtecke verglichen. Die Bilder haben durchsichtige Ecken, vor allem der Blob, sodass sich zwei Rechtecke überschneiden können, obwohl sich nichts Sichtbares berührt. Ein drittes Argument wählt einen genaueren Test aus:
if pygame.sprite.spritecollideany(runner, obstacles, pygame.sprite.collide_mask):
state = "over"collide_mask vergleicht die gezeichneten Pixel der Bilder und ignoriert die durchsichtigen. Ein Zusammenstoß ist dann ein Zusammenstoß, den der Spieler sehen kann.
Der Zustand funktioniert wie in Meteor Dodge: Aktualisieren, Springen und neue Hindernisse finden nur statt, während der Zustand "play" ist, und der Game-Over-Bildschirm zeigt das eingefrorene Spiel mit einer Nachricht an.
Aufgabe
Mittel- Füge eine Schriftart
assets/fonts/pixel.ttfin Größe 32 undstate = "play"hinzu. - Nur während der Zustand
"play"ist: Springe, füge Hindernisse hinzu und aktualisiere den Läufer und die Hindernisse. - Wenn der Läufer ein Hindernis berührt (
collide_mask), setze den Zustand auf"over". - Wenn das Spiel vorbei ist, zeige
Game overin(40, 50, 80)zentriert bei (320, 140) an.
Probier es selbst
import random
import pygame
pygame.init()
screen = pygame.display.set_mode((640, 320))
pygame.display.set_caption("Sky Runner")
clock = pygame.time.Clock()
SKY = (140, 200, 240)
GROUND = (90, 160, 80)
GROUND_Y = 260
GRAVITY = 1
SPAWN = pygame.USEREVENT + 1
class Runner(pygame.sprite.Sprite):
def __init__(self):
super().__init__()
self.frames = [
pygame.image.load("assets/images/player.png").convert_alpha(),
pygame.image.load("assets/images/player_walk.png").convert_alpha(),
]
self.image = self.frames[0]
self.step = 0
self.rect = self.image.get_rect(midbottom=(100, GROUND_Y))
self.vy = 0
def jump(self):
if self.rect.bottom == GROUND_Y:
self.vy = -16
def update(self):
self.vy += GRAVITY
self.rect.y += self.vy
if self.rect.bottom >= GROUND_Y:
self.rect.bottom = GROUND_Y
self.vy = 0
if self.rect.bottom == GROUND_Y:
self.step += 1
self.image = self.frames[self.step // 8 % 2]
else:
self.image = self.frames[1]
class Obstacle(pygame.sprite.Sprite):
def __init__(self):
super().__init__()
self.image = random.choice(obstacle_images)
self.rect = self.image.get_rect(midbottom=(664, GROUND_Y))
def update(self):
self.rect.x -= speed
if self.rect.right < 0:
self.kill()
obstacle_images = [
pygame.image.load("assets/images/spike_ball.png").convert_alpha(),
pygame.image.load("assets/images/blob.png").convert_alpha(),
]
runner = Runner()
obstacles = pygame.sprite.Group()
speed = 6
pygame.time.set_timer(SPAWN, 1500)
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.KEYDOWN and event.key in (pygame.K_SPACE, pygame.K_UP):
runner.jump()
if event.type == SPAWN:
obstacles.add(Obstacle())
pygame.time.set_timer(SPAWN, random.randint(1000, 2000))
runner.update()
obstacles.update()
screen.fill(SKY)
pygame.draw.rect(screen, GROUND, (0, GROUND_Y, 640, 60))
screen.blit(runner.image, runner.rect)
obstacles.draw(screen)
pygame.display.flip()
clock.tick(60)
pygame.quit()
Alle Lektionen in Spielregeln
Übe selbstständig: Pygame-Playground