Menu
CoddyTech

Âm thanh và các phím được giữ

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 4 trên 23.

Giữ phím Space, tàu sẽ bắn laser sau mỗi 12 khung hình. Đoạn code khởi đầu phát âm thanh laser như sau:

if keys[pygame.K_SPACE]:
    laser_sound.play()
    if cooldown == 0:
        lasers.append(...)

keys[pygame.K_SPACE] có giá trị true ở mỗi khung hình khi bạn nhấn giữ phím. Vì vậy, khi bạn giữ phím Space, âm thanh bắt đầu phát 60 lần mỗi giây, dù chỉ có 5 tia laser bay ra. Bạn nghe thấy tiếng ù khó chịu thay vì tiếng bắn.

Cách sửa cũng theo quy tắc như trước: phát âm thanh tại nơi hành động xảy ra. Một phát bắn xảy ra bên trong if cooldown == 0:, vậy nên âm thanh được phát ở đó:

if keys[pygame.K_SPACE]:
    if cooldown == 0:
        lasers.append(...)
        laser_sound.play()

Giờ đây, mỗi tia laser đều có âm thanh riêng và không có âm thanh nào khác phát ra. Với hành động chỉ xảy ra một lần mỗi lần nhấn, chẳng hạn như nhảy, hãy phát âm thanh trong sự kiện KEYDOWN: mỗi lần nhấn chỉ có một sự kiện, dù bạn giữ phím lâu đến đâu.

challenge icon

Thử thách

Dễ

Phát âm thanh laser một lần cho mỗi tia laser thay vì phát liên tục.

  1. Tìm laser_sound.play().
  2. Chuyển nó vào nhánh if cooldown == 0:, sau khi thêm tia laser.

Nhấn Chơi và giữ phím Space: bạn nghe một phát bắn cho mỗi tia laser. Sau đó, nhấn Kiểm tra.

Tự làm thử

import pygame

pygame.init()
screen = pygame.display.set_mode((480, 360))
pygame.display.set_caption("Lasers")
clock = pygame.time.Clock()

laser_sound = pygame.mixer.Sound("assets/sounds/laser.ogg")
laser_sound.set_volume(0.5)

ship = pygame.Rect(220, 300, 40, 30)
lasers = []
cooldown = 0

running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

    keys = pygame.key.get_pressed()
    if keys[pygame.K_LEFT]:
        ship.x -= 5
    if keys[pygame.K_RIGHT]:
        ship.x += 5
    ship.clamp_ip(screen.get_rect())

    if cooldown > 0:
        cooldown -= 1
    if keys[pygame.K_SPACE]:
        laser_sound.play()
        if cooldown == 0:
            lasers.append(pygame.Rect(ship.centerx - 2, ship.top - 12, 4, 12))
            cooldown = 12

    for laser in lasers:
        laser.y -= 8
    lasers = [laser for laser in lasers if laser.bottom > 0]

    screen.fill((30, 30, 46))
    for laser in lasers:
        pygame.draw.rect(screen, (255, 230, 90), laser)
    pygame.draw.rect(screen, (80, 200, 230), ship)
    pygame.display.flip()
    clock.tick(60)

pygame.quit()

Tất cả bài học trong Âm thanh và cảm giác chơi

Tự luyện tập: Playground Pygame