コリジョン
ゲームにおけるコリジョン(Collision)は、オブジェクト(キャラクターや背景など)同士の衝突や接触を検知する「当たり判定」の領域、またはその仕組みです。
ボックスや球体などの単純な形状を物体に設定し、それらが重なることで、攻撃の命中、壁のすり抜け防止、着地判定などを行う、ゲーム制作に不可欠な機能です。
概要
Playdateの開発において、コリジョン (衝突判定)は playdate.graphics.sprite モジュールに統合されており、非常に高速で使いやすい仕組みが提供されています。
Playdateのコリジョンは基本的に
AABB (Axis-Aligned Bounding Boxes:回転しない矩形) をベースにしています。
1. コリジョンの基本設定
スプライトに衝突判定を持たせるには、まず「衝突範囲(Collide Rect)」を設定する必要があります。
local player = playdate.graphics.sprite.new(image)
-- スプライトの画像サイズと同じサイズの衝突範囲を設定
player:setCollideRect(0, 0, player:getSize())
player:add()
2. 移動と衝突の実行
Playdateで最も重要な関数が moveWithCollisions(x, y) です。これを使うと、「指定した座標に移動しようとした際、途中で何かにぶつかったか」を自動で計算してくれます。
function player:update()
-- (200, 120) に移動を試みる
local actualX, actualY, collisions, length = self:moveWithCollisions(200, 120)
-- collisions には衝突した相手や場所の情報が入っている
if length > 0 then
print("衝突しました! 相手の数: " .. length)
end
end
- actualX, actualY
- 衝突を考慮した結果、最終的に到達した座標。
- collisions
- 衝突情報のリスト(後述)。
- length
- 衝突したオブジェクトの数。
3. 衝突レスポンス (Collision Response)
壁にぶつかった時、「止まる」のか「滑る」のかを決定するのが collisionResponse です。スプライトごとにこの関数を定義して挙動を指定します。
| 定数 |
挙動 |
主な用途 |
| kCollisionTypeSlide |
壁に沿って滑る |
最も一般的。プレイヤーの移動など |
| kCollisionTypeFreeze |
ぶつかった瞬間に止まる |
弾が壁に当たって止まる時など |
| kCollisionTypeOverlap |
通り抜けるが、判定は検知する |
アイテムの回収、トリガーゾーン |
| kCollisionTypeBounce |
跳ね返る |
ボールや反射する弾など |
function player:collisionResponse(other)
if other:isa(Wall) then
return "slide" -- 壁なら滑る
elseif other:isa(Enemy) then
return "overlap" -- 敵なら重なる(ダメージ判定用)
end
end
4. 衝突情報の取得
moveWithCollisions が返す collisions リストの各要素には、以下の詳細が含まれています。
- sprite
- 自分自身のスプライト。
- other
- 衝突した相手のスプライト。
- type
- レスポンスの種類(slide, bounceなど)。
- normal
- 衝突面の法線ベクトル(どちらの方向からぶつかったか)。
- touch
- 衝突した瞬間の座標。
5. グループによるフィルタリング
すべてのオブジェクト同士が判定を行うと重くなるため、グループ分けをして効率化します。
-- グループの設定
player:setGroups(1) -- プレイヤーはグループ1
player:setCollidesWithGroups({2}) -- プレイヤーはグループ2(敵や壁)とだけ衝突する
-- 壁の設定
wall:setGroups(2)
Playdateでは
タイルマップ(playdate.graphics.tilemap)に対してもコリジョンを設定できます。
- tilemap:setWallSprites(tileIndices) で、壁として扱うタイルのインデックスを指定します。
- これにより、タイルマップ上の指定タイルが自動的に衝突可能なスプライトとして扱われるようになります。
コリジョンが意図通りに動かない場合は、前述の
デバッグ描画が役立ちます。
-- main.lua の update 内などで
playdate.graphics.sprite.addDirtyRect(0, 0, 400, 240) -- 全画面更新(デバッグ用)
-- スプライトの衝突範囲を可視化
function playdate.debugDraw()
playdate.graphics.sprite.performOnAllSprites(function(s)
s:drawDebug()
end)
end
- パフォーマンスの注意点
- 非常に多く(数百個以上)のスプライトが常に moveWithCollisions を呼び出すと、CPU負荷が高まります。
- 動かない背景オブジェクトは setGroups を適切に設定し、不要な判定をスキップするように設計するのがコツです。
関連ページ
最終更新:2026年05月01日 22:43