Menu
CoddyTech

Kẻ địch xuất hiện

Thuộc phần Sprite và hình ảnh trong hành trình Pygame của Coddy. Bài học 33 trên 39.

Tiếp theo là kẻ địch. Một đối tượng Enemy nhận hình ảnh và tốc độ khi được tạo, vì vậy một lớp có thể vẽ mọi loại kẻ địch:

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

Một đợt gồm nhiều kẻ địch xếp hàng phía trên cửa sổ để chúng lần lượt xuất hiện, mỗi kẻ cách kẻ trước 120 pixel, ở vị trí x ngẫu nhiên:

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

Kẻ đầu tiên có tâm ở y = -40, kẻ tiếp theo ở -160, và cứ tiếp tục như vậy: lúc đầu tất cả đều nằm ngoài tầm nhìn. Một hàm giữ cả đợt ở cùng một chỗ; bài học trước gọi hàm này cho mỗi đợt.

Kẻ địch rơi qua đáy màn hình thì phải bị loại bỏ. Trong vòng lặp chính, sau enemies.update(), hãy loại bỏ mọi kẻ địch có cạnh trên vượt quá 480. Sau này, việc đó sẽ khiến bạn mất một mạng.

challenge icon

Thử thách

Trung bình

Gửi xuống một đợt kẻ địch màu đỏ.

  1. Thêm import random, tải enemy_red.png vào red_image, rồi viết Enemy và spawn_wave.
  2. Tạo enemies = pygame.sprite.Group(), rồi gọi spawn_wave(red_image, 6, 2).
  3. Mỗi khung hình, cập nhật kẻ địch, loại bỏ những kẻ có rect.top vượt quá 480, rồi vẽ chúng trước các tia laser.

Nhấn Chơi: kẻ địch màu đỏ bay xuống. Sau đó nhấn Kiểm tra.

Tự làm thử

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


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


player = Player()
lasers = pygame.sprite.Group()
last_shot = 0

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

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

pygame.quit()

Tất cả bài học trong Sprite và hình ảnh

Tự luyện tập: Playground Pygame