衝突応答
ゲーム開発における衝突応答(Collision Response)とは、ゲーム内のオブジェクト同士が衝突(
コリジョン)したことを検知した後に、その物体が「どのように反応するか」を定義する物理演算やスクリプト上の処理のことです。
具体的には、単に「当たった」という事実(衝突検出)を受けて、物体同士がすり抜けないようにしたり、跳ね返ったり、壊れたりする計算を指します。
概要
Playdate のスプライトシステムにおいて、
衝突応答(Collision Responses)は「衝突した瞬間に
スプライトがその後どう動くべきか」を決定する非常に重要な要素です。
moveWithCollisions を呼び出した際、エンジンは内部的に sprite:collisionResponse(other) という関数を呼び出し、その返り値に基づいて移動の最終座標を計算します。
1. 4つのレスポンスタイプ
| 定数 |
挙動の名称 |
詳細 |
| kCollisionTypeFreeze |
フリーズ (Block) |
衝突した瞬間にその場で停止します。移動ベクトルがそこで遮断されます |
| kCollisionTypeSlide |
スライド |
障害物に沿って滑るように移動します。斜めの壁に当たっても止まらずに進めるため、最も多用されます |
| kCollisionTypeBounce |
バウンス |
障害物の面に対して反射(跳ね返り)します。入射角と反射角を計算した動きになります |
| kCollisionTypeOverlap |
オーバーラップ (Overlap) |
物理的な衝突(制止)は行わず、そのまま通り抜けます。ただし、衝突イベント自体は発生します |
2. 実装方法:collisionResponse のオーバーライド
各スプライトに対して、どのような応答を返すかを定義します。これにより、「壁にはスライドするが、溶岩に触れたら止まる」といった個別のロジックを組むことができます。
function MySprite:collisionResponse(other)
-- other は衝突相手のスプライト
if other:getTag() == TAG_WALL then
return gfx.sprite.kCollisionTypeSlide
elseif other:getTag() == TAG_BUMPER then
return gfx.sprite.kCollisionTypeBounce
elseif other:getTag() == TAG_COIN then
return gfx.sprite.kCollisionTypeOverlap
else
return gfx.sprite.kCollisionTypeFreeze
end
end
3. 各レスポンスのユースケース
- kCollisionTypeSlide (スライド)
- 用途: トップダウンやサイドビューのプレイヤー移動
- メリット: プレイヤーが壁に対して斜めに移動入力をした際、ガクガク止まらずにスムーズに壁沿いを歩けます
- kCollisionTypeFreeze (フリーズ)
- 用途: 弾丸が壁に当たって消滅する場合、あるいは重い物体が何かにぶつかって即座に止まる場合
- メリット: 計算が最もシンプルで、意図しないめり込みを防ぎやすいです
- kCollisionTypeBounce (バウンス)
- 用途: ブロック崩しのボール、ピンボールのギミック、あるいは「跳ね返る弾」など
- メリット: 反射ベクトルを自分で計算する必要がなく、SDK側で正確に反射後の位置を戻してくれます
- kCollisionTypeOverlap (オーバーラップ)
- 用途: アイテムの取得、ゴール地点の判定、ダメージエリア(毒沼など)
- メリット: 「当たった」という情報(どのスプライトと、どの位置で、どの面で当たったか)を取得しつつ、移動自体には干渉したくない場合に最適です
4. 衝突情報の取得
moveWithCollisions を実行すると、これらのレスポンスを反映した結果として、以下の情報が含まれる collisions リストが返されます。
- over: 衝突した相手のスプライト
- type: 実行されたレスポンスタイプ
- normal: 衝突面の法線ベクトル。どっちの方向から当たったか(上下左右)の判定に使えます
- touch: 実際に接触した座標。
- TIP
- デバッグのコツとしては、意図しない挙動(壁を突き抜ける、ガタつくなど)が発生した場合は、collisionResponse が正しく意図した定数を返しているか、まず確認してみてると良いです。
関連ページ
最終更新:2026年04月30日 22:48