所以我在AS3中创建了一个僵尸游戏,我创建了一个僵尸精灵阵列。每次启动新波时,它会根据波浪级别创建一定数量的僵尸精灵。这是创建僵尸精灵的功能。
public function spawnZombies(amount:int):void {
for (var spawned:int = 0; spawned < amount; spawned++) {
Stats.zombieAmount += 1;
zombies.push(new CreateZombie("zombie.png", Math.random()*-(Stats.level * 150), gameHeight - 45));
addChild(zombies[zombies.length - 1].spriteObj);
zombies[zombies.length - 1].spriteObj.addEventListener(MouseEvent.CLICK, function killed(evt:MouseEvent):void {
Stats.zombieAmount -= 1;
Stats.money += 1;
moneyText.displayText.text = "$" + Stats.money;
trace(zombies.indexOf(evt.currentTarget));
removeChild(evt.currentTarget as Sprite);
zombies[zombies.indexOf(evt.currentTarget as Sprite)] = null;
});
}
}
现在这一切都很好,但是我遇到了eventListiner
的问题,我正在添加到我创建的每个精灵中。问题在于以下几行代码:
trace(zombies.indexOf(evt.currentTarget)); //Returns -1
removeChild(evt.currentTarget as Sprite); //Works fine
zombies[zombies.indexOf(evt.currentTarget as Sprite)] = null; //Sets -1 in list to null, not what I want!
问题在于使用目标找到精灵的索引,它似乎永远找不到它,并且总是返回-1;如果有人有任何想法,请帮忙!
答案 0 :(得分:1)
您的直接问题是,您将CreateZombie
实例存储在zombies
数组中,但您的点击侦听器正被添加到spriteObj
这是CreateZombie实例的属性添加到数组中。
这意味着在您的点击处理程序中,evt.currentTarget
是对spriteObj
的引用,而不是CreateZombie
实例。因此,当您执行indexOf时,在数组中找不到它。
看起来spriteObj
中没有引用它产生的CreateZombie
对象。所以你可能不得不求助于遍历整个数组,试图找到与spriteObj一起使用的Zombie。
function getZombieForSprite(spriteObj){
for(var i:int=0;i<zombies.length;i++){
if(zombies[i].spriteObj === spriteObj) return zombies[i];
}
return null;
}
如果spriteObj
是自定义类,那么为它提供一个引用它来自的CreateZombie
obj的属性可能会更容易。
或者,如果CreateZombie只是名称所建议的工厂方法,只需将spriteObj
存储在zombies
数组中。
现在,作为避免内存泄漏的提示,您应该使点击监听器变弱:addEventListener(MouseEvent.CLICK, handler, false, 0, true);
(最后一个参数是弱标志)。或者在你杀死僵尸时显式删除该事件监听器。如果不这样做,该事件监听器将把对象保留在内存中,即使在您杀死它并删除了对它的所有其他引用之后。