我有一个Character对象数组(扩展Sprite)。
public static var charlist:Array;
当一个角色死亡时,我会设置一个标志来表示。
char.die = true;
当我产生一个新玩家时,我会检查这个标志,重新使用该插槽。这就是问题所在。 最好的方法是什么?其实我有这种方法:
char = new Char();
/* ... */
for (var i:Number = 0; i < Char.charlist.length; i++) {
if (Char.charlist[i].death) {
Char.charlist[i] = char;
return;
}
}
但问题是我来自C ++,我认为每次迭代计算索引都是浪费 我会这样做,但这在AS3中不起作用,因为我无法通过引用访问项目:
char = new Char();
/* ... */
for (var i:Number = 0; i < Char.charlist.length; i++) {
var char_it:Char = Char.charlist[i];
if (char_it.death) {
char_it = char;
return;
}
}
注意:charlist是Char类的静态成员。
您有任何想法或更好的方法吗?
谢谢!
答案 0 :(得分:2)
我认为“优化”版本的优化程度不高。
您的代码在每次迭代中都不会执行2次访问。当你碰巧找到一个死的Char时它就会发生;然后你回来了。所以,我认为没什么大不了的。
就个人而言,我认为重用阵列插槽也不会产生很大的影响。并且,它可能会降级(但最糟糕的是,如果你避免它,你的代码会更简单)。假设你有100个字符,其中60个已经死了,你有一个循环,每个帧运行并对每个实时字符执行一些检查/操作。你可以循环超过100个字符,如果你保留了一个活动对象列表和一个死对象的separte列表,你可以循环超过40个字符,准备重用它们。此外,“死列表”可以作为堆栈处理,因此不需要迭代来获取char。
无论如何,我看到你可以在代码中轻松优化的两件事:
1)检索循环外的列表长度:
这样做:
var len:int = Char.charlist.length;
for (var i:Number = 0; i < len; i++) {
而不是:
for (var i:Number = 0; i < Char.charlist.length; i++) {
编译器不会优化调用长度(遵循ecmascript规范)。
2)避免静态访问(对于charlist)。众所周知,它比实例访问慢得多。
修改强>
重新阅读你的问题,我意识到我误解了它的一部分。您不是要重用Char对象,而是重用阵列插槽。不过,我不认为重用数组插槽是值得的(Actionscript中的数组是不固定的);但是可以帮助提高性能的东西就是重用Char对象本身。重新设置Sprite通常比创建一个Sprite便宜。 您可以通过一组“死”对象来管理它,您可以从中获取一个并在需要时“恢复生命”,而不是创建一个新对象。
这篇文章讨论了对象池(博客本身是Actionscript的一个很好的来源,特别是对于性能和数据结构主题;值得一看):
答案 1 :(得分:0)
为什么不使用列表而不是数组,只需从列表中删除死的列表并在需要时添加新的列表?
是否有充分理由尝试重复使用插槽?
你想要优化什么?
答案 2 :(得分:0)
有没有理由你不能拼出所需的角色并将新角色推到阵列上?
var characters:Array = ["leo", "raph", "don", "mike"];
characters.splice(1, 1);
trace(characters);
characters.push("splinter");
trace(characters);
如果您正在通过引用查找存储,请检查AS3的Dictionary
对象,甚至是Flash 10的Vector(如果存储类型一致;速度非常快):
http://www.gskinner.com/blog/archives/2006/07/as3_dictionary.html