Skip to content

第09回 音声の管理と再生 ​

第08回では、画像リソースの所有権とRAIIパターンを学びました。
第09回では同じ管理方法を使い、BGMと効果音の再生を実装します。

音声の所有と解放をまとめて行うSoundManagerを作ります。画面遷移や射撃・命中・被弾に合わせて音を再生する設計も学びます。

始める前に ​

読み込んだ資源をManagerで管理し、必要な場所から呼ぶ流れを確認してください。確認したい場合は、画像リソースの管理を参照してください。

前の回の受講や完成物は必須ではありません。下の開始用プロジェクトを使い、配布済みの処理と今回追加する処理を確認してから進めます。

配布プロジェクト ​

第09回のプロジェクトを展開し、ShootingGame2D.slnをVisual Studio 2026で開いてください。
第08回で実装した画像リソース管理(ImageManager)が含まれたプロジェクトから開始します。

配布ファイル一覧
ファイル役割
Source/Shooting/Game.cpp状態遷移や戦闘イベントへのサウンド再生の接続
Assets/Sounds/TitleBgm.wavタイトル画面用BGM素材
Assets/Sounds/Shot.wav射撃時の効果音素材

この回のゴール ​

画面遷移に合わせてBGMが切り替わり、弾の発射や敵への命中、被弾の瞬間に効果音が正しく再生される状態を作ります。

  • 第08回で学んだ対応表とRAIIパターンを応用し、SoundManagerで音声を一括所有・自動解放できる
  • ChangeState()と連動させて、タイトルとプレイ中のBGMを二重に重なることなく切り替えられる
  • キー入力の瞬間ではなく、「出来事が成立した瞬間」に効果音(SE)を鳴らす設計の重要性を説明できる
  • 各オブジェクトに音声再生処理を散乱させず、調停役であるGameクラスから整理して呼び出せる

今回のポイント ​

画像管理で学んだパターンの反復適用 ​

画像と音声はデータ形式こそ異なりますが、プログラム上の管理構造は共通しています。

音声はSoundManager::Idで指定し、ファイルパスをSoundTableで管理します。
起動時にLoadAll()でまとめて読み込み、デストラクタからDeleteSoundMem()で解放します。
コピーは= deleteで禁止し、二重解放を防ぎます。

画像と同じ管理方法を音声にも使うと、設計をそろえ、安全に実装できます。

「入力」ではなく「出来事の成立」で鳴らす ​

射撃キーを押したときに音を鳴らすと、弾数が上限に達していても音だけが出てしまいます。これではプレイヤーに誤った情報を伝えます。
弾の生成やダメージが成立した結果に効果音を結びつけることが、自然な操作感を作るうえで重要です。

イベント成立と効果音再生の連携
Player::TryShoot()
生成成功時に射撃SE
SoundManager
Enemy::TakeDamage()
命中成立時に命中SE
SoundManager
Player::TryTakeDamage()
被弾成立時に被弾SE
SoundManager
Game::ChangeState()
クリア遷移時にクリアSE
SoundManager

作業の準備 ​

開始用ZIPには前回までの到達状態が含まれています。今回の新規ファイルは、本文を進めながら追加します。ファイルの登録方法や変更の引き継ぎ手順は、配布ファイルの手順で確認できます。

作業対象
新規作成Source/Shooting/SoundManager.cpp、Source/Shooting/SoundManager.h
既存ファイルへ追記・編集Source/Shooting/Game.cpp、Source/Shooting/Game.h、Source/Shooting/Tuning/GameTuning.h
重点的に実装・確認する処理SoundManager::PlayBgm、SoundManager::PlaySe、Game::ChangeState

ヘッダーの宣言、#include、登録テーブル、エラー処理などは、最終ステップの参考実装を参照できます。重点関数は各ステップで処理の流れを確認しながら記述します。関数を変更する際は、宣言・定義・呼び出し元の整合性を保ちます。

GameTuning.hには今回必要な定数を追記し、自身で調整した既存の値を維持します。

第09回の目次 ​