безопасно уберите ребенка с работающим энтерфреймом - PullRequest
0 голосов
/ 22 октября 2011

Всякий раз, когда я пытаюсь удалить объект / дочерний объект с запущенным enterframe, я всегда получаю нулевую ссылку. В моем конкретном случае, установка Battlefield содержит много роботов:

  1. Дочерняя (робот) отправка, даже если она уничтожена
  2. Родительский контейнер получает событие и начинает удалять дочерний элемент с помощью removeChild и удаляет дочерний элемент из массива роботов.
  3. на enterframe, во время цикла для перемещения роботов, иногда я получаю нулевую ссылку, поэтому мне нужно позвонить, если (robots [i] == null) продолжится;

Как безопасно удалить ребенка, не посыпая его, если робот не работает во всем моем компьютере?

Одна из идей, которые у меня есть, состоит в том, чтобы иметь список роботов, которые должны быть удалены внутри энтерфрейма, который проверяет, есть ли робот, которого нужно удалить, и, если он есть, выполняет удаление вместо обратного вызова при событии разнесенного робота.

Ответы [ 3 ]

1 голос
/ 22 октября 2011

Обычно я делаю две вещи:

1) В объекте обновляется active bool.Когда вы вызываете функцию destroy() или что-либо еще для очистки, установите active на false.В функции update() проверьте при запуске.если active равно false, выйдите из системы.

2) Имейте свойство removeFromUpdate, для которого установлено значение true, если вы хотите удалить свой объект.В вашем UpdateManager (или как называется update() на ваших объектах) сделайте что-то вроде этого:

private function _update():void
{
    // update our objects
    var remove:Boolean = false;
    var len:int = this.m_objects.length;
    for( var i:int = 0; i < len; i++ )
    {
        this.m_objects[i].update();
        if( this.m_objects[i].removeFromUpdate )
            remove = true;
    }

    // if we don't have anything to remove, quit
    if( !remove )
        return;

    // we have something to remove, so traverse the array
    // backwards (so we don't have index problems)
    for( i = len - 1; i >= 0; i-- )
    {
        if( this.m_objects[i].removeFromUpdate )
        {
            // you can optionally call the object's destroy() function
            // here

            // splice the array
            this.m_objects.splice( i, 1 );
        }
    }
}

Это в значительной степени работает для меня.При желании вы можете сделать так, чтобы функция update() объекта возвращала true, если она должна быть удалена, если вы хотите сохранить параметр

1 голос
/ 23 октября 2011

Ну, для одного в haXe Array на самом деле имеет remove -метод. Вы можете использовать это, чтобы удалить роботов навсегда. Метод также сообщает о своем успехе, поэтому ваш код будет выглядеть примерно так:

if (robotsArray.remove(explodedRobot)) 
    robotsLayer.removeChild(explodedRobot)

Обратите внимание, однако, что вызов remove для Array не должен происходить, пока он повторяется, иначе вы наверняка получите странное поведение.

0 голосов
/ 22 октября 2011

Я пока не могу оставлять комментарии, так что придется делать это так.

Две вещи, о которых я могу подумать: вы говорите, что удалили ребенка из списка роботов.Так что кажется странным, что вы встречаете нулевые значения в списке;разве в реализации удаления есть ошибка?

Возможно ли, что внутри ENTER_FRAME при прохождении через роботов экземпляры робота удаляются?Если это так, это может помочь, если вы пройдете через список, начиная с последнего индекса.Если экземпляр удаляется, он не изменит элементы с более низким индексом.

Что-то вроде:

for(var index: int = list.length; index--; ) doSomething(list[index]);
...