第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を用いて、エフェクトの描画処理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)とフェードアウトの仕組み
- 半径の拡大
時間とともに、半径をStartRadiusからEndRadiusへ広げます。たとえば4ピクセルから24ピクセルへ変化します。 - アルファ値の減少
アルファ値は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)に戻している