我正在构建一款受星际飞行启发的2D太空探索游戏,带有程序化世界。 游戏玩法分为不同的"场景"(使用戈多术语(来管理游戏的不同"深度"。 例如,星际飞行是恒星系统仅由恒星精灵表示的场景。 当玩家进入射程时,视图将移动到太阳系场景,玩家在实际太阳系内移动他的飞船。
到目前为止一切顺利,我从坐标和种子的硬编码数组中生成宇宙(太阳系(。 现在我也想让宇宙生成程序化,但我猜在内存中加载整个宇宙(一旦成为程序化,太阳系的数量就没有真正的限制(不会有效率。
我正在考虑在第一次运行时生成宇宙并将数据保存到文件中,但我想知道如何以有效的方式加载相关数据,让我只加载玩家飞船周围的特定"半径"数据。 我觉得如果我使用生成"逼真"星系形状的生成算法,这将是要走的路,因为它意味着数据处理的许多步骤(生成不同的星团形状,臂,斑点等,然后恒星围绕中心旋转以模拟星系旋转等(可能太长而无法实时计算。
我想知道我应该对这个问题采取哪种方法。 它并不真正依赖于语言或引擎,因此引用有关该主题的通用文章和算法就足够了。
我也读了一些关于 QuadTrees 的信息,我想我正在那里找到一些东西,但我不确定如何在磁盘上的文件中使用它。
提前感谢您的帮助!
我有一些建议:
- 不要在第一次运行时生成整个宇宙,只生成以某种方式可见的区域。然后,你不是从磁盘加载整个宇宙,而是在你的宇宙飞船(或其他任何东西(进入该区域的视距内时生成它。这使得游戏初始化速度更快,并允许(几乎(无限的宇宙。
- 如果您希望宇宙是可修改的,请仅存储玩家所做的"编辑"。因此,如果要显示宇宙的一部分,请从种子生成该部分,然后覆盖存储的编辑内容。这使得存储要小得多。
- 对于磁盘上的存储,请查看 R-Tree,尤其是 R*Tree 和 R+Tree,它们专为在磁盘页面中存储数据而设计。
正如TilmannZ所建议的那样,当你开始游戏时,你不应该为星系生成整个数据集,因为可能没有必要(除非玩家需要一次查看/交互所有数据 - 例如所有恒星(。如果是这种情况,例如对于星图,那么最好加载所有数据一次并将结果保存在图像文件中。
相反,您应该只根据需要在播放器周围生成数据。最明显的方法是在玩家周围构建一个网格,并在玩家四处移动时保持这个网格的中心。当玩家四处移动时,你只需要更新每个单元格的概念星系坐标(而不是渲染的坐标(。然后,对于每个像元,您可以使用坐标作为值或梯度生成器(如 Perlin(的输入,以确定应在该位置生成哪些要素。
至于"塑造"星系或宇宙,一种有效的方法是对具有所需形状的星系灰度图像的像素数据进行采样。您可以在运行时加载图像的 RGB 数据,并在生成星星时使用网格的坐标来获取 RGB 值,您可以将其用作星星生成的密度因子;像素越白,此位置的星密度越高,对于黑色像素,反之亦然。这种方法可以有效地在油漆中绘制星系的形状。
也许可以考虑不同的抽象层。每一层都使用父层、设计器输入、事件和程序生成算法来生成所需的数据。
- 宇宙层包含用户或随机放置的星系多边形和类型。
- 星系层可以添加更多细节(螺旋臂的数量和密度(或密度图。
- 太阳系的集群。
- 太阳系增加了恒星和行星。
并且仅为当前需要的元素创建详细信息。