如何像Minecraft一样处理Block World


9

我想写一个像《我的世界》这样的带有方块世界的简单游戏。我的理论问题是在播放期间处理此块信息的最佳方法是什么。我的第一个想法是一个庞大的数组,但是我认为这将导致内存不足。也许我只需要在播放器附近加载块。

如何处理从文件中加载所需的块信息并仅将所需的信息保留在内存中?


2
Minecraft将世界装在称为块的相当大的立方体中,而不是一次全部加载。我不确定确切的细节。如果您想了解一下Minecraft的去向,很容易掌握Minecraft的来源。
瑞宝,

看一下Minecraft Wiki:minecraftwiki.net/wiki/Chunk
汤姆·范·格林

我已经知道《我的世界》中的大块内容,但还是要感谢。
danijar

这是一个复杂的问题,不适合本博客的范围。

Answers:


9

有几种不同的方法可以为带有Minecraft之类的块的游戏存储数据。

我相信Minecraft的做法是在16x16x256块中打破世界。玩家启动游戏时,玩家周围的块会加载到内存中,然后在您四处走动时会加载更多后台线程。以下是展示该视频的视频:http : //www.youtube.com/watch?v=oR_ZdJH9eho

做到这一点的另一种方法是将世界分解成八进制。Michael Goodfellow撰写了有关使用此数据结构实现多维数据集世界的博客:http : //www.sea-of-memes.com/LetsCode1/LetsCode1.html。Octree很不错,因为它为您提供了一些内置的压缩​​功能,但是与Array一起使用可能会更难一点。

关于将“仅需要的那些保留在内存中”?这有点困难,因为您必须问“需要”什么。如果您的NPC通过与环境互动的AI生活在世界的另一端,那么您“需要”更多的世界来记忆。Voxel世界数据可以非常快地变得非常大,因此最好尝试将尽可能少的数据保持在内存中。(即,只有NPC靠近播放器)。

图形引擎将“需要”每个未被其他非透明块完全包围的块。渲染世界的常用方法是构建一个包含每个可见块的顶点的网格。由于您只对65,536个块(以Minecraft大小的块为单位)对draw方法进行了一次调用,因此绘制速度更快。由于图形引擎将需要构建此网格,因此通常需要了解块中的所有多维数据集。请注意,这就是为什么当您透过Minecraft的地板看时,很多世界都是不可见的。这是因为跳过了在所有六个侧面上包围的每个块。我相信Minecraft还可以通过将相同纹理的水平边合并到一个具有重复纹理的盒子中来减少顶点数量。

我的建议是使用16x16x256块。将它们存储在数组中,因为构建网格和游戏逻辑(碰撞检测,添加/删除块等)将需要快速迭代和编辑。然后,尽可能多地在播放器周围的一个圆圈中加载多个块。放大或缩小块的数量,以提高或降低计算机的性能。

块的加载将极大地影响性能,因此请将其放入随时间运行的线程中。做到这一点,这样您就可以在玩家从一个块的一端移到另一个块的时间内完全加载3个新块。


谢谢!关于AI并没有什么,因为我正在为MMO编写客户端。NPC的计算由服务器完成。一个补充:图形引擎不需要“不是由其他非透明块不完全包围的每个块”。如果有洞穴,玩家看不到它们并不重要。;-)
danijar

2
关于玩家看不到的洞穴...我认为,绘制洞穴比使用以确定洞穴是否被完全挡住的性能要低。如果不绘制洞穴,则如果删除了一个块,则可能必须重新生成多个块的网格,而不仅仅是一个。找到排除洞穴的方法很酷,我只是想不出一种有效的方法:D。
托马斯·马奈尔

3

我可能没有最好的解释方式,但我会尽力的。

我认为了解如何使其更有效的最佳方法是了解Voxels。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
Marching Cubes是关于可视化体素的。Minecraft甚至不使用它。它只是绘制多维数据集,而这恰恰是Marching Cubes 不做的事情。
Nicol Bolas 2012年

感谢您的解释!我以前从未听说过Voxels,这对于我的项目而言似乎非常重要。但是我还有一个问题。
danijar

我了解创建一个近块的数组,其中每个元素都包含该块的体素数组。但是当玩家在世界各地移动时,我需要处理更改块数组的问题。我是否需要从保存文件中读取所需的块?还是有一种很好的方式将它们保存在内存中?
danijar

2
@danijar只是一些琐事,像素是“像素”的缩写,体素与“体积元素”的形成方式相同。并不是说这对任何事情都重要,但是由于您在我认为这可能对您有些兴趣之前还没有听说过体素这个词。
Daniel Carlsson

1

您可以尝试仅渲染可见的表面,计算机在后台处理块数据,而渲染器仅适用于您所看到的内容。8x8块将更易于处理。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.