Skip to content

第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);

動作確認

  1. 音声素材なしで実行してもゲームが止まらないことを確認する
  2. Assets/Sounds/Shot.wavを置き、ショット時に音が鳴ることを確認する
  3. 敵を倒した位置にエフェクトが出ることを確認する
  4. エフェクトが一定時間後に消えることを確認する
  5. 命中、ダメージ、クリア、ゲームオーバーの音を追加する

よくある問題

  • 音が鳴らない場合は、作業ディレクトリからAssets/Soundsが見えるか確認する
  • 同じ音が鳴り続ける場合は、状態が切り替わった瞬間だけ再生しているか確認する
  • エフェクトが残り続ける場合は、timerを減らしているか確認する

今回の完成条件

  • SoundManagerで効果音を管理できる
  • 必要なタイミングで効果音を鳴らせる
  • 敵撃破時のエフェクトを固定配列で管理できる
  • 音とエフェクトが操作結果を伝える役割を説明できる

まとめ

今回は、音とエフェクトでゲームの反応を強化しました。
次回は、完成が近づいたコードを、所有、参照、寿命の観点で点検します。