Appearance
第10回 音と演出
前回: 第09回 ゲーム状態 / 次回: 第11回 参照・ポインタ・寿命
今回の授業内容
- DXライブラリで効果音を読み込んで再生する
SoundManagerで音声ハンドルを管理する- ショット、命中、ダメージ、結果表示に音を付ける
- 敵撃破エフェクトを固定配列で管理する
- 音と演出の有無で操作感が変わることを確認する
今回の開始状態
第09回終了時点では、タイトル、プレイ中、結果画面があります。
今回の終了時点では、ショットや命中時に音が鳴り、敵撃破位置に短いエフェクトが出るようにします。
変更するファイル
| ファイル | 変更内容 |
|---|---|
SoundManager.h / SoundManager.cpp | 効果音の読み込み、再生、解放を追加する |
Effect.h / Effect.cpp | 撃破エフェクトを追加する |
Game.h / Game.cpp | 音管理とエフェクト配列を所有し、イベント時に呼ぶ |
Assets/Sounds | 任意で効果音素材を配置する |
SoundManagerを追加する
効果音の種類を列挙型で定義します。
cpp
enum class SoundId
{
Shot,
Hit,
Damage,
Clear,
GameOver,
Count
};再生時は、読み込みに成功したハンドルだけを使います。
DXライブラリの音声ハンドルは、読み込み失敗時に-1になります。
cpp
void SoundManager::Play(SoundId id) const
{
const int handle = handles[ToIndex(id)];
if (handle != -1)
PlaySoundMem(handle, DX_PLAYTYPE_BACK);
}この確認は、素材がない状態でも授業を進めるために必要な確認です。
音を鳴らす場所を決める
音は、処理結果が確定した場所で鳴らします。
たとえばショット音は、実際に弾を生成できたときに鳴らします。
cpp
if ((input.IsDown(KEY_INPUT_Z) || input.IsDown(KEY_INPUT_SPACE)) && player.CanShoot())
{
SpawnBullet();
player.OnShoot();
sounds.Play(SoundId::Shot);
}命中音は、弾と敵の衝突が成立し、スコアを増やす場所で鳴らします。
ゲームクリア音とゲームオーバー音は、状態が切り替わった瞬間に鳴らします。
Effectを追加する
エフェクトも、弾や敵と同じように固定配列と有効フラグで管理します。
cpp
class Effect
{
public:
void Spawn(float startX, float startY);
void Update();
void Draw() const;
bool IsActive() const;
private:
Vec2 position = {};
int timer = 0;
bool active = false;
};寿命が切れたら無効化します。
cpp
void Effect::Update()
{
if (!active) return;
--timer;
if (timer <= 0)
active = false;
}敵を倒した瞬間に、その敵の中心へエフェクトを出します。
cpp
const Rect rect = enemy.GetRect();
SpawnEffect(rect.x + rect.width * 0.5f, rect.y + rect.height * 0.5f);動作確認
- 音声素材なしで実行してもゲームが止まらないことを確認する
Assets/Sounds/Shot.wavを置き、ショット時に音が鳴ることを確認する- 敵を倒した位置にエフェクトが出ることを確認する
- エフェクトが一定時間後に消えることを確認する
- 命中、ダメージ、クリア、ゲームオーバーの音を追加する
よくある問題
- 音が鳴らない場合は、作業ディレクトリから
Assets/Soundsが見えるか確認する - 同じ音が鳴り続ける場合は、状態が切り替わった瞬間だけ再生しているか確認する
- エフェクトが残り続ける場合は、
timerを減らしているか確認する
今回の完成条件
SoundManagerで効果音を管理できる- 必要なタイミングで効果音を鳴らせる
- 敵撃破時のエフェクトを固定配列で管理できる
- 音とエフェクトが操作結果を伝える役割を説明できる
まとめ
今回は、音とエフェクトでゲームの反応を強化しました。
次回は、完成が近づいたコードを、所有、参照、寿命の観点で点検します。