Menu
CoddyTech

Tiga Nyawa

Termasuk bagian Sprite dan Gambar dalam perjalanan Pygame di Coddy. Pelajaran 35 dari 36.

Sekarang permainan bisa berakhir dengan kekalahan. Pesawat memiliki tiga nyawa. Nyawa berkurang satu saat musuh melewati bagian bawah layar, dan satu lagi saat musuh menabrak pesawat:

crashes = pygame.sprite.spritecollide(player, enemies, True, pygame.sprite.collide_mask)
for enemy in crashes:
    lives -= 1
    explosions.add(Explosion(enemy.rect.center))

Pesawat juga memerlukan self.mask. Dalam perulangan yang menghapus musuh yang melewati bagian bawah layar, kurangi satu nyawa juga.

Saat lives mencapai 0, permainan berhenti: letakkan seluruh bagian pembaruan, dari player.update() hingga pemeriksaan tabrakan, di bawah if lives > 0:, lalu tampilkan Game over di tengah. Biarkan explosions.update() di luarnya agar ledakan terakhir tetap berlangsung.

Dua musuh bisa menghabiskan dua nyawa terakhir pada frame yang sama, sehingga lives menjadi -1. Tampilkan max(lives, 0), angka yang lebih besar dari kedua nilai tersebut, agar penghitung tidak pernah menunjukkan angka di bawah 0.

challenge icon

Tantangan

Sedang
  1. Buat lives = 3 dan berikan Player sebuah self.mask.
  2. Musuh yang melewati bagian bawah mengurangi satu nyawa. Musuh yang menyentuh pesawat, diuji dengan collide_mask, akan dihabisi, mengurangi satu nyawa, dan meledak.
  3. Letakkan bagian pembaruan di bawah if lives > 0:.
  4. Gambar Lives: dan max(lives, 0) dengan sudut kanan atasnya di (630, 10), dan Game over di tengah (320, 240) saat lives <= 0.

Coba sendiri

import random
import pygame

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

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()
explosion_frames = []
for number in range(1, 5):
    explosion_frames.append(pygame.image.load(f"assets/images/explosion_{number}.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))
        self.mask = pygame.mask.from_surface(self.image)

    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.mask = pygame.mask.from_surface(self.image)
        self.speed = speed

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


class Explosion(pygame.sprite.Sprite):
    def __init__(self, center):
        super().__init__()
        self.index = 0
        self.timer = 0
        self.image = explosion_frames[0]
        self.rect = self.image.get_rect(center=center)

    def update(self):
        self.timer += 1
        if self.timer == 5:
            self.timer = 0
            self.index += 1
            if self.index == len(explosion_frames):
                self.kill()
            else:
                self.image = explosion_frames[self.index]


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()
explosions = pygame.sprite.Group()
last_shot = 0
score = 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()
    hits = pygame.sprite.groupcollide(enemies, lasers, True, True, pygame.sprite.collide_mask)
    for enemy in hits:
        score += 10
        explosions.add(Explosion(enemy.rect.center))
    explosions.update()

    screen.fill((12, 14, 30))
    enemies.draw(screen)
    lasers.draw(screen)
    screen.blit(player.image, player.rect)
    explosions.draw(screen)
    score_text = font.render(f"Score: {score}", True, (240, 240, 240))
    screen.blit(score_text, (10, 10))
    pygame.display.flip()
    clock.tick(60)

pygame.quit()

Semua pelajaran di Sprite dan Gambar

Latihan sendiri: Playground Pygame