Menu
CoddyTech

Schianto

Fa parte della sezione Regole di gioco del percorso Pygame di Coddy. Lezione 27 di 29.

Toccare un ostacolo termina la partita. pygame.sprite.spritecollideany(sprite, group) restituisce il primo sprite del gruppo che tocca lo sprite, oppure None.

Per impostazione predefinita, confronta i rettangoli. Le immagini hanno angoli trasparenti, soprattutto quella della macchia, quindi due rettangoli possono sovrapporsi senza che gli elementi visibili si tocchino. Un terzo argomento seleziona un controllo più preciso:

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

collide_mask confronta i pixel disegnati delle immagini e ignora quelli trasparenti. Così, una collisione è una collisione che il giocatore può vedere.

Lo stato funziona come in Meteor Dodge: l'aggiornamento, i salti e la comparsa di nuovi ostacoli avvengono solo quando è "play", mentre la schermata di fine partita mostra il gioco congelato con un messaggio.

challenge icon

Sfida

Medio
  1. Aggiungi un font, assets/fonts/pixel.ttf con dimensione 32, e state = "play".
  2. Solo mentre lo stato è "play": salta, aggiungi ostacoli e aggiorna il corridore e gli ostacoli.
  3. Quando il corridore tocca un ostacolo (collide_mask), imposta lo stato su "over".
  4. Quando il gioco è finito, mostra Game over in (40, 50, 80) centrato in (320, 140).

Provalo tu

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

Tutte le lezioni di Regole di gioco

Esercitati da solo: Playground Pygame