Data structures 存储大型2D游戏世界

Data structures 存储大型2D游戏世界,data-structures,spatial,Data Structures,Spatial,我一直在试验如何存储2D游戏世界的不同想法。我感兴趣的是如何在管理可见的设备(比如100000个方形瓷砖)的同时存储大量对象。显然,技术可以根据游戏渲染空间的方式而有所不同 让我们假设我们描述的是一个滚动的2d游戏世界,而不是基于屏幕的游戏世界,因为你可以很容易地从这样的设置中进行基于屏幕的渲染,而反之则有点混乱 在这里寻找语言不可知的解决方案,这样对其他人更有帮助 强>编辑:< /强>我认为这里的一个很好的答案是当思考一些问题时,要考虑这些想法的一般性回顾,因为一些应答者已经尝试过,但是也开始

我一直在试验如何存储2D游戏世界的不同想法。我感兴趣的是如何在管理可见的设备(比如100000个方形瓷砖)的同时存储大量对象。显然,技术可以根据游戏渲染空间的方式而有所不同

让我们假设我们描述的是一个滚动的2d游戏世界,而不是基于屏幕的游戏世界,因为你可以很容易地从这样的设置中进行基于屏幕的渲染,而反之则有点混乱

在这里寻找语言不可知的解决方案,这样对其他人更有帮助


<>强>编辑:< /强>我认为这里的一个很好的答案是当思考一些问题时,要考虑这些想法的一般性回顾,因为一些应答者已经尝试过,但是也开始解释不同的解决方案会如何应用于这些场景。这是一个有点复杂的问题,所以我希望有一个很好的答案来反映这一点。

您可能会从一些空间数据结构(如范围树或kd树)中了解如何实现这一点

然而,这个问题的答案会有很大的不同,这完全取决于你的游戏是如何运作的

我们说的是一个2D平台,屏幕上有10个敌人,屏幕外有20个敌人,但“活跃”,还有一个未知的数字“不活跃”?如果是这样的话,你可以将你的整个关卡存储为一系列“屏幕”,在那里你可以操作离你最近的那些屏幕

或者你的意思是一个真正的2D游戏,有很多上下运动?你在这里可能得更小心一点

这个平台也很重要。如果您正在为台式PC实现一个简单的平台,您可能不必像在嵌入式设备上那样担心性能。这不是幼稚的借口,但你也不必太聪明


我认为这是一个有点有趣的问题。大概是比我更聪明、有实施平台化经验的人已经想到了这些问题。

是一个相当有效的解决方案,用于存储关于大二维世界及其对象的数据。

将世界划分为更小的区域,并对其进行处理。这个问题的任何解决方案都将归结为这个概念(例如,在另一个答案中提到的四叉树)。不同之处在于他们如何细分世界

每个磁贴存储多少数据?玩家能以多快的速度穿越世界?NPC等的屏幕外行为是什么?当玩家回来时,他们会重置吗(就像旧的塞尔达游戏)?他们只是简单地回到原来的位置吗?他们有没有做过一些赶超剧本

不同区域需要多少不同的渲染数据

一次能看到多少世界


所有这些问题都将影响您的解决方案以及平台的功能。在对这些参数没有合理了解的情况下,对这些问题给出一个一般性的答案会有点困难。

假设您的游戏只会更新可见的内容和可见内容周围的某个区域,只需将世界划分为“屏幕”(屏幕是tilemap上可以填充整个屏幕的矩形区域)。将可见区域周围的“屏幕”保留在内存中(如果您想更新靠近角色的实体,可以保留一些屏幕,但没有理由更新那么远的实体),并将其余的屏幕保存在磁盘上,带有缓存,以避免在移动时加载/卸载经常访问的区域。一些设置如下:

+---+---+---+---+---+---+---+
|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”部分是那些在附近且具有活动(更新)实体、检查碰撞等的部分,“F”部分是可能不经常更新且易于“交换”(存储到磁盘)的远部分。当然,您可能希望使用多于两个的“N”屏幕:-)


顺便说一句,由于2D游戏通常不会保存太多数据,而不是将遥远的部分保存到磁盘上,因此您可能希望将它们保存在内存中进行压缩。

您可能希望使用链接到块类型的单个int或byte数组。如果需要进一步优化,则需要从阵列中链接到更复杂的数据结构,如oct树。在Java游戏论坛上有一个很好的讨论:

任何带有链接的东西都会变得非常昂贵,因为指针根据语言的不同,每个指针占用大约8个字节,因此根据您的世界的填充情况,它可能会很快变得非常昂贵(8个指针8个字节每项64个字节,字节数组每项1个字节)。因此,除非世界的1/64是空的,否则字节数组将是更好的选择。在查找冲突或其他任何情况时,您还需要花费大量时间在树上进行迭代-字节数组将是即时查找


希望这对您足够详细。:-)

从我读到的四叉树来看,更新它们似乎很昂贵。因此,如果有任何主动移动的对象,这可能是有问题的,不是吗?这主要取决于世界的稀疏性-如果世界中的对象与空间的比率相当小,那么使用四叉树的好处将超过稍微复杂的更新过程。如果比率很大(因此世界上有大量的对象),那么四叉树就不是理想的解决方案,而另一种表示形式则更理想。我可以为我的具体行为提供细节,但这对其他人来说似乎没有多大用处。我将尝试在这里进一步指定一个好答案的参数…我很感激你的想法!这还不够笼统,不能成为公认的答案,但谢谢分享这个想法。谢谢分享。我已经在做类似的事情了,现在我发现它对于我的目的来说足够有效。