とんんでもないスピードでぶっ飛びたい

アクションゲームだけでなく、チップ単位の壁の当たり判定があるゲームを作る場合、必ず考えなければならないことがあります。
それは、壁のすり抜け対策。
アクションゲームを作っていて、これの対策を後回しにしている人間は、僕ぐらいなんじゃないかと。
ひどい怠慢です。


なぜ壁のすり抜けが発生するかというと、この当たり判定があるチップのサイズが25×25だとします。
ゲーム上の、ある物質がx軸方向、y軸方向のどちらでもいいですが、
25より速いスピードで動いている場合、チップを飛び越えてすり抜けてしまう現象が起こります。


この対策として、非常に簡単な方法が2つ。

  1. チップサイズを大きくする。
  2. 物体の最大スピードをチップサイズ以下にする。

僕は2を使っています。
いつか直そうとは思っているのですが。
1は、ステージの当たり判定を細かく設定し辛くなります。
2は、超スピードが出せなくなります。
どちらも何らかの制限がかかるので困ります。


対策を考えてみました。
実装すれば、基本的にスピードの制限が無くなります。
また、チップのサイズを非常識なまでに小さくしない限り、自由に設定できます。


大体、この壁との当たり判定の処理は、

  1. スピードを物体の座標に適用する。
  2. 物体が壁に当たっているか調べる。
  3. 当たっていれば、壁の境界位置へ座標を調整。

こんな流れだと思います。

対策するには、まず、スピードを座標に適用する前に、
スピード分、細かく座標を調べていき、途中に壁があるかどうかチェックします。
物体の座標が(x, y) = (10, 10)、x軸方向スピードが25、y軸方向スピードが-15である場合、
座標にスピードを適用したら座標は(35, -5)となります。
スピードを10分割ぐらいして、
xスピード:25 / 10 = 2.5
yスピード:-15 / 10 = -1.5
あとはこの値を元の座標に1倍、2倍、3倍・・・、10倍して足した座標に対して
当たり判定を取っていけば、元の座標(10, 10)、適用後の座標(35, -5)の間を10分割して細かく当たり判定を確かめることができそうです。


イメージはこんな感じでしょうか。

int sx = obj.x;
int sy = obj.y;
for (i = 0; i < 10; ++i)
{
	sx += xSpeed / 10 * i;
	sy += ySpeed / 10 * i;
	
	// 座標(sx, sy)に対して壁当たり判定
}
if (壁に当たっている)
{
	// 壁の境界位置に座標を設定
}
else
{
	obj.x += xSpeed;
	obj.y += ySpeed;
}

「10」を増やせばより精密に、減らせばより大雑把に当たり判定をチェックできます。


これをうまいこと今のゲームに組み込めないかしら?