#actionscript-3 #parent-child
#actionscript-3 #родитель-потомок
Вопрос:
Я создаю игру Tower Defense, и после того, как башня aoe уничтожает 2 монстров одновременно, я получаю ‘TypeError: ошибка # 1009: не удается получить доступ к свойству или методу нулевого объекта reference…at Document/loop()… в EnemyRed/removeSelf()’
Я использую событие.ВВЕДИТЕ ФУНКЦИЮ_FRAME в классе document, чтобы проверить, является ли (hp монстра < 0), затем вызовите функцию в классе monster, чтобы удалить себя из своего родителя. (Код ниже).
Трассировка показывает, что она пытается удалить один и тот же экземпляр дважды, хотя он уже должен был быть удален из массива.
Класс документа:
public function loop(event:Event):void
{
//If enemy hit points < 0 remove self
if(enemies.length > 0)
{
for(var e = 0; e < enemies.length; e )
{
if(enemies[e].hitPoints <= 0)
{
enemies[e].removeSelf();
Класс монстра:
public function removeSelf():void
{
trace(this.name);
trace(this.parent);
removeEventListener(Event.ENTER_FRAME, loop);
parent.removeChild(this);
Document.enemies.splice(this,1);
}
трассировка возвращает:
Monster: instance2019
Parent: [object Level1]
Monster: instance2019
Parent: null
Ответ №1:
Прошло некоторое время, но я думаю, что это должно быть
public function removeSelf():void {
trace(this.name, this.parent);
if (hasEventListener(Event.ENTER_FRAME)) {
removeEventListener(Event.ENTER_FRAME, loop);
}
if (parent) {
parent.removeChild(this);
}
var index:int = Document.enemies.indexOf(this);
if (index > -1) {
Document.enemies.splice(index,1);
}
}
Теперь экземпляр должен быть правильно удален.
Кроме того, лучше выполнять итерацию enemies
массива в обратном направлении, потому что, когда вы соединяете элемент из массива во время итерации вперед, следующие элементы смещаются на предыдущие позиции, и первый из них не повторяется. Если вы соединяете элемент во время итерации назад, элементы, которые меняют позиции, уже обработаны в этом цикле, поэтому ошибка не возникает. В этом случае ошибка просто приведет к тому, что монстры с 0 HP будут сохраняться несколько кадров, прежде чем будут удалены из массива, но в других случаях это может даже привести к нарушению вашей игры.
for(var e:int = enemies.length-1; e >=0; e--)
{
if(enemies[e].hitPoints <= 0)
{
enemies[e].removeSelf();
Комментарии:
1. К вашему сведению: это, вероятно, также выявит другую ошибку — пропуск последовательных элементов, которые должны быть удалены из-за изменения массива во время итерации по нему.