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.
Thử thách
Trung bìnhHãy để tia laser tiêu diệt kẻ địch.
- Sau các lần cập nhật, kiểm tra
enemiesvớilasersbằngpygame.sprite.groupcollide, đồng thời xóa cả kẻ địch lẫn tia laser. - 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()
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
5Va chạm chính xác đến từng pixel
Hình chữ nhật thật bất côngMặt nạSprite chính xác đến từng pixelVùng va chạm hình tròn3Lớp cho đối tượng trong trò chơi
Lớp đầu tiên của bạnPhương thứcSelf là đối tượngDanh sách đối tượngĐối tượng có hình ảnhDanh sách kẻ địchLớp con6Hoạt ảnh từ sprite sheet
Cắt sprite sheetBộ đếm khung hìnhTạo hoạt ảnh theo thời gianHiệu ứng nổ chỉ chạy một lầnTự luyện tập: Playground Pygame