Событие не удаляется из слушателя в AS3 - PullRequest
0 голосов
/ 15 сентября 2011

Я разрабатываю функцию drag'n'clone для своего флэш-приложения (AS3 и Flash CS5). Клоны созданы идеально, но когда я пытаюсь перетащить недавно созданный клон, приложение создает новый клон (и позволяет мне его перетаскивать).

Я хочу убрать это поведение: только клон следует перетаскивать, а не клонировать. Мой код:

public class Car extends MovieClip
    {

        // imports...

        public function Car()
        {
            addListeners();
        }

        private function addListeners():void
        {
            this.addEventListener(MouseEvent.MOUSE_DOWN,clone);
        }

        private function clone(e:MouseEvent):void
        {
            // Clone the object
            var newcar = new e.target.constructor;
            newcar.graphics.copyFrom(this.graphics);
            newcar.x = this.x;
            newcar.y = this.y;

            this.parent.addChild(newcar);

            newcar.addEventListener(MouseEvent.MOUSE_MOVE,dragCar);
            newcar.addEventListener(MouseEvent.MOUSE_UP,dropCar);
        }

        private function dragCar(e:MouseEvent):void
        {
            e.target.startDrag();
        }

        private function dropCar(e:MouseEvent):void
        {
            e.target.stopDrag();

                    // This line doesn't remove the event, and I don't know why
            e.currentTarget.removeEventListener(MouseEvent.MOUSE_DOWN,clone);

            e.target.removeEventListener(MouseEvent.MOUSE_MOVE, dragCar);
            e.target.removeEventListener(MouseEvent.MOUSE_UP,dropCar);

        }

    }

Я надеюсь, что кто-то может мне помочь. Спасибо!

1 Ответ

1 голос
/ 15 сентября 2011

Здесь, когда вы создаете новый экземпляр Car в функции клона, вызывается конструктор этого нового объекта Car, который, в свою очередь, вызывает addListeners(), и у клона есть прослушиватель событий MOUSE_DOWN, который снова клонирует клон.Вот почему у вас есть проблема, которую вы описываете.

Чтобы избежать этого, вам нужно добавить следующую строку в вашу функцию клонирования ( это не работает, см. Ниже edit )

newcar.removeEventListener(MouseEvent.MOUSE_DOWN,clone);

это удаляет слушателя события клонирования из клонированного (нового) экземпляра Car и избегает клонирования снова.

Также, чтобы начать перетаскивание, вы должны сделать это в MOUSE_DOWN вместо MOUSE_MOVE.

Обновление
ОК. Понятно, MOUSE_DOWN снова не вызывается для клона, поэтому вам нужно использовать MOUSE_MOVE.Таким образом, в этом случае я бы удалил слушателя MOUSE_MOVE из тела слушателя так, чтобы он вызывался только один раз.

Обновление
Это, кажется, удаляет слушателя события.

newcar.removeEventListener(MouseEvent.MOUSE_DOWN, newcar.clone);

Вы должны обратиться к методу клонирования экземпляра newcar newcar.clone, чтобы удалить прослушиватель событий.

Рабочий код
Следующий код работает нормально

package{
    import flash.display.MovieClip;
    import flash.events.*;
    public class Car extends MovieClip
    {
        public function Car()
        {
            addListeners();
        }

        private function addListeners():void
        {
            this.addEventListener(MouseEvent.MOUSE_DOWN,clone);
        }

        private function clone(e:MouseEvent):void
        {
            // Clone the object
            var newcar = new e.target.constructor;
            newcar.graphics.copyFrom(this.graphics);
            newcar.x = this.x;
            newcar.y = this.y;

            this.parent.addChild(newcar);

            // remove the clone listener
            newcar.removeEventListener(MouseEvent.MOUSE_DOWN, newcar.clone);

            // add dragging listeners
            newcar.addEventListener(MouseEvent.MOUSE_MOVE, dragCar);
            newcar.addEventListener(MouseEvent.MOUSE_UP, dropCar);

            // this is used for dragging the clone
            newcar.addEventListener(MouseEvent.MOUSE_DOWN, dragCar);
        }

        private function dragCar(e:MouseEvent):void
        {
            // if a MOUSE_MOVE event listener is registered remove it
        if(e.target.hasEventListener(MouseEvent.MOUSE_MOVE))
            e.target.removeEventListener(MouseEvent.MOUSE_MOVE, dragCar);
            e.target.startDrag();
        }

        private function dropCar(e:MouseEvent):void
        {
            e.target.stopDrag();

            // do not remove the listener if you want the clone to be dragable
            // e.target.removeEventListener(MouseEvent.MOUSE_UP,dropCar);
        }
    }
}

Сохранить клон перетаскиваемым
Для этого в приведенном выше коде я добавил прослушиватель событий MOUSE_DOWN для перетаскивания клона

newcar.addEventListener(MouseEvent.MOUSE_DOWN, dragCar);

и прокомментировал e.target.removeEventListener(MouseEvent.MOUSE_UP,dropCar); in dropCar

Также добавлена ​​проверка перед удалением прослушивателя MOUSE_MOVE на предмет наличия или отсутствия, так как эта функция будет позже вызываться MOUSE_DOWN.

...