我正在尝试对使用以下内容添加到数组中的项目数组进行预排序:
draw(texture:LTexture, position:Point, depth:int = 0):void
目前,调用此方法会将纹理添加到队列中。一旦我的队列中的项目准备好呈现,我使用以下内容对我的数组进行排序:
queue.sortOn("depth");
这样可以正常工作,但速度很慢,尤其是当我的队列中有超过2000个纹理被绘制时。
我试图通过在draw()
中添加一些新逻辑来预先输出我的数组。基本上我的队列现在是一个2D数组,其中第一层代表深度,其中的每个数组都包含要绘制的纹理。例如:
queue[1] = [texture, texture];
queue[4] = [texture];
queue[2] = [texture, texture, texture, texture];
然后我有一个将这些数组组合成一个新队列的函数:
function collate():Array
{
var collated:Array = [];
for each(var i:Array in _block)
collated = collated.concat(i);
return collated;
}
这似乎工作正常,但到目前为止存在一些问题:
5
和17
,foreach循环似乎按照它们创建的顺序连接我的内部数组,而不是它们的索引(很奇怪 - 如果我使用更接近的深度,则工作正常)。我怎样才能更好地接近我想要实现的目标?那就是,我希望最终得到一个包含按深度排序的所有纹理的数组。
答案 0 :(得分:2)
虽然我无法想象有2000个纹理被z排序的原因(看起来非常多),但我想出了这些想法:
使用linked list代替数组,让纹理在添加它们时找到各自的位置(add()
每个新纹理到第一个节点,然后让链接节点传递它直到它到达正确深度的位置)。
如果您有时间进入链接列表,这可能是我选择的解决方案,因为它允许您保留现有结构并在它们出现时添加或删除纹理,而无需再次对整个列表进行排序试。
您可以将链表与字典组合:如上所述创建链表,并收集对字典中每个深度的第一个节点的引用(node_dictionary[depth] = node;
)。这样,您可以在给定深度添加()新节点,而不必从列表的开头传递它们。
使用第二个数组仅收集现有的队列索引(每次添加纹理时按下索引)并对该简单数组进行排序以消除空槽。
var index_array : Array = [];
...
queue[17].push(texture);
index_array.push (17);
...
queue[1].push(texture);
index_array.push (1);
...
queue[17].push(texture); // probably more than one texture for each index
index_array.push (17);
index_array.sort(Array.NUMERIC|Array.UNIQUESORT);
var i:int = -1;
while (++i < index_array.length) drawTextures(queue[i]);