Skip to content
第10回 エフェクトと演出

2 / 4 エフェクトの時間更新と描画計算 ​

このステップの目的

エフェクトの経過時間から半径の拡大率と透明度を計算し、寿命を迎えたら自動的に停止させる処理を実装します。

経過時間の加算と寿命判定 ​

EffectManager::Update()では、有効なすべてのエフェクトに対して経過時間deltaTimeを加算します。
経過時間ageが設定された継続時間(tuning::effect::Duration)に達したエフェクトは、isActive = falseに戻して停止状態にします。

EffectManager.cppcpp
void EffectManager::Update(float deltaTime)
{
    for (Effect& effect : effects)
    {
        if (!effect.isActive)
            continue;

        effect.age += deltaTime;
        if (effect.age >= tuning::effect::Duration)
            effect.isActive = false;
    }
}

進行度(progress)に基づく半径と透明度の計算 ​

発生から終了までの進行度をprogressで表すと、エフェクトの動きを滑らかに計算できます。

progress=ageDuration(0.0≤progress≤1.0)

このprogressを用いて、エフェクトの描画処理Draw()を実装します。

EffectManager.cppcpp
void EffectManager::Draw() const
{
    for (const Effect& effect : effects)
    {
        if (!effect.isActive)
            continue;

        // progressは開始時の0から終了時の1まで変化する
        float progress = effect.age / tuning::effect::Duration;
        float radiusRange = tuning::effect::EndRadius - tuning::effect::StartRadius;
        float radius = tuning::effect::StartRadius + radiusRange * progress;

        // 円を広げながら透明にして短い爆発を表現する
        int alpha = static_cast<int>(255.0f * (1.0f - progress));

        SetDrawBlendMode(DX_BLENDMODE_ALPHA, alpha);

        DrawCircle(
            static_cast<int>(effect.center.x),
            static_cast<int>(effect.center.y),
            static_cast<int>(radius),
            GetColor(255, 220, 80),
            FALSE);

    }

    SetDrawBlendMode(DX_BLENDMODE_NOBLEND, 0);
}

線形補間(Lerp)とフェードアウトの仕組み ​

  1. 半径の拡大
    時間とともに、半径をStartRadiusからEndRadiusへ広げます。たとえば4ピクセルから24ピクセルへ変化します。
  2. アルファ値の減少
    アルファ値は255 * (1.0 - progress)で求めます。発生直後の255から徐々に下がり、終了時は0になります。円がはっきり見える状態から、完全に見えなくなるまで変化します。

描画後はSetDrawBlendMode(DX_BLENDMODE_NOBLEND, 0)で通常のブレンドモードへ戻してください。戻さないと、後に描くプレイヤーやUIまで意図せず半透明になります。

チェックリスト
  • 経過時間ageがDurationに達したエフェクトが正しく非アクティブ化されている
  • 進行度progress(0.0〜1.0)を用いて半径とアルファ値が滑らかに計算されている
  • DX_BLENDMODE_ALPHAを用いて半透明の円が描画されている
  • 描画終了後にブレンドモードを通常描画(DX_BLENDMODE_NOBLEND)に戻している