为每种状态播放音乐
本课属于 Coddy Pygame 学习旅程的“音效与游戏体验”单元。第 6 课,共 23 课。
游戏的每种状态都可以有自己的音乐:菜单播放舒缓的主题曲,游戏过程中播放节奏紧凑的曲子,获胜或失败时播放一段短曲。要切换音乐,加载新曲目并播放即可。加载新曲目会停止旧曲目。可以用一个小函数把这两行代码放在一起:
def play_music(path, loops=-1):
pygame.mixer.music.load(path)
pygame.mixer.music.play(loops)在状态发生变化时切换音乐,也就是在设置 state 的那一行:
if player.colliderect(goal):
state = "win"
play_music("assets/music/win.ogg", 0)这行代码只会运行一次,因此曲目也只会播放一次。不要在绘制部分的 if state == "win": 中切换音乐:这段代码每一帧都会运行,因此会每秒重新播放曲目 60 次。
获胜和失败的曲子都很短,会自行结束,因此将 loops 设为 0。主题曲和关卡曲目则用 -1 循环播放。
挑战
中等为游戏的每种状态播放专属音乐。
- 编写
play_music(path, loops=-1)来加载并播放曲目;在循环开始前播放assets/music/theme.ogg。 - 状态变为
"play"时,播放assets/music/level.ogg。 - 状态变为
"win"时,播放一次assets/music/win.ogg(loops 为 0);状态变为"lose"时,播放一次assets/music/lose.ogg。 - 按 Enter 返回
"menu"时,再次播放 theme.ogg。
点击“运行”,按 Enter 并到达绿色目标:每次状态变化时,音乐都会切换。然后点击“检查”。
亲手试试
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()
音效与游戏体验中的所有课
自己练习: Pygame 在线编辑器