- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
想象一个具有较大游戏区域的 2D 游戏,比如 10000x10000 像素。现在想象有成千上万的物体散布在这个区域。所有对象都在 Z 顺序列表中,因此每个对象相对于其他每个对象都有明确定义的位置,即使它们相距很远。
假设这个游戏区域有一个视口(viewport),显示这个游戏区域的 500x500 区域。显然,如果算法是“对于 Z 顺序列表中的每个对象,如果在视口(viewport)内,则渲染它”,那么您将浪费大量时间迭代远在视口(viewport)之外的所有数千个对象。更好的方法是在视口(viewport)附近或内部维护一个按 Z 顺序排列的对象列表。
如果对象和视口(viewport)都在移动,那么维护候选绘制对象的 Z 顺序列表的有效方法是什么?这是针对通用游戏引擎的,因此没有太多其他假设或细节可以添加以利用:问题几乎就是这样。
最佳答案
你不需要保持你的内存布局按 Z 强烈排序。相反,你需要将你的对象存储在一个沿着观察表面定向的空间分区结构中。
一个典型的分区结构,是二维的四叉树。您可以使用二叉树,可以使用网格,也可以使用空间散列方案。您甚至可以混合使用这些技术并将它们相互结合。
没有“最好”之分,但您可以权衡编写代码和维护代码的难易程度。还有你可用的内存。
让我们考虑一下网格,它实现起来最简单,访问速度最快,也最容易遍历。 (遍历就是去邻域单元格的事实)
想象一下,考虑到单元格内容只是一个小对象(如 std::vector 或 c# 列表),比如 50 字节,您允许自己为网格骨架使用 20MB 的 RAM。对于 10k 像素的正方形表面,您将拥有:
sqrt(20*1024*1024 / 50) = 647
一维有 647 个单元格,因此 10k/647 = 15 像素宽的单元格。
仍然很小,所以我想完全可以接受。例如,您可以调整数字以获得 512 像素的单元格。当几个单元格适合视口(viewport)时,它应该是一个很好的适合。
然后,通过将左上角除以单元格的大小和结果的底板,可以很容易地确定视口(viewport)激活了哪些单元格,这会直接在单元格中为您提供索引。 (前提是您的视口(viewport)空间和网格空间都从 0,0 开始。否则您需要偏移)
最后取右下角,确定单元格的网格坐标;您可以在最小值和最大值之间执行双循环(x 和 y)以迭代激活的单元格。
在处理一个单元格时,您可以通过遍历您之前存放的对象列表来绘制它包含的对象。
当心跨越 2 个或更多单元格的对象。您需要做出选择,或者只存储一次,但随后您的搜索算法将始终需要知道该区域中最大元素的大小,并搜索相邻单元格的列表(通过尽可能远地搜索确保至少覆盖这个最大元素的大小)。
或者,您可以多次存储它(我喜欢的方式),并且只需确保在迭代单元格时,每帧只处理一次对象。这可以通过在对象结构中(作为可变成员)使用帧 ID 轻松实现。
同样的逻辑适用于更灵活的分区,如二叉树。
我的引擎中都提供了实现,请查看代码,它可能会帮助您了解详细信息:http://sourceforge.net/projects/carnage-engine/
关于 Z 排序的最后的话,如果每个 Z 有多个内存存储,那么您已经进行了空间分区,只是没有沿着好的轴。
这可以称为分层。
作为优化,您可以做的不是在您的单元格中存储对象列表,您可以存储(有序的)对象的 map
s 并且它们的键是它们的 Z,因此迭代将沿着Z.
关于performance - 在 2D 游戏的视口(viewport)中有效地检索 Z 排序对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27029763/
我在一个C++程序中找到了一段代码,好像每隔for()循环两次。在这个程序中循环,但为什么在这样的预处理器定义中需要第三个 for 呢? #define for for(int z=0;z<2;++z
我正在尝试分割其中有一个小写字母后跟一个大写字母的文本。 假设文本是: “Įvairių rūšiųSkinti kardeliai” 我想在“ųS”处拆分它,但是以下正则表达式“[ą-ž][Ą-Ž]
这个问题在这里已经有了答案: Reference - What does this regex mean? (1 个回答) 关闭 2 年前。 下面的正则表达式有什么区别。对我来说,它们都是一样的 [
我正在尝试用 Java 编写一个正则表达式: "/[A-Z]{6}-[A-Z]{4}-[A-Z]{4}/" 但是它不起作用。例如 "AASAAA-AAAA-AAAA".matches("/[A-Z]{
我需要确定一个字符串是否是一个变量标识符。 即(a-z,A-Z,,$) 后跟 (a-z,A-Z,0-9,,$) 我知道我可以使用手动配置的 reg exp 来完成它,但必须有一个更紧凑的内置函数我可以
早上好,我是新来的,我带来了一个小问题。我无法针对以下问题开发有效的算法:我需要找到三个正数 x、y 和 z 的组合,以便 x + y、x - y、y + z、y - z、x + z 和 x - z
这个问题已经有答案了: How does the ternary operator work? (12 个回答) 已关闭 6 年前。 我发现了一种不同的返回值的方式,并且很兴奋。它到底是什么意思? 如
我需要以下正则表达式,允许 [a-zA-Z]+ 或 [a-zA-Z]+[ \\-]{0,1}[a-zA-Z]+ 所以我想在 a-zA-Z 字符之间允许无限的减号和空格 示例: sdfsdfdsf-sf
我正在编写一个代码,它以“代码”(编码理论)作为输入,并且我已经计算了它的权重枚举器。我想使用 MacWilliams Identity 找到双代码的权重枚举器. 我有W(z) ,代码的权重枚举器,我
我已经编写了一个 child 文字游戏,现在我正在尝试优化性能。游戏以一种特殊的方式从数据库中挑选关键词,我想做得更好。 给定一个按字母数字排序的 MySQL 关键字字段: keyword s
假设一个字符串是abc/xyz/IMPORTANT/DATA/@#!%@!%,我只想要IMPORTANT/DATA/!%#@%!#% 我对正则表达式很烂,而且真的还没学过 JavaScript API
JS代码: ? 1
大家晚上好我想知道有没有更快的方法来生成以下形式的列表? [a,b,c,…,z] → [[z], [y,z], [x,y,z], … , [a,b,…,y,z]] 我知道切片是最好的方法之一,但没有更
我在 Firefox 和其他浏览器上遇到嵌套 z-index 的问题,我有一个 div,z-index 为 30000,位于 label 下方> zindex 为 9000。我认为这是由 z-inde
我正在尝试制作一个灯泡。这是代码 JSfiddle HTML 查询 $('.button').click(function() { $('#add').show();
在您想将嵌套模块导入命名空间的情况下,我总是这样写: from concurrent import futures 不过,我最近意识到这也可以使用“as”语法来表达。请参阅以下内容: import c
我正在尝试创建一个基本上复制 matlab 命令的函数:[z;-z] 其中 z = randn(m,n) 返回一个 m -by-n 随机条目矩阵。我能够在 C++ 中为下面的 randn 函数创建一个
好吧,我迷失在这些指针中,有人能准确地告诉我 char * x,y,z; 和 char* x,y,z 之间的区别是什么; 和 char (*)x,y,z; ?如果可以,请为您的答案或其他内容提供资源。
这是一道函数依赖题。 我知道当 x->yz 然后 x->y 和 x->z 时。但是上面的依赖关系可能吗? 最佳答案 If xy determines z can x determine z and y
我有一个列表列表 nLedgers - 一个 3D 点云: [nodeID, X, Y, Z] 多行。一些节点将具有相同的 X 和 Y 坐标以及不同的 Z 坐标。 我想首先确定具有相同 X 和 Y 坐
我是一名优秀的程序员,十分优秀!