Âm nhạc cho từng trạng thái
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 6 trên 23.
Mỗi trạng thái trong trò chơi có thể có nhạc riêng: giai điệu êm dịu ở menu, bản nhạc sôi động khi bạn chơi, giai điệu ngắn khi bạn thắng hoặc thua. Để chuyển nhạc, hãy tải bản nhạc mới rồi phát. Tải bản nhạc mới sẽ dừng bản nhạc cũ. Một hàm nhỏ giúp gộp hai dòng này lại:
def play_music(path, loops=-1):
pygame.mixer.music.load(path)
pygame.mixer.music.play(loops)Chuyển nhạc vào thời điểm trạng thái thay đổi, trên dòng thiết lập state:
if player.colliderect(goal):
state = "win"
play_music("assets/music/win.ogg", 0)Dòng đó chỉ chạy một lần, nên bản nhạc cũng chỉ bắt đầu một lần. Đừng chuyển nhạc bên trong if state == "win": ở phần vẽ: đoạn đó chạy ở mỗi khung hình và khởi động lại bản nhạc 60 lần mỗi giây.
Giai điệu thắng và thua ngắn, tự kết thúc nên chúng dùng loops bằng 0. Giai điệu chủ đề và bản nhạc của màn chơi lặp lại với -1.
Thử thách
Trung bìnhPhát nhạc riêng cho từng trạng thái của trò chơi.
- Viết
play_music(path, loops=-1)để tải và phát một bản nhạc; phátassets/music/theme.oggtrước vòng lặp. - Khi trạng thái chuyển thành
"play", phátassets/music/level.ogg. - Khi trạng thái là
"win", phátassets/music/win.oggmột lần (loops 0); khi trạng thái là"lose", phátassets/music/lose.oggmột lần. - Khi nhấn Enter để quay lại
"menu", phát lại theme.ogg.
Nhấn Chơi, nhấn Enter và đến đích màu xanh lá cây: nhạc sẽ thay đổi mỗi lần. 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("Lava Run")
clock = pygame.time.Clock()
font = pygame.font.Font(None, 32)
player = pygame.Rect(40, 160, 30, 30)
goal = pygame.Rect(420, 160, 30, 30)
lava = pygame.Rect(0, 320, 480, 40)
state = "menu"
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_RETURN:
if state == "menu":
state = "play"
player.topleft = (40, 160)
elif state in ("win", "lose"):
state = "menu"
if state == "play":
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
player.x -= 4
if keys[pygame.K_RIGHT]:
player.x += 4
if keys[pygame.K_UP]:
player.y -= 4
if keys[pygame.K_DOWN]:
player.y += 4
player.clamp_ip(screen.get_rect())
if player.colliderect(goal):
state = "win"
elif player.colliderect(lava):
state = "lose"
screen.fill((30, 30, 46))
if state == "menu":
title = font.render("Press Enter to start", True, (240, 240, 240))
screen.blit(title, title.get_rect(center=(240, 180)))
else:
pygame.draw.rect(screen, (230, 90, 40), lava)
pygame.draw.rect(screen, (90, 200, 120), goal)
pygame.draw.rect(screen, (80, 160, 255), player)
if state == "win":
message = font.render("You win!", True, (240, 240, 240))
screen.blit(message, message.get_rect(center=(240, 100)))
elif state == "lose":
message = font.render("Game over", True, (240, 240, 240))
screen.blit(message, message.get_rect(center=(240, 100)))
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
4Rung màn hình và chớp sáng khi trúng đòn
Rung màn hìnhChớp sáng khi trúng đònKhựng hình khi trúng đònGiữ hiệu ứng tinh tếTự luyện tập: Playground Pygame