Minecraftのようなブロックワールドを処理する方法


9

Minecraftのようなブロックの世界で簡単なゲームを書きたいです。私の理論的な質問は、再生中にこのブロック情報を処理する最良の方法は何ですか。私の最初のアイデアは巨大な配列でしたが、これはメモリ不足を引き起こすと思います。多分私はプレーヤーの近くのブロックをロードする必要があるだけです。

ファイルから必要なブロック情報をロードし、必要なものだけをメモリに保持するにはどうすればよいですか?


2
Minecraftは、チャンクと呼ばれるかなり大きなキューブに世界をロードします。一度にすべてではありません。正確な詳細はわかりません。Minecraftのソースは、それがどのように行われたのかを確認したい場合、簡単に入手できます。
ラトバム2012

minecraft wikiをご覧ください:minecraftwiki.net/wiki/Chunk
tom van green

私はすでにMinecraftのチャンクについて知っていましたが、とにかく感謝します。
ダニジャー

これは、このブログの範囲には適さない複雑な質問です。

回答:


9

Minecraftのようなブロックを持つゲームのデータを保存するには、いくつかの方法があります。

Minecraftのやり方は、16x16x256チャンクで世界を壊すことだと私は信じています。プレーヤーの周りのチャンクは、プレーヤーがゲームを開始するときにメモリに読み込まれます。その後、バックグラウンドスレッドは、歩き回るとさらに読み込まれます。これを示すビデオは次のとおりです:http : //www.youtube.com/watch?v=oR_ZdJH9eho

それを行うもう1つの方法は、世界をOctreeに分割することです。Michael Goodfellowは、次のデータ構造でキューブワールドを実装することについてブログを書いていますhttp : //www.sea-of-memes.com/LetsCode1/LetsCode1.html。Octreeは組み込みの圧縮機能を備えているので素晴らしいですが、おそらくArrayでの作業は少し難しくなります。

「必要なものだけをメモリに残しておく」とは?「必要なもの」を尋ねなければならないので、これは少し難しいです。環境と相互作用するAIを使用して、世界の別の場所に住んでいるNPCがある場合、メモリに多くの世界が存在する必要があります。ボクセルワールドデータは非常に速く非常に大きくなる可能性があるため、メモリ内のデータ量をできるだけ少なくすることをお勧めします。(つまり、プレイヤーの近くにのみNPCがあります)。

グラフィックエンジンは、他の不透明なブロックで完全に囲まれていないすべてのブロックを「必要」とします。ワールドをレンダリングする通常の方法は、すべての可視ブロックの頂点を含む単一のメッシュを構築することです。65,536ブロック(Minecraftサイズのチャンク)の描画メソッドを1回呼び出すだけなので、これは描画がはるかに高速です。グラフィックスエンジンはこのメッシュを構築する必要があるため、通常、チャンク内のすべてのキューブを知る必要があります。これが、Minecraftの床を通して見ると、世界の多くが見えない理由です。これは、6辺すべてで囲まれているすべてのブロックがスキップされるためです。Minecraftは、同じ種類のテクスチャの水平方向の辺を1つのボックスに組み合わせてテクスチャを繰り返すことで、頂点の数も減らすと思います。

私のアドバイスは、16x16x256チャンクを使用することです。メッシュとゲームロジックの構築(衝突検出、ブロックの追加/削除など)のために高速な反復と編集が必要になるため、それらを配列に格納します。次に、プレーヤーの周りの円にできるだけ多くのチャンクをロードします。チャンクの数を増減して、コンピュータの性能を向上または低下させます。

チャンクのロードはパフォーマンスに大きな影響を与えるので、時間の経過とともに実行するスレッドに入れます。プレーヤーがチャンクの一方の端から他方の端まで歩くのにかかる時間中に、3つの新しいチャンクを完全にロードできるようにします。


ありがとうございました!MMOのクライアントを書いているので、AIについては何もありません。NPCの計算はサーバーによって行われます。1つの追加:「他の非透過ブロックによって完全に囲まれていないすべてのブロック」は、グラフィックスエンジンでは必要ありません。洞窟がある場合、プレイヤーはそれらが重要でないことを見ることができません。;-)
danijar 2012

2
プレイヤーが見えない洞窟について...洞窟を完全に塞いでいるかどうかを判断するよりも、洞窟を描くだけの方がパフォーマンスが低いと思います。また、洞窟を描かない場合、ブロックを削除すると、1つではなく複数のチャンクのメッシュを再生成する必要が生じる可能性があります。洞窟を除外する方法を見つけるのは素晴らしいことです。私はそれを効率的に行う方法を考えることができません:D。
Thomas Marnell、2012

3

私にはそれを説明する最良の方法がないかもしれませんが、私は試みます。

私はそれをより効率的にする方法を理解する最良の方法はボクセルを理解することだと思います。Minecraftはボクセルベースで、球などの代わりに立方体を使用します。

基本的にボクセルは動的に変化するボリュームを持つことができる3D形状であり、ボリュームが変化すると形状も変化します。チャンクは、X x X x Xのボクセルのセットです。したがって、たとえば、16x16x16ボクセルを持つチャンクを作成し、X個のチャンクを作成することができます。距離が設定されます。プレーヤーがチャンクからNを超えている場合は、それらを計算に含めないでください。これはクリッピング距離に少し似ていますが、各チャンクにも適用する必要があります。このようにして、プレーヤーを常に中央のチャンク、たとえば3x3のチャンクセットに置くことができます。

したがって、個々のボクセルを処理するためのクラスがあります。これをVoxel_clと呼びます。そして、Chunk_clと呼ばれるボクセルのチャンクを処理するクラスがあります。そして、World_clと呼ばれる、ボクセルを生成するすべてのチャンクを生成するいくつかのワールドクラスがあります。

そのため、すべての巨大な配列の代わりに、いつでも9個のチャンクの配列があり、チャンククラスでは、4096個のボクセルの配列があります。

これはかなり簡単な説明であることに注意してください。私は現在ボクセルを使用して何かに取り組んでいるので、自分の入力をスローするだろうと考えました=-)

ボクセルの詳細については、http://en.wikipedia.org/wiki/Marching_cubesを確認してください


3
マーチングキューブはボクセルを視覚化することです。そして、Minecraftはそれさえ使用しません。それは単にキューブを描画するだけであり、これはまさにマーチングキューブが行っていないことです。
Nicol Bolas

説明ありがとうございます!ボクセルについて聞いたことがなく、私のプロジェクトにとって非常に重要なようです。しかし、今、質問があります。
ダニジャー

各要素にこのチャンクのボクセルの配列が含まれるニアチャンクの配列の作成を理解しています。しかし、プレイヤーが世界を動き回るときにチャンク配列を変更する必要があります。保存ファイルから必要なチャンクを読み取る必要がありますか?または、それらをメモリに保持する良い方法はありますか?
ダニジャー

2
@danijarほんの一部の雑学。ピクセルは「ピクチャエレメント」の略で、ボクセルは「ボリュームエレメント」から同じ方法で形成されます。それは何の問題でもないが、あなたがボクセルという言葉をあなたが何らかの興味を持つかもしれないと思う前に聞いたことがないので。
ダニエルカールソン

1

レンダラーは表示されているものだけを処理するのに対し、コンピューターはバックグラウンドでブロックデータを処理するだけで、表示されているサーフェスをレンダリングすることができます。8x8チャンクの方が扱いやすいでしょう。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.