7

2D ゲームの世界を保存する方法について、さまざまなアイデアを試してきました。大量のオブジェクトを格納しながら、目に見えるセット (100,000 タイルの正方形としましょう) を管理する技術に興味があります。明らかに、ゲームがその空間をどのようにレンダリングするかによって、テクニックは異なります。

画面ベースではなく、スクロールする 2D ゲームの世界を説明していると仮定しましょう。そのようなセットアップから画面ベースのレンダリングをかなり簡単に行うことができますが、その逆はもう少し面倒です。

ここで言語にとらわれないソリューションを探しているので、他の人にとってより役に立ちます。

編集:ここでの良い答えは、これについて考えるときに考慮すべきアイデアの一般的なレビューであると思います.一部のレスポンダーが試みましたが、これらのシナリオにさまざまなソリューションがどのように適用されるかについても説明し始めています. これはやや複雑な質問なので、それを反映した適切な回答を期待しています。

4

5 に答える 5

7

四分木は、大きな 2 次元の世界とその中のオブジェクトに関するデータを格納するためのかなり効率的なソリューションです。

于 2009-08-02T06:09:56.477 に答える
2

範囲や kd ツリーなどの空間データ構造から、これを実装する方法についていくつかのアイデアが得られるかもしれません。

ただし、この質問に対する答えは、ゲームがどのように機能するかによって大きく異なります。

画面上に 10 人の敵がいて、画面外に「アクティブ」な敵が 20 人、さらに「非アクティブ」な未知数の敵がいる 2D プラットフォーマーについて話しているのでしょうか。その場合、レベル全体を「スクリーン」の配列として保存し、最も近いものを操作することができます。

それとも、上下の動きが多い真の 2D ゲームのことですか? ここはもう少し注意が必要かもしれません。

プラットフォームも重要です。デスクトップ PC 用の単純なプラットフォーマーを実装している場合は、組み込みデバイスの場合ほどパフォーマンスについて心配する必要はないでしょう。これはナイーブであることの言い訳にはなりませんが、それほど賢くある必要はないかもしれません。

これはやや興味深い質問だと思います。おそらく、プラットフォーマーの実装経験がある私より頭の良い誰かが、これらのことをすでに考え出しています。

于 2009-08-02T05:30:06.760 に答える
2

世界をより小さな領域に分割し、それらに対処します。この問題に対する解決策は、この概念に要約されます (別の回答で言及されている四分木など)。違いは、世界を細分化する方法にあります。

タイルごとに保存されるデータの量は? プレイヤーはどのくらいの速さで世界中を移動できますか? 画面外にいるNPC等の挙動は?プレイヤーが戻ってきたときにリセットされるだけですか (古いゼルダのゲームのように)? 彼らは単に元の場所に戻るだけですか?彼らはある種のキャッチアップスクリプトを実行しますか?

領域ごとにどれだけの異なるレンダリング データが必要になるか?

一度に見られる世界の広さは?

これらの質問はすべて、プラットフォームの機能だけでなく、ソリューションにも影響を与えます。これらのパラメータについて合理的な考えがなければ、これらの一般的な答えを考え出すのは少し難しいでしょう。

于 2009-08-02T06:37:36.580 に答える
1

あなたのゲームが表示されているものと表示されているものの周りの一部の領域のみを更新すると仮定すると、世界を「スクリーン」に分けてください (「スクリーン」とは、タイルマップ上の四角形の領域で、スクリーン全体を埋めることができます)。可視領域の周りの「スクリーン」をメモリに保持し (キャラクターに近いエンティティを更新したい場合はさらにいくつか - ただし、遠く離れたエンティティを更新する理由はほとんどありません)、残りをキャッシュ付きのディスクに保持します。移動するときによく訪れるエリアの積み降ろしを避けるため。次のようないくつかの設定:

+---+---+---+---+---+---+---+
|FFF|FFF|FFF|FFF|FFF|FFF|FFF|
+---+---+---+---+---+---+---+
|FFF|NNN|NNN|NNN|NNN|NNN|FFF|
+---+---+---+---+---+---+---+
|FFF|NNN|NNN|NNN|NNN|NNN|FFF|
+---+---+---+---+---+---+---+
|FFF|NNN|NNN|VVV|NNN|NNN|FFF|
+---+---+---+---+---+---+---+
|FFF|NNN|NNN|NNN|NNN|NNN|FFF|
+---+---+---+---+---+---+---+
|FFF|NNN|NNN|NNN|NNN|NNN|FFF|
+---+---+---+---+---+---+---+
|FFF|FFF|FFF|FFF|FFF|FFF|FFF|
+---+---+---+---+---+---+---+

「V」部分は中心(ヒーローなど)が存在する「スクリーン」であり、「N」部分は近くにいてアクティブな(更新中の)エンティティを持ち、衝突などをチェックする人であり、「F」部分は頻繁に更新されず、「スワップ」アウト (ディスクに保存) される傾向がある far パーツ。もちろん、2 つよりも多くの "N" 画面を使用することもできます:-)。

ところで、2D ゲームは通常、遠く離れた部分をディスクに保存する代わりに多くのデータを保持しないため、それらをメモリ内で圧縮したままにしておくことをお勧めします。

于 2009-08-05T05:10:46.763 に答える
0

おそらく、ブロック型にリンクする単一の int または byte 配列を使用する必要があります。そこからさらに最適化が必要な場合は、配列から oct ツリーなどのより複雑なデータ構造にリンクする必要があります。ここの Java ゲーム フォーラムで良い議論があります: http://www.javagaming.org/index.php/topic,20505.30.html テキスト

言語によっては、ポインターがそれぞれ 8 バイト程度を占めるため、リンクを含むものはすべて非常に高価になります。そのため、世界の人口によっては、非常に急速に高価になる可能性があります (8 つのポインターはそれぞれ 8 バイトで、アイテムごとに 64 バイトであり、バイト配列はアイテムごとに 1 バイトです)。したがって、世界の 1/64 が空でない限り、バイト配列の方がはるかに優れたオプションになります。また、衝突などのルックアップを行うときはいつでも、ツリーをたどるのに多くの時間を費やす必要があります。バイト配列は瞬時のルックアップになります。

うまくいけば、それはあなたにとって十分に詳細です。:-)

于 2009-08-19T03:09:15.087 に答える