0

2D RPG ゲームを作成しています。マップには 32x32 タイルを使用します。プレイヤーやモンスターなどのオブジェクトはスプライト マスクの幅と高さが異なり、タイルではなく x と y で移動します。だから私は、プレイヤーとタイル、プレイヤーとモンスター、モンスターとタイル、モンスターとプレイヤーの間の衝突をチェックするものを見つけるための「正しい」(速くて正確な)方法を見つけようとしています。

衝突検出には、長方形から長方形、円から円 (距離)、長方形から円、円から長方形の衝突チェックを使用します。

たとえば、幅と高さが1600x1600のマップがあります。それを 32 で割ると、50x50 のタイル マップになります。

bool の 2 次元配列を作成しました。

bool tile_area[50][50];

したがって、衝突のないすべてのタイルでは 1 を保持し、衝突のないタイルでは 0 を保持します。たとえば、プレイヤーが tile_area[1][1] にいて右に移動したい場合、 tile_area[2][1] の衝突。タイルに衝突がない場合、タイルは移動します。モンスターも同様で、ここではすべてが完璧です。

しかし、このタイプの衝突検出は、プレイヤーとモンスター、モンスターとモンスターなどの移動オブジェクト間で異なります。1 つのマップに 200 ~ 300 個の移動オブジェクトがある場合、移動するピクセルごとにメインの移動オブジェクトと他のすべてのオブジェクトの衝突をチェックするのはあまり良い考えではありません。

そこで、オブジェクトの領域のマップも分割するというアイデアを考えたので、obj_area[x][y] の構造体の 2 次元配列を取得しました。この構造体は、オブジェクト構造体「vector obj_list;」のベクトルを保持します。これは、1 つのオブジェクトだけがその領域に存在できるわけではないためです。

struct obj_area{
vector<obj> obj_list;
};

obj_area o_Area[50][50];

構造体のベクトルの 2 次元配列を作成できると思います:D よくわかりません;D

したがって、プレイヤーまたはモンスターが移動するとき、たとえば x 210 と y 300 に移動すると、obj_area[210/32=7][300/32=9] に追加され、右に移動する場合は最初にチェックしますtile_area[8][9] および空いている場合は、ベクトル obj_area[8][9] 内のすべてのオブジェクト。したがって、それも空いている場合は、obj_area[7][9] から obj_area[8][9] に再割り当てされます <- この時点では、再割り当ての良いアイデアかどうかわかりません。削除する必要があります古いベクトルから新しいベクトルに追加します。これは、移動のすべてのステップで必要になります。

別のアイデアがありますが、それがより良いか可能かはわかりません。構造体のマップと、キー値として x、y のペアがある場合、理論的には、オブジェクトが移動するたびに再割り当てする必要があります。そのマップ ペアのキー値を変更するだけで済みます。

私はあなたの考えやより良いアイデアにとても感謝しています:)

4

1 に答える 1

2

あなたのアイデアに関する最初のいくつかのコメント:

  • オブジェクトをルックアップ構造に入れないでください (これらはあなたが話している構造体ですか?)。ポインタを使用すると、データをコピーする時間を大幅に節約できます
  • vector1 つの要素の数が少なくなることがわかっている場合にのみ、s を使用します。アイテムを削除するには、ベクトル全体を反復する必要があります (線形時間の複雑さがあります)。

そして今提案:

ほとんどのオブジェクトが小さい場合は、現在の各バウンディング ボックスにアタッチできます。次に、2 つのマップ (x 軸用と y 軸用) を保持し、境界ボックスの角の座標をそれぞれのオブジェクトにマッピングすると、次のことができます。

  • オブジェクトが移動するたびに、対数時間でマップを更新します (数千のオブジェクトの場合でも小さい)
  • 軸の1つで現在扱っているオブジェクトと交差するオブジェクトとの衝突のみをチェックします(範囲の要素が少ないものを選択し、ここlower_boundupper_boundあなたの友達です)
于 2012-08-21T22:16:00.560 に答える