Menu
CoddyTech

Zderzenie

Część sekcji Zasady gry ścieżki Pygame w Coddy. Lekcja 27 z 29.

Dotknięcie przeszkody kończy rozgrywkę. pygame.sprite.spritecollideany(sprite, group) zwraca pierwszy duszek z grupy, który dotyka duszka, albo None.

Domyślnie porównuje prostokąty. Obrazki mają przezroczyste rogi, szczególnie blob, więc dwa prostokąty mogą na siebie nachodzić, mimo że nic, co widzisz, się nie dotyka. Trzeci argument wybiera dokładniejszy test:

if pygame.sprite.spritecollideany(runner, obstacles, pygame.sprite.collide_mask):
    state = "over"

collide_mask porównuje narysowane piksele obrazków i ignoruje te przezroczyste. Kolizja następuje więc wtedy, gdy gracz może ją zobaczyć.

Stan działa tak jak w Meteor Dodge: aktualizacja, skoki i pojawianie się nowych przeszkód odbywają się tylko wtedy, gdy jego wartość to "play", a ekran końca gry wyświetla zamrożoną rozgrywkę z komunikatem.

challenge icon

Wyzwanie

Średni
  1. Dodaj czcionkę assets/fonts/pixel.ttf w rozmiarze 32 oraz state = "play".
  2. Tylko gdy stan to "play": skacz, dodawaj przeszkody oraz aktualizuj biegacza i przeszkody.
  3. Gdy biegacz dotknie przeszkody (collide_mask), ustaw stan na "over".
  4. Po zakończeniu gry wyświetl Game over w kolorze (40, 50, 80), wyśrodkowane w punkcie (320, 140).

Spróbuj swoich sił

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

Wszystkie lekcje w sekcji Zasady gry

Poćwicz samodzielnie: Edytor online Pygame