我有一个2D自上而下的45度游戏,比如口袋妖怪或塞尔达。由于对象的 y 值决定了它的深度,因此需要按其 y 值的顺序绘制对象。因此,例如,当您站在树后时,树会画在玩家的顶部,看起来像您站在树后面。
我目前的设计是画一排牌,然后画站在那一排的任何玩家,然后画下一行,然后画任何站在那边的玩家。这样,任何 y 值高于玩家的图块都会在它们面前绘制以模拟深度。
但是,我的玩家目前是一个对象std::vector
,在绘制完所有瓷砖后,只需迭代和绘制即可。为了使我的方法起作用,我必须迭代每行图块的矢量,并且仅在它们位于当前行时才渲染,或者以某种方式按 y 值对每个玩家进行排序。这两种方法似乎都占用了大量CPU,也许我想多了,在这种类型的游戏中有一种更简单的方法来模拟深度。
编辑:这个游戏是一个MMORPG类型的游戏,所以可能会有很多玩家/NPC四处走动,这就是为什么我需要一种非常有效的方法。
想法或意见将不胜感激!
谢谢
std::set
或std::map
而不是vector
来保持对象的排序顺序。不幸的是,您无法简单地修改它们的位置,每次需要更改y
坐标时都必须删除/插入。
(如果你读过我最初的建议,那就不以为然了;这很愚蠢。
据我所知,你基本上每次渲染帧时都必须迭代一个排序的容器;这将有一个计算惩罚,并且每次都必须做一个副本和排序不会那么糟糕(O(N log N)排序时间,我猜)。
一个聪明的数据结构可能会在这里帮助你;例如,一个包含游戏对象向量的数组作为每个元素。数组的每个元素代表一行平铺网格,您遍历对象向量并将它们装箱到深度缓冲区数组中(这将需要大约 O(N) 时间)。然后只需迭代代表每一行的向量并依次绘制每个对象,再次为 O(N)。
可能有更聪明的 z 缓冲技术,但我会把它们留给读者练习。
只要您不尝试根据其他标准对玩家进行排序,那么每次要遍历玩家时,都可以按 y 坐标对玩家进行排序。 只要您使用在输入大部分排序时以线性时间运行的排序,那么此步骤甚至可能不会产生 O(n log n) 时间。 我在这里假设你的一组玩家变化缓慢,他们的 y 坐标也会缓慢变化。 如果是这种情况,那么每次您需要对向量进行排序时,它都已经大部分排序了,并且像平滑排序或 Tim 排序之类的东西将在线性时间内运行。
对于 c++,看起来你可以在这里找到 Tim 排序的实现。
如果您有空间,另一种选择是创建一个玩家列表数组,数组的索引是行号,数组包含该行中玩家的集合。
正如我所提到的,这将需要一些额外的内存,并且每次玩家移动到不同的行时都会有一些嘘声,但是绘制只是遍历行并绘制该行中存在的玩家的问题。