状態ごとの音楽
CoddyのPygameジャーニー「サウンドとゲームの手応え」セクションの一部。レッスン 6/23。
ゲームの各状態には、それぞれ専用の音楽を設定できます。メニューでは落ち着いたテーマ曲、プレイ中はにぎやかな曲、勝敗が決まったときには短い曲を流します。切り替えるには、新しい曲を読み込んで再生します。新しい曲を読み込むと、古い曲は停止します。2行をまとめておくために、小さな関数を使います。
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":の中に切り替え処理を入れないでください。そこは毎フレーム実行されるため、1秒間に60回曲が最初から再生されてしまいます。
勝利と敗北の曲は短く、自然に終わるため、loopsには0を指定します。テーマ曲とレベルの曲は-1を指定してループ再生します。
チャレンジ
中級Enterキーでゲームが始まります。青い四角形は緑のゴールに到達すると勝ち、溶岩に入ると負けです。各状態に対応する音楽を設定しましょう。
- トラックを読み込んで再生する
play_music(path, loops=-1)を書きましょう。 - ループの前に、
assets/music/theme.oggを再生しましょう。 - 状態が
"play"になる箇所で、assets/music/level.oggを再生しましょう。 - 状態が
"win"になる箇所で、assets/music/win.oggを1回(loops 0)再生しましょう。"lose"の場合は、assets/music/lose.oggを1回再生しましょう。 - Enterキーで
"menu"に戻る箇所で、theme.ogg をもう一度再生しましょう。
自分で試してみよう
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プレイグラウンド