2016-11-24 6 views
2

私は学校プロジェクトのためにJavaで2-D RPGスタイルのスプライトベースのゲームをコーディングしています。私たちのグループは、ゲームに固定されたものではなくプレーヤーに従うカメラが必要であると判断しました。プレーヤーが移動するにつれて世界のデータを動的にロードする必要があります。私はこれがMinecraftのように世界のセクションをチャンクに読み込むことで実現できることを知っていますが、大量のデータをあまり頻繁に読み込むのではなく、少量のデータを選択的かつ頻繁にロードできるようにしたいと思います。たとえば、プレーヤーは1つのユニットを上に移動するので、チャンク全体をロードしたり、チャンクを毎回アンロードしたりするのではなく、一番上のローをロードしながら、メモリからデータの最下位行を破棄することができます。現在のところ、関連する世界のデータはすべて2次元配列に格納されているので、全体を読み込んだり大きなチャンクで読み込んだりすることなく、配列内の特定のデータポイントをワールドファイルからロードする効率的な方法はありますか?Javaの直列化オブジェクトから選択データを読み込むにはどうすればよいですか?

また、ハードドライブからの読み込みに時間がかかりますので、大きなチャンクローディングが最適です。

この場合、基本的にはチャンクである領域という小さなファイルで構成されるワールドファイルがあるとします。

私の質問は次のようなものです。「すべてのものを一度にロードせずにメインワールドファイルから特定の領域をロードするにはどうすればいいですか?

+0

これで、ファイルに行列を保存し、後でファイル全体を調べずにファイルからランダムにサブ行列にアクセスしたいとしますか? –

+0

@WasiAhmad基本的にはい。 –

+0

ファイル形式によって異なります。指定されたセルのオフセットをプログラムで決定できる場合は、そのオフセットを検索して読み込むことができます。できない場合(セルのサイズが可変)、シリアル化されたデータのインデックスをセルからオフセットにする必要があります。しかし、このために、ディスクシークはあなたを殺してくれるでしょうし、あなたはおそらく世界全体を記憶に収めることができます。 –

答えて

2

大きな行列を読み込むには大量のメモリが必要なので、主に巨大行列の格納に使用できるexampleがあります。メモリに読み込む代わりに、ランダムアクセスファイルに行列を格納すると、それらを非常に素早く取り出すことができます。後で使用するためにマトリックスをRandomAccessFileにマップする必要があります。私は例全体を反復するのではなく、必要に応じて再実装できるように、明確に理解する必要のある主要部分だけを繰り返します。

public long position(int x, int y) { 
    return (long) y * width + x;   // returns the position of a value in the file 
} 

public double get(int x, int y) { 
    assert x <= 0 && x > width;   // simply bound check 
    assert y <= 0 && y > height;   // simply bound check 
    long p = position(x, y) * 8;   // 8 for double, if integer then use 4 
    int mapN = (int) (p/MAPPING_SIZE); 
    int offN = (int) (p % MAPPING_SIZE); 
    return mappings.get(mapN).getDouble(offN); 
} 

get方法は、ファイルに格納されたマトリックス中の特定の位置(行、列)から値を取得します。 mappingsは、Javaのlistのような単なるデータ構造です。 getメソッドと同様に、setメソッドも必要です。

public void set(int x, int y, double d) { 
    assert x <= 0 && x > width; 
    assert y <= 0 && y > height; 
    long p = position(x, y) * 8; 
    int mapN = (int) (p/MAPPING_SIZE); 
    int offN = (int) (p % MAPPING_SIZE); 
    mappings.get(mapN).putDouble(offN, d); 
} 

重要Javaのは一度に2ギガバイト(2^31)以上のマッピングをサポートしていないためMAPPING_SIZE1 << 31または低い値に設定することができます。したがって、セットMAPPING_SIZE = 1 << 30を使用すると、ファイルを1 GBのマッピングに分割します。簡単にするために、大きな行列を分割して小さな断片に格納すると考えることができます(これらはマッピングと呼ばれます)。小さな行列があれば、それを心配する必要はありません。

+0

ありがとう、これはまさに私が探していたものです! –

+0

@GregorySalazar最高の方法は、答えを受け入れることとupvoteを与えることです) –

+0

申し訳ありません私はここに新しいです、私はあなたをupvotedしかし、私の評判がまだ十分に高くないので表示されません –

関連する問題