2

私はトップダウン ゲームに取り組んでいます。このゲームには、単純なものから複雑なものまで多くの衝突が含まれます。

いくつかの調査を行った後、コード内で自分のキャラクターを「オブジェクト」と常に比較し、衝突計算を確認する必要があることを理解しました。

例えば:

CheckCollisions(Player, Object);

つまり、シーン内のすべての衝突可能なオブジェクトをコードに追加する必要があります。

CheckCollisions(Player, Building1);
CheckCollisions(Player, Building2);
CheckCollisions(Player, Trash);
CheckCollisions(Player, Bench1);
CheckCollisions(Player, Bench2);
CheckCollisions(Player, Office1);
CheckCollisions(Player, Office2);

まず、オブジェクトは単純な四角形ではなく、複雑な形状である可能性があります。第二に、それらのいくつかは独自のローテーションを持っているかもしれません。第 3 に、シーン内にコリー可能なオブジェクトが数万個ある場合はどうなりますか?

HTML5/JS ゲーム内で衝突をチェックする簡単な方法はありませんか?

これは可能ですか?私は本当にいくつかのアドバイスと指針を探しています。

ありがとう

4

5 に答える 5

2

ゲーム内のすべてのオブジェクトに名前付き変数があることは非常にまれです。通常、すべてのオブジェクトを1つのデータ構造(配列など)に格納し、すべてのオブジェクトで何かを行う必要がある場合は、この配列に対してforループを実行します。

プレイヤーキャラクターのようないくつかの重要なオブジェクトは独自の変数を持つことができますが、それらは「すべてのオブジェクト」配列にも含まれている必要があるため、プレイヤーキャラクターを含めるために特別な処理をプログラムする必要はありません。

パフォーマンスについて:すべてをすべてに対してチェックすると、実行する必要のある衝突チェックの量が2倍に増加します。ただし、すでに互いに接近しているオブジェクトの衝突のみをチェックする場合は、労力を減らすことができます。衝突をチェックする前に、次のことを行います。

  1. 競技場を長方形のゾーンに分割します(ゾーンは少なくとも最大のオブジェクトと同じ大きさである必要があります)。
  2. 次に、各オブジェクトをその左上隅にあるゾーンに割り当てます。
  3. 次に、各ゾーンを取得し、その中の各オブジェクトと、ゾーン内の他のオブジェクト、およびそのゾーンの右、下、右下の3つのゾーン(ゾーンの境界と重なるオブジェクトの場合)のすべてのオブジェクトとの衝突を確認します。

非常に複雑な形状の場合は、各形状の境界長方形(形状が収まる最小の長方形)を計算することで、衝突検出を高速化することもできます。2つのオブジェクト間の衝突をチェックする前に、まずそれらの外接する長方形が交差するかどうかをチェックします。そうでない場合、複雑な形状が交差する可能性はなく、すべての複雑な計算をスキップできます。

于 2013-01-28T15:26:02.653 に答える
2

これまで誰もが指摘しているように、オブジェクトの配列は、すべてのオブジェクトに個別に名前を付けるよりもはるかに優れています。

衝突検出のはるかに簡単な方法は、すべての占有スペースを追跡する中央オブジェクトを使用することです。たとえば、LocationTracker今はそれを呼び出してみましょう。

x 軸と y 軸のみを使用していると仮定すると、X と Y の位置を格納する Point オブジェクトを使用できます (さらに、気をつけたい場合はtimestamp)。移動する各オブジェクトは、Point占有しているすべての の配列を送信します。たとえばlocationTracker.occupySpace(player[i], array(point(3,4), point(4,4), point(5,4))、 などを呼び出すことができます。

への呼び出しoccupySpaceが false を返す場合、一致するポイントはなく、安全です。true を返す場合は、衝突があります。

この方法の良い点は、オブジェクトの数が x の場合、移動ごとに x*x 回チェックするのではなく、最大 x 回チェックすることです。

オブジェクトのすべてのポイントを渡す必要はなく、最も外側のポイントだけを渡す必要があります。

于 2013-01-28T15:32:52.380 に答える
1

1 - ゲーム内のすべてのオブジェクトに対して 1 行のコードを記述する必要はありません。それらを配列に入れて、配列をループします。

var collidableObjects = [Building1, Building2, Trash, Bench1, Bench2,Office1, Office2];
var CheckAllCollisions = function() {
    for (var i=0; i<collidableObjects.length; i++) {
        CheckCollisions(Player, collidableObjects[i]);
    }
}

2 - 複雑な衝突チェック (つまり、回転した形状、多角形など) がある場合は、最初に単純な長方形チェック (または半径チェック) をチェックし、最初のチェックが true を返すかどうか、より正確なチェックを行うことができます。

3 - 何万ものオブジェクトを計画している場合は、よりスマートなデータ コレクションを用意する必要があります。たとえば、オブジェクトを X 座標で並べ替えて、Player.X+100 よりも大きく、Player.X-100 よりも小さいすべてのチェックをすばやく回避できるようにする必要があります (二分探索)、またはオブジェクトをグリッドに分割し、プレーヤーの周囲の 3x3 グリッド セル内のオブジェクトをチェックするだけです。

于 2013-01-28T15:29:25.890 に答える
0

まず第一に、常にオブジェクトを配列にする必要があります。これには、敵、弾丸、その他のものが含まれます。そうすれば、ゲームはそれらを自由に作成および破壊できます。

衝突チェックの方法ではなく、衝突チェックの実際の頻度について話しているようです。そのための私のアドバイスは、有限数のオブジェクトに対してのみ衝突チェックを実行することです。グリッドを使用して、プレイヤーと同じグリッド ブロック内のオブジェクトとの衝突のみをチェックしてみてください。

役立つもう 1 つのことは、メソッド自体の中に「ショートカット」をたくさん用意することです。これらは、複雑な計算を行う前に、すばやく簡単に確認できるものです。たとえば、2 つのオブジェクト間の距離を確認できます。オブジェクトが最も遠いコーナーよりも離れている場合、衝突をチェックする必要はありません。

独自の組み合わせで利用できるこれらの方法はたくさんあります。

于 2013-01-28T15:27:05.567 に答える
0

はるかに良い方法は、すべてのシーン オブジェクトを配列またはツリー構造に入れてから、

for( var i=0; i<scene.length; i++ ) {
    scene[i].checkCollision( player );
}

すべてのオブジェクトに関数.checkCollision()を追加すると、そこで特別なケースを処理できます。

チェック コードが複雑になりすぎないように、プレーヤーを四角形にすることをお勧めします。

プレイヤー オブジェクトの衝突チェックの長方形を実際のスプライトよりわずかに小さくします。これにより、プレイヤーの生活が楽になります。

于 2013-01-28T15:24:09.193 に答える