我想写一个像《我的世界》这样的带有方块世界的简单游戏。我的理论问题是在播放期间处理此块信息的最佳方法是什么。我的第一个想法是一个庞大的数组,但是我认为这将导致内存不足。也许我只需要在播放器附近加载块。
如何处理从文件中加载所需的块信息并仅将所需的信息保留在内存中?
我想写一个像《我的世界》这样的带有方块世界的简单游戏。我的理论问题是在播放期间处理此块信息的最佳方法是什么。我的第一个想法是一个庞大的数组,但是我认为这将导致内存不足。也许我只需要在播放器附近加载块。
如何处理从文件中加载所需的块信息并仅将所需的信息保留在内存中?
Answers:
有几种不同的方法可以为带有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个新块。
我可能没有最好的解释方式,但我会尽力的。
我认为了解如何使其更有效的最佳方法是了解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