Bắn trúng và ghi điểm
Thuộc phần Sprite và hình ảnh trong hành trình Pygame của Coddy. Bài học 34 trên 39.
Laser va kẻ địch đối đầu theo nhóm với groupcollide. Hình laser là một tia mảnh nằm giữa một hình vuông rộng 48 pixel, nên phép kiểm tra Rect sẽ khiến một laser lệch sang bên 20 pixel vẫn phá hủy được kẻ địch. Hãy kiểm tra hình ảnh bằng mask:
hits = pygame.sprite.groupcollide(enemies, lasers, True, True, pygame.sprite.collide_mask)
for enemy in hits:
score += 10Đối số thứ năm là phép kiểm tra, giống như với spritecollide. Tạo self.mask = pygame.mask.from_surface(self.image) cho cả Laser và Enemy, để mask chỉ được tạo một lần, không phải trong mỗi lần kiểm tra.
Lặp qua hits sẽ duyệt từng kẻ địch bị phá hủy: mỗi kẻ địch được 10 điểm. Hiển thị điểm ở góc trên bên trái bằng font = pygame.font.Font(None, 32), tạo một lần trước vòng lặp.
Thử thách
Trung bìnhCộng 10 điểm cho mỗi kẻ địch bị tia laser bắn trúng.
- Thêm
self.maskchoLaservàEnemy. Đặtscore = 0và tạo phông chữ cỡ 32. - Sau khi cập nhật, kiểm tra va chạm giữa
enemiesvàlasersbằngpygame.sprite.collide_mask, loại bỏ cả hai; cộng 10 điểm cho mỗi kẻ địch bị bắn trúng. - Vẽ
f"Score: {score}"tại(10, 10)với màu(240, 240, 240).
Nhấn Chơi rồi bắn: kẻ địch biến mất và điểm số tăng thêm 10. Sau đó nhấn Kiểm tra.
Tự làm thử
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()
Tất cả bài học trong Sprite và hình ảnh
7Tuần tra giữa các vì sao
Tàu tuần traBắn laser5Va 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