Menu
CoddyTech

Toucher et marquer des points

Fait partie de la section Sprites et images du Journey Pygame de Coddy. Leçon 33 sur 36.

Les lasers contre les ennemis, c’est un groupe contre un groupe, avec groupcollide. L’image d’un laser est un fin trait au milieu d’un carré de 48 pixels, donc un test avec Rect permettrait à un laser situé à 20 pixels sur le côté de détruire un ennemi. Testez les images à l’aide de masques :

hits = pygame.sprite.groupcollide(enemies, lasers, True, True, pygame.sprite.collide_mask)
for enemy in hits:
    score += 10

Le cinquième argument est le test, comme avec spritecollide. Attribuez à Laser et à Enemy un self.mask = pygame.mask.from_surface(self.image) chacun, afin que les masques soient créés une seule fois, et non à chaque test.

Parcourir hits permet de traiter les ennemis détruits un par un : chacun vaut 10 points. Affichez le score en haut à gauche avec font = pygame.font.Font(None, 32), créé une seule fois avant la boucle.

challenge icon

Défi

Moyen
  1. Ajoutez self.mask à Laser et à Enemy.
  2. Définissez score = 0 et une police de taille 32 avant la boucle.
  3. Après les mises à jour, détectez les collisions entre enemies et lasers à l’aide de pygame.sprite.collide_mask, en détruisant les deux, puis ajoutez 10 à score pour chaque ennemi touché.
  4. Affichez Score: et le score aux coordonnées (10, 10), en (240, 240, 240).

Essayez vous-même

import random
import pygame

pygame.init()
screen = pygame.display.set_mode((640, 480))
pygame.display.set_caption("Star Patrol")
clock = pygame.time.Clock()

ship_image = pygame.image.load("assets/images/ship.png").convert_alpha()
laser_image = pygame.image.load("assets/images/laser.png").convert_alpha()
red_image = pygame.image.load("assets/images/enemy_red.png").convert_alpha()


class Player(pygame.sprite.Sprite):
    def __init__(self):
        super().__init__()
        self.image = ship_image
        self.rect = self.image.get_rect(midbottom=(320, 470))

    def update(self):
        keys = pygame.key.get_pressed()
        if keys[pygame.K_LEFT]:
            self.rect.x -= 6
        if keys[pygame.K_RIGHT]:
            self.rect.x += 6
        self.rect.clamp_ip(screen.get_rect())


class Laser(pygame.sprite.Sprite):
    def __init__(self, x, y):
        super().__init__()
        self.image = laser_image
        self.rect = self.image.get_rect(midbottom=(x, y))

    def update(self):
        self.rect.y -= 10
        if self.rect.bottom < 0:
            self.kill()


class Enemy(pygame.sprite.Sprite):
    def __init__(self, image, x, y, speed):
        super().__init__()
        self.image = image
        self.rect = self.image.get_rect(center=(x, y))
        self.speed = speed

    def update(self):
        self.rect.y += self.speed


def spawn_wave(image, count, speed):
    for i in range(count):
        x = random.randint(40, 600)
        enemies.add(Enemy(image, x, -40 - i * 120, speed))


player = Player()
lasers = pygame.sprite.Group()
enemies = pygame.sprite.Group()
last_shot = 0
spawn_wave(red_image, 6, 2)

running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

    player.update()
    keys = pygame.key.get_pressed()
    now = pygame.time.get_ticks()
    if keys[pygame.K_SPACE] and now - last_shot >= 250:
        lasers.add(Laser(player.rect.centerx, player.rect.top))
        last_shot = now
    lasers.update()
    enemies.update()
    for enemy in enemies:
        if enemy.rect.top > 480:
            enemy.kill()

    screen.fill((12, 14, 30))
    enemies.draw(screen)
    lasers.draw(screen)
    screen.blit(player.image, player.rect)
    pygame.display.flip()
    clock.tick(60)

pygame.quit()

Toutes les leçons de Sprites et images

Entraînez-vous par vous-même : Playground Pygame