Skip to content

第19回 地形との衝突解決

第18回では、重力と床タイルへの着地処理を実装しました。
第19回では、壁・天井・床との衝突判定と位置補正(コリジョン・リゾリューション)を実装します。

プレイヤーの移動と地形衝突を「横方向(X軸)」と「縦方向(Y軸)」に分離して順番に処理する「軸分離アプローチ」を採用します。これにより、斜め移動時の角への引っ掛かりや不自然な押し戻しを防ぎ、安定した衝突解決を実現します。

配布プロジェクト

第19回の開始用プロジェクトを展開し、PlatformerGame2D.sln を Visual Studio 2026 で開いてください。
床への着地まで実装されたプロジェクトから開始します。

配布ファイル一覧
ファイル役割
Source/Platformer/Stage.h / Stage.cppResolveHorizontal()(壁補正)と ResolveVertical()(床・天井補正)
Source/Platformer/Player.cpp横移動と縦移動を段階的に実行し、衝突結果に応じて速度と端数を停止
Source/Platformer/Tuning/GameTuning.h衝突判定の基準となるタイルサイズ(TileSize

この回のゴール

プレイヤーが床の上を走り、左右の壁に遮られて通り抜けず、ジャンプしてブロックの下側に接触すると天井で遮られて落下へ転じる挙動を実装します。

  • 単なる「重なり判定(検知)」と「位置補正(押し戻し)」の違いを説明できる
  • 「横移動 → 横補正」の後に「縦移動 → 縦補正」を行う軸分離処理の利点を理解する
  • 壁衝突時にX速度とX端数を止め、天井衝突時にY速度を0にして落下へ転じさせることができる
  • 1フレームあたりの移動量をタイルサイズ未満に保つことで、すり抜けを防ぐ仕組みを説明できる

今回のポイント

軸分離アプローチによる衝突解決

斜めに移動した結果ブロックの角にめり込んだ場合、X軸とY軸を同時に補正しようとすると、押し戻す方向の判定が複雑になり、不自然な方向へ押し出される原因になります。

そのため、移動と衝突解決を2段階に分けて順番に実行します。

軸分離による2段階の移動と衝突解決
横方向移動
壁があればX座標を押し戻し、X速度と端数を0にする
横衝突解決
横衝突解決
補正完了後のX座標を基準にY軸方向へ移動する
縦方向移動
縦方向移動
床や天井があればY座標を押し戻し、Y速度を0にする
縦衝突解決

このようにX軸とY軸を段階的に処理することで、角での不自然な引っ掛かりを防ぎ、安定した操作感を実現します。

作業の準備

開始用ZIPは前回までの到達状態です。今回の新規ファイルはありません。ファイルの登録方法と自分の変更の引き継ぎは、配布ファイルの手順で確認できます。

作業対象
新規作成なし
既存ファイルへ追記・編集Source/Platformer/Game.cppSource/Platformer/Player.cppSource/Platformer/Player.hSource/Platformer/Stage.cppSource/Platformer/Stage.h
重点的に実装・確認する処理Player::MoveHorizontal()Stage::ResolveHorizontal()Stage::ResolveVertical()

ヘッダーの宣言、include、登録表、読み込みのエラー処理は、最終ステップの参考実装を必要に応じて利用します。重点関数は各ステップで処理の理由を確かめながら記述します。関数を変更するときは、宣言・定義・呼び出し元の整合性を保ちます。

必要に応じて調整値を設定しながら進めます。

第19回の目次

動作確認

  • 左右の壁でX位置とX速度が補正されること
  • 床と天井でY位置とY速度が補正されること
  • 着地したフレームのみ接地イベントが生成されること
  • 高速移動時における方式上の制約(トンネリング)を説明できること

次回は、移動状態をスプライトアニメーションへ反映し、ジャンプと着地に効果音を接続します。

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