Google

2014年1月22日水曜日

HTML5で3Dゲーム:当たり判定

今回はタイトル通りの話です。
当たり判定問題はどのFWを使おうが付いて回るもの。
一応曲りなりにもアクションゲーの分類に入る訳ですから、適当には出来ません。

主人公も接近する物体もどちらもペラ1枚の画像を使うと決めたので、システム上では矩形です。
これをそのままサイズで判定すると最も矛盾が生じるのは斜めの部分でしょう。

避けたつもりが当たってる、よくあるパターンです。
前回の記事の通り、最大で1つのエリアに4個の物体(アイテムor障害物)が存在するのですが、これらが同時に4個当たる仕組みにすると、それはそれで処理も煩雑になります。
まあ解決策は簡単で、当たり判定は皆さんおなじみの某定理を使って、円状にすることにしました。
もし判定を円ではなく球状にすれば3Dになりますが、元々が2D処理している点と見た目のズレが相まって無駄な努力になる可能性を考慮し、遊んで問題なければOKとする判断になりました。

その際に作ったのは簡単な円の概念を持つクラス、Circleです。

// サークルクラス
function Circle(x, y, r) {
    this.x = x;
    this.y = y;
    this.r = r;
}
// isHitメンバ関数です。引数はCircleインスタンスです。
Circle.prototype.isHit = function(doubt) {
    return ((doubt.x - this.x) * (doubt.x - this.x) + (doubt.y - this.y) * (doubt.y - this.y) < (this.r + doubt.r) * (this.r + doubt.r));
};

判定は数学でおなじみのアレです
このクラスは基準となるx,y位置と半径のrを持ち、定理を使ったヒット判定関数だけを実装しています。
主人公、障害物共にこの基本となる値を持たせるのですが、単にこのままでは使えません。
擬似的な球状を表現するため、本体の中心位置から遠ざかるほど半径を縮めて計算するようにしたわけです。

台北にあるダンパーの写真です。
いや、これを見せたい訳じゃなくて、円の判定がこのように折り重なってると
いうことを表現するために出したのですが、、、、
JavaScriptはENTER_FRAMEの間隔が保証されているわけでもないため、前回のフレームからの経過時間を元にし、移動した距離分の差分に丸め誤差を入れてあたったかどうかを判定するといった感じになります。
ここは入り組んでいるので部分的なサンプルが出しづらいためソース無しです、すみません。

分割すべき内容だったので、壁床の仕組みは次回書きます。

0 件のコメント:

コメントを投稿