5

2D タイル ベースのゲームを作成しています。2D ジャグ配列を使用して整数を格納すると、レンダラーはその整数に応じて特定の画像を描画します。コードのこの部分は機能していますが、次の処理方法がわからないところまで来ました。

プレイヤーがゲームを進めていくと、光レベル、ユーザーがそのセルをクリックした回数、画像の回転値など、すべてのセルに関する情報を 2D 配列に保存できる必要があります。そのセル、またはその画像のアルファレベルなど

これを行う唯一の方法は、使用している各情報に対して、以前に行ったように 2D 配列を作成することです。たとえば、次のようになります。

AlphaLevel[][]
NumberOfTimesClicked[][]

そして、(たとえば) ユーザーがセルをクリックした回数を確認する必要がある場合は、NumberOfTimesClicked[5][5] を実行するか、回転を設定する必要がある場合は SetRotation[5][ を実行できます。 5] = 90。

私が確信していないのは、これがどれほど効率的であるかということです。情報の各部分に配列を持たせることは、メモリ効率が悪いようです。

私は良い解決策を持っていますか、それとも私が考えていなかったより良い方法がありますか?

どんなアドバイスも素晴らしいでしょう!ありがとう

4

3 に答える 3

22

とのような情報を持つTileオブジェクトを作成し、それらのギザギザの配列を作成します。そうすれば、すべての情報を保持するために 1 つのギザギザ配列だけが必要になります。これは、 が持つすべてのプロパティを簡単に見つけることができるため、より適切に編成されます。AlphaLevelNumberOfTimesClickedTile

メモリの最適化に興味があるなら、NPSF3000 は、構造体がわずかに優れていると言っているのは正しいです。使用する前に、値と参照の型がどのように異なるかをよく理解しておいてください。

小さい形式でデータを保存すると、データをまったく保存しない場合よりも常に大きくなります。現在のデータを可能な限り圧縮することに加えて、ディスクに保存する必要のない古いデータを保存する方法、または後で手続き的に生成できるデータを破棄する方法を検討してください。

最後の注意: 本当に圧縮する必要がありますか? 過去に 2D タイル システムに取り組んだとき、実際にはそれほど多くのメモリを使用していなかったので、速度を向上させるために余分なデータを格納していたことに気付きました。いくつかの数値を実行して、最適化に十分なメモリを実際に使用していることを確認してください。

于 2013-08-19T17:12:11.917 に答える
5

私が確信していないのは、これがどれほど効率的であるかということです。情報の各部分に配列を持たせることは、メモリ効率が悪いようです。

簡単な回答: 代わりに Structs を使用できます。単純に「すべてをまとめて格納する」ことで、追加の配列を取り除くことができます。


長い答え:

配列の表現は次のようなものです Header:Data 。ヘッダーは 4 バイトの Int32 です。

現在、ストレージは次のようになっています。

IIII:B:B:B  //Byte array (e.g. alpha level)
IIII:SS:SS:SS  //Short array (e.g. num times clicked)
IIII:B:B:B  //Byte array

ここで、I、B、および S は、それぞれ Int、Byte、および Short のバイトを表します。Struct を使用すると、次のようにすべてをまとめて保存できます。

IIII:BSSB:BSSB:BSSB

代わりにクラスを使用すると、クラスはデータの場所への参照として配列に格納されるため、見た目が大きく異なります。

IIII:RRRR:RRRR:RRRR
BSSB  //These can be stored anywhere in memory
BSSB  //These can be stored anywhere in memory
BSSB  //These can be stored anywhere in memory

したがって、構造体はいくらかのメモリを節約できますが、それほど多くはありません。代わりにクラスを使用すると、実際にメモリが消費されます! ただし、使用するメモリは連続している必要はありません。これは、大量の大きなデータ グループ (合計 1 GB 以上) を格納する場合に役立ちます。32 ビット マシンでは... ただし、これについては別の機会に説明します。

もちろん、これは純粋にメモリ サイズの効率に関するものです。ワークロードがフィールドごとに計算を行う場合、個々の配列ははるかにキャッシュ フレンドリーになり、効率的になります。逆に、タイルごとに計算を行う傾向がある場合は、その逆になります。クラスは raw ストレージには非効率的ですが、コーディング パラダイムに適合する場合、開発がはるかに容易になる可能性があります。さらに、クラスは、多くのオブジェクトが同じデータへの参照を必要とする場合に適しています。重複を減らすことでメモリを節約することもできます!

基本をよく理解していると少し役立つことがわかるので、これがお役に立てば幸いです。ただし、最も重要なことは、自分の時間を大切にすることです。パフォーマンスが問題になるかどうか、いつパフォーマンスが問題になるかを自分でテストしてベンチマークすることです。

免責事項:早朝に書いたもので、間違っている/抜けがあるかもしれません.

于 2013-08-19T17:41:53.140 に答える
0

4 つのアプローチは次のとおりです。

  • 各マップセルが持つ属性ごとにギザギザ配列を定義する
  • 複数のセル属性を 1 つの構造型に結合し (最高のパフォーマンスとセマンティクスのために、プロパティではなくパブリック フィールドを公開します)、それらのジャグ配列を定義します。
  • 複数のセル属性を保持する不変クラス型クラス型を定義し、それらのジャグ配列を定義し、すべての要素をデフォルト インスタンスで初期化します。
  • 複数のセル属性を保持する変更可能なクラス型を定義し、それらのジャグ配列を定義し、配列のすべての要素を初期化して個別のオブジェクト インスタンスを参照し、配列に再度書き込むことはありません (参照を保持するインスタンスを変更するだけです)。 .

一緒にアクセスされる可能性が高い特定の属性グループとそうでない属性グループがある場合、2 番目のアプローチを使用して最適なパフォーマンスを達成し、しばしば一緒に使用されるものをグループ化することができます。他よりもはるかに頻繁に発生する属性値の特定の組み合わせがある場合、それらの特定の属性を組み合わせて不変のクラスにすることが理にかなっている場合があります。ただし、通常、内部データ型の場合は、公開フィールド構造体型のジャグ配列を使用することをお勧めします。

このアプリケーションでは、構造体は不変でなければならないというマントラは、まったく間違っています。可変構造のセマンティクスは、クラスのセマンティクスとは異なります。それを理解していない人は、混乱するかもしれません。ただし、これは、構造体の使用を避けるべきだという意味ではありません。むしろ、優れたプログラマーになりたい人は、構造がどのように機能するかを理解する必要があることを意味します。すべての公開フィールド構造は同じように動作し、そのようなすべての構造がどのように動作するかを学ぶことは、典型的なフレームワーク クラスの使用方法を学ぶよりも長くはかからないはずです。

于 2013-08-19T23:41:12.947 に答える