Skip to content
第22回 敵の物理と巡回状態

3 / 4 壁接触時の方向転換と端数リセット

このステップの目的

水平移動時の壁衝突検知結果(hitWall)を受け取り、進行方向の反転と速度・端数のクリアを行うことで、壁に引っかかることなく反転巡回する仕組みを実装します。

衝突解決の結果を行動トリガーに利用する

敵キャラクターが壁に衝突した際、その場で停止するのではなく進行方向を反転させて巡回を継続させます。

水平移動処理 MoveHorizontal() は、壁に衝突して押し戻しが発生した場合に truehitWall)を返します。この戻り値を利用して反転処理 TurnAround() を呼び出します。

Enemy.cppcpp
const bool hitWall = MoveHorizontal(stage, deltaTime);
MoveVertical(stage, deltaTime);

if (hitWall)
{
    TurnAround();
}

衝突解決の結果を行動判定のトリガーとして利用することで、重複した当たり判定の計算を避けることができます。

方向転換時の端数リセット

進行方向を反転させる処理では、向きフラグ(facingRight_)の反転に加えて、水平速度と移動端数もリセットします。

Enemy.cppcpp
void Enemy::TurnAround()
{
    facingRight_ = !facingRight_;
}

移動端数(remainderX_)をクリアする理由

壁に接触したフレームでは、壁に向かって進もうとした端数(例: +0.7f ピクセル分)が remainderX_ に残っています。この端数を残したまま反転させると、次フレームの計算で古い前進方向のプラス端数と新しい後退方向のマイナス速度が合算され、反転直後の1フレームだけ移動量が不自然に減少します。
反転時に端数をリセットすることで、切り替わったフレームから新しい方向へ一定の速度で移動できます。

向きフラグとスプライト反転の同期

facingRight_ は、移動速度の符号(プラス/マイナス)と、グラフィック描画時の左右反転フラグ(flipX)の両方を決定する共通の基準となります。

Enemy.cppcpp
void Enemy::Draw(const Camera& camera, const ImageManager& images) const
{
    if (!IsActive())
        return;

    images.Draw(ImageId::Enemy, camera.WorldToScreen(GetDrawRect()));
}

デバッグ描画(F1 キー)を有効にして、当たり判定矩形(Hitbox)の端が壁タイルに接触したフレームで向きが反転することを確認します。

チェックリスト
  • 水平移動時の壁衝突判定結果(hitWall)を受け取って反転関数を呼び出せる
  • 反転時に向きフラグだけでなく水平速度と移動端数を0クリアする理由を説明できる
  • 敵の当たり判定矩形が壁に接触した瞬間に、進行方向と描画の向きが同期して反転することを確認できる

ゲームプログラミング実践