バックグラウンド
私は友達と一緒に、宇宙を舞台にした2Dゲームに取り組んでいます。可能な限り没入型でインタラクティブなものにするために、何千ものオブジェクトが自由に浮遊し、一緒にクラスター化されたり、空のスペースに漂っていたりしたいと思っています。
チャレンジ
レンダリングと物理エンジンに負担をかけないようにするには、ある種の空間分割を実装する必要があります。私たちが克服しなければならない2つの課題があります。最初の課題は、すべてが動いているため、データ構造の再構築/更新はフレームごとに実行する必要があるため、非常に安価でなければならないということです。2つ目の課題は、オブジェクトの分散です。前述のように、オブジェクトのクラスターと膨大な空きスペースがあり、さらに悪いことに、スペースの境界はありません。
既存のテクノロジー
私はBSPツリー、クワッドツリー、kdツリー、さらにはRツリーなどの既存の手法を見てきましたが、他のセルに移動した多くのオブジェクトを更新しているため、これらのデータ構造は完全には適合しません比較的高価です。
私が試したこと
私は、クエリに基づいて可能な最小のヒットを返すよりも、迅速な挿入/更新を目的としたデータ構造が必要だと判断しました。その目的のために、セルを暗黙的にしたので、各オブジェクトは、その位置を指定すると、どのセルにあるかを計算できます。次に、HashMap
セル座標をArrayList
(セルの内容)にマップするを使用します。「空の」セルでメモリが失われることがなく、検査するセルを簡単に計算できるため、これはかなりうまく機能します。ただし、これらすべてのArrayList
s(最悪の場合N)を作成するとコストがかかるためHashMap
、多くの時間をかけて成長します(ただし、初期容量を大きくすることで多少軽減されます)。
問題
わかりましたので、これは機能しますが、まだそれほど高速ではありません。これで、JAVAコードをマイクロ最適化することができます。ただし、プロファイラーはセルの格納に使用するすべてのオブジェクトの作成にほとんどの時間を費やしていると私に言っているので、あまり期待していません。これを大幅に高速化する他のトリック/アルゴリズムがいくつかあることを願っています。理想的なデータ構造は次のようになります。
- 最優先事項は、データ構造全体の高速更新/再構築です
- オブジェクトを同じサイズのビンに細かく分割することはそれほど重要ではありません。更新が少し速いことを意味する場合、いくつかの追加のオブジェクトを描画し、いくつかの追加の衝突チェックを実行できます。
- メモリはそれほど重要ではありません(PCゲーム)