とんんでもないスピードでぶっ飛びたい
アクションゲームだけでなく、チップ単位の壁の当たり判定があるゲームを作る場合、必ず考えなければならないことがあります。
それは、壁のすり抜け対策。
アクションゲームを作っていて、これの対策を後回しにしている人間は、僕ぐらいなんじゃないかと。
ひどい怠慢です。
なぜ壁のすり抜けが発生するかというと、この当たり判定があるチップのサイズが25×25だとします。
ゲーム上の、ある物質がx軸方向、y軸方向のどちらでもいいですが、
25より速いスピードで動いている場合、チップを飛び越えてすり抜けてしまう現象が起こります。
この対策として、非常に簡単な方法が2つ。
- チップサイズを大きくする。
- 物体の最大スピードをチップサイズ以下にする。
僕は2を使っています。
いつか直そうとは思っているのですが。
1は、ステージの当たり判定を細かく設定し辛くなります。
2は、超スピードが出せなくなります。
どちらも何らかの制限がかかるので困ります。
対策を考えてみました。
実装すれば、基本的にスピードの制限が無くなります。
また、チップのサイズを非常識なまでに小さくしない限り、自由に設定できます。
大体、この壁との当たり判定の処理は、
- スピードを物体の座標に適用する。
- 物体が壁に当たっているか調べる。
- 当たっていれば、壁の境界位置へ座標を調整。
こんな流れだと思います。
対策するには、まず、スピードを座標に適用する前に、
スピード分、細かく座標を調べていき、途中に壁があるかどうかチェックします。
物体の座標が(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」を増やせばより精密に、減らせばより大雑把に当たり判定をチェックできます。
これをうまいこと今のゲームに組み込めないかしら?