我一直在试验如何存储2D游戏世界的不同想法。我有兴趣听到存储大量物体的技术,同时管理可见的集合(比如100,000平方块)。显然,这些技术可以根据游戏渲染空间的方式而有所不同。
让我们假设我们正在描述一个滚动的2D游戏世界,而不是基于屏幕,因为你可以很容易地从这样的设置做基于屏幕的渲染,而反过来更麻烦。
在这里寻找与语言无关的解决方案,以便对其他人更有帮助。
编辑: 我认为这里的一个好的答案是对想到这一点时要考虑的想法的一般性回顾,正如一些响应者尝试过的那样,但也开始解释不同的解决方案将如何应用于这些场景。这是一个有点复杂的问题,所以我希望有一个很好的答案来反映这一点。
答案 0 :(得分:7)
Quadtrees是一个非常有效的解决方案,用于存储有关大型二维世界及其中对象的数据。
答案 1 :(得分:2)
您可能会从一些空间数据结构(如范围或kd树)中获得有关如何实现此功能的一些想法。
然而,这个问题的答案会因你的游戏运作方式而有很大差异。
我们是在谈论2D平台游戏,屏幕上有10个敌人,屏幕外还有20个“活跃”,未知数量更“无效”吗?如果是这样,您可以将整个级别存储为一组“屏幕”,您可以操作最接近您的屏幕。
或者你的意思是真正的2D游戏还有很多上/下运动吗?你可能需要在这里更加小心。
该平台也具有一定的重要性。如果您正在为台式机实现简单的平台游戏,您可能不必像在嵌入式设备上那样担心性能问题。这不是天真的借口,但你可能也不必非常聪明。
我认为这是一个有点有趣的问题。据推测,比我有实施平台游戏经验的人更聪明,已经把这些事情想到了。
答案 2 :(得分:2)
将世界分解成更小的区域,并处理它们。这个问题的任何解决方案都归结为这个概念(例如四叉树,在另一个答案中提到)。不同之处在于它们如何细分世界。
每个瓷砖存储多少数据?球员在世界各地的移动速度有多快?屏幕外的NPC等行为是什么?他们只是在玩家回来时重置(就像旧的塞尔达游戏一样)?他们只是恢复原状吗?他们会做一些追赶剧本吗?
不同区域需要多少不同的渲染数据?
一次可以看到多少世界?
所有这些问题都会影响您的解决方案以及平台的功能。在没有合理理解这些参数的情况下提出一般性答案将会有点困难。
答案 3 :(得分:1)
假设您的游戏只会更新可见的内容以及可见区域周围的某些区域,只需在“屏幕”中打破世界(“屏幕”是瓷砖地图上可以填满整个屏幕的矩形区域)。在内存中保留可见区域周围的“屏幕”(如果你想更新与角色接近的实体,还有更多的东西 - 但没有理由更新远处的实体)并将其余部分放在带有缓存的磁盘上当你四处走动时,避免加载/卸载常见区域。一些设置如:
+---+---+---+---+---+---+---+
|FFF|FFF|FFF|FFF|FFF|FFF|FFF|
+---+---+---+---+---+---+---+
|FFF|NNN|NNN|NNN|NNN|NNN|FFF|
+---+---+---+---+---+---+---+
|FFF|NNN|NNN|NNN|NNN|NNN|FFF|
+---+---+---+---+---+---+---+
|FFF|NNN|NNN|VVV|NNN|NNN|FFF|
+---+---+---+---+---+---+---+
|FFF|NNN|NNN|NNN|NNN|NNN|FFF|
+---+---+---+---+---+---+---+
|FFF|NNN|NNN|NNN|NNN|NNN|FFF|
+---+---+---+---+---+---+---+
|FFF|FFF|FFF|FFF|FFF|FFF|FFF|
+---+---+---+---+---+---+---+
其中“V”部分是中心(英雄或其他)所在的“屏幕”,“N”部分是附近并有活动(更新)实体,检查碰撞等的“N”部分和“F” “部件是可能不经常更新的部件,很容易被”换掉“(存储到磁盘)。当然,你可能想要使用比两个更多的“N”屏幕: - )。
请注意,由于2D游戏通常不会保留太多数据而不是将远处的部分保存到磁盘,因此您可能只想将它们保存在压缩内存中。
答案 4 :(得分:0)
您可能希望使用链接到块类型的单个int或byte数组。如果您需要从那里进行更多优化,那么您将需要链接到更复杂的数据结构,例如数组中的oct树。这里有一个关于Java游戏论坛的讨论:http://www.javagaming.org/index.php/topic,20505.30.html text
任何带链接的东西变得非常昂贵,因为指针占用的东西各占8个字节,具体取决于语言,所以根据你的世界填充方式,它会很快变得昂贵(8个指针,每个8字节,每个项目64个字节) ,每个项目的字节数组为1个字节。因此,除非你的世界的1/64是空的,否则字节数组将是一个更好的选择。每当你正在查找碰撞或其他任何事情时,你还需要花费大量时间迭代树 - 字节数组将是一个瞬时查找。
希望这对你来说足够详细。 : - )