Menu
CoddyTech

Xóa các hạt đã ngừng hoạt động

Thuộc phần Âm thanh và cảm giác chơi trong hành trình Pygame của Coddy. Bài học 11 trên 23.

Hạt đã chết không được vẽ, nhưng vẫn còn trong danh sách. Mỗi khung hình, vòng lặp di chuyển hạt đó và giảm tuổi thọ của nó thêm một lần nữa. Nhấp 100 lần, danh sách sẽ chứa 2000 hạt mà không ai nhìn thấy, và trò chơi ngày càng chậm hơn. Bộ đếm ở phía trên cho thấy điều đó.

Xóa các hạt đã chết một lần mỗi khung hình, sau bước cập nhật. Cách rõ ràng nhất là tạo một danh sách mới gồm các hạt vẫn còn sống:

particles = [p for p in particles if p["life"] > 0]

Câu lệnh này có nghĩa là: danh sách gồm mọi p trong particles có tuổi thọ lớn hơn 0.

Đừng xóa phần tử khỏi danh sách khi vòng lặp for đang duyệt chính danh sách đó:

for p in particles:
    if p["life"] <= 0:
        particles.remove(p)

Khi một phần tử bị xóa, phần tử kế tiếp sẽ chuyển vào vị trí của nó, còn vòng lặp bỏ qua phần tử đó mà không kiểm tra. Ở đây, mọi hạt trong một đợt đều chết trong cùng một khung hình, nên mỗi lần một nửa số hạt vẫn còn lại. Tạo danh sách mới sẽ không bỏ sót phần tử nào.

challenge icon

Thử thách

Trung bình

Xóa các hạt khi chúng bay ra ngoài.

  1. Sau vòng lặp cập nhật, thay particles bằng một danh sách chỉ gồm những hạt có life lớn hơn 0.
  2. Khi một đợt bùng nổ kết thúc, bộ đếm sẽ hiển thị Particles: 0.

Nhấn Chơi rồi nhấp chuột: số lượng tăng lên 20, sau đó giảm về 0. Tiếp theo, nhấn Kiểm tra.

Tự làm thử

import random
import pygame

pygame.init()
screen = pygame.display.set_mode((480, 360))
pygame.display.set_caption("Fireworks")
clock = pygame.time.Clock()
font = pygame.font.Font(None, 28)

particles = []

running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        elif event.type == pygame.MOUSEBUTTONDOWN:
            x, y = event.pos
            for i in range(20):
                particles.append({
                    "x": x,
                    "y": y,
                    "vx": random.uniform(-3, 3),
                    "vy": random.uniform(-3, 3),
                    "life": 30,
                })

    for p in particles:
        p["x"] += p["vx"]
        p["y"] += p["vy"]
        p["life"] -= 1

    screen.fill((20, 20, 36))
    for p in particles:
        if p["life"] > 0:
            pygame.draw.circle(screen, (255, 160, 60), (p["x"], p["y"]), 3)
    label = font.render(f"Particles: {len(particles)}", True, (240, 240, 240))
    screen.blit(label, (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 Âm thanh và cảm giác chơi

Tự luyện tập: Playground Pygame