Menu
CoddyTech

Nhóm đối đầu với nhóm

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

Laser nên tiêu diệt kẻ địch. Đây là tương tác giữa một nhóm với một nhóm: bất kỳ laser nào cũng có thể va chạm với bất kỳ kẻ địch nào. groupcollide kiểm tra mọi cặp cùng lúc:

hits = pygame.sprite.groupcollide(enemies, lasers, True, True)
score += len(hits)

Hai giá trị True là các cờ dokill, mỗi nhóm có một cờ: cờ đầu tiên tiêu diệt những kẻ địch bị trúng, cờ thứ hai tiêu diệt những laser bắn trúng chúng. Một laser tiếp tục bay sau khi va chạm có thể hạ gục kẻ địch thứ hai ở phía trên kẻ địch đầu tiên.

hits là một từ điển (dictionary): mỗi kẻ địch bị trúng là một khóa, còn giá trị tương ứng là danh sách laser bắn trúng nó. len(hits) là số kẻ địch bị trúng trong khung hình này, ngay cả khi hai laser cùng bắn trúng một kẻ địch.

Thứ tự các nhóm quyết định khóa là gì. Với groupcollide(lasers, enemies, True, True), khóa sẽ là laser và len(hits) sẽ đếm số laser.

challenge icon

Thử thách

Trung bình

Hãy để tia laser tiêu diệt kẻ địch.

  1. Sau các lần cập nhật, kiểm tra enemies với lasers bằng pygame.sprite.groupcollide, đồng thời xóa cả kẻ địch lẫn tia laser.
  2. Cộng số kẻ địch bị bắn trúng vào score.

Nhấn Chơi rồi bắn một kẻ địch: nó biến mất và điểm số tăng lên. 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("Laser Hits")
clock = pygame.time.Clock()

ship_image = pygame.image.load("assets/images/ship.png").convert_alpha()
enemy_image = pygame.image.load("assets/images/enemy_red.png").convert_alpha()
laser_image = pygame.image.load("assets/images/laser.png").convert_alpha()
font = pygame.font.Font(None, 32)


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 Enemy(pygame.sprite.Sprite):
    def __init__(self, x, y):
        super().__init__()
        self.image = enemy_image
        self.rect = self.image.get_rect(center=(x, y))

    def update(self):
        self.rect.y += 1
        if self.rect.top > 480:
            self.rect.bottom = 0


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()
enemies = pygame.sprite.Group()
for i in range(5):
    enemies.add(Enemy(64 + i * 128, 60))
score = 0

running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        elif event.type == pygame.KEYDOWN and event.key == pygame.K_SPACE:
            lasers.add(Laser(player.rect.centerx, player.rect.top))

    player.update()
    lasers.update()
    enemies.update()

    screen.fill((20, 22, 40))
    enemies.draw(screen)
    lasers.draw(screen)
    screen.blit(player.image, player.rect)
    text = font.render(f"Score: {score}", True, (240, 240, 240))
    screen.blit(text, (10, 10))
    pygame.display.flip()
    clock.tick(60)

pygame.quit()
quiz iconTự kiểm tra

Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.

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

Tự luyện tập: Playground Pygame