as3 Как parent может быть null?

#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. К вашему сведению: это, вероятно, также выявит другую ошибку — пропуск последовательных элементов, которые должны быть удалены из-за изменения массива во время итерации по нему.