Проблема с удалением слушателя событий в ActionScript

Я не новичок во flash, но я немного новичок в ActionScript, пытаюсь создать приложение во flash pro (или, скорее, анимировать cc), которое (надеюсь) научит пользователей теории музыки (как читать музыку , и т.д.). Я хочу иметь разные уроки на разных фреймах, с отдельными «экранами», по которым пользователь может пролистывать. Я использую несколько копий кода пролистывания, который Adobe предоставляет в своем шаблоне галереи прокрутки.

В кадре 5 я использую следующее:

stop()

Multitouch.inputMode = MultitouchInputMode.GESTURE;

var currentGalleryItem:Number = 1;
var totalGalleryItems:Number = 10;

stage.addEventListener (TransformGestureEvent.GESTURE_SWIPE, fl_SwipeToGoToNextPreviousFrameB);

function fl_SwipeToGoToNextPreviousFrameB(event:TransformGestureEvent):void
{
    if(event.offsetX == 1)
    {
        if(currentGalleryItem > 1){
            currentGalleryItem--;
            slideRight();
        }
    }
    else if(event.offsetX == -1)
    {
        if(currentGalleryItem < totalGalleryItems){
            currentGalleryItem++;
            slideLeft();
        }
    }
}
var slideCounter:Number = 0;
function slideLeft(){
    lsn112.addEventListener("enterFrame", moveGalleryLeft);
}
function slideRight(){
    lsn112.addEventListener("enterFrame", moveGalleryRight);
}

function moveGalleryLeft(evt:Event){
    lsn112.x -= 128;
    slideCounter++;
    if(slideCounter == 10){
        lsn112.removeEventListener("enterFrame", moveGalleryLeft);
        slideCounter = 0;
    }
}
function moveGalleryRight(evt:Event){
    lsn112.x += 128;
    slideCounter++;
    if(slideCounter == 10){
        lsn112.removeEventListener("enterFrame", moveGalleryRight);
        slideCounter = 0;
    }
}

Home112.addEventListener(MouseEvent.CLICK, fl_ClickToGoToAndStopAtFrame_22);

function fl_ClickToGoToAndStopAtFrame_22(event:MouseEvent):void
{
    gotoAndStop(2);
}

stop()

Кадр 6 практически идентичен, только с разными именами переменных, функций и т. Д .:

stop()

Multitouch.inputMode = MultitouchInputMode.GESTURE;

var currentGalleryItemA:Number = 1;
var totalGalleryItemsA:Number = 11;

stage.addEventListener (TransformGestureEvent.GESTURE_SWIPE, fl_SwipeToGoToNextPreviousFrameA);

function fl_SwipeToGoToNextPreviousFrameA(event:TransformGestureEvent):void
{
    if(event.offsetX == 1)
    {
        if(currentGalleryItemA > 1){
            currentGalleryItemA--;
            slideRightA();
        }
    }
    else if(event.offsetX == -1)
    {
        if(currentGalleryItemA < totalGalleryItemsA){
            currentGalleryItemA++;
            slideLeftA();
        }
    }
}
var slideCounterA:Number = 0;
function slideLeftA(){
    lsn113.addEventListener("enterFrame", moveGalleryLeftA);
}
function slideRightA(){
    lsn113.addEventListener("enterFrame", moveGalleryRightA);
}

function moveGalleryLeftA(evt:Event){
    lsn113.x -= 128;
    slideCounterA++;
    if(slideCounterA == 10){
        lsn113.removeEventListener("enterFrame", moveGalleryLeftA);
        slideCounterA = 0;
    }
}
function moveGalleryRightA(evt:Event){
    lsn113.x += 128;
    slideCounterA++;
    if(slideCounterA == 10){
        lsn113.removeEventListener("enterFrame", moveGalleryRightA);
        slideCounterA = 0;
    }
}

Home113.addEventListener(MouseEvent.CLICK, fl_ClickToGoToAndStopAtFrame_23);

function fl_ClickToGoToAndStopAtFrame_23(event:MouseEvent):void
{
    gotoAndStop(2);
}

stop()

Также есть кнопка как часть фрагмента ролика «lsn112», который пролистывается. Не знаю, актуально это или нет, но код такой:

stop();

fwdtest.addEventListener(MouseEvent.CLICK, GoRootNext112);

function GoRootNext112(event:MouseEvent):void
{
    MovieClip(root).nextFrame();
}

В какой-то момент он работает нормально, но я думаю, что прослушиватель событий не удаляется должным образом. Когда пользователь пролистывает галерею, все работает как положено. Затем они могут перейти к следующей галерее, которая также работает должным образом. Пока ошибок нет. Однако, если они затем вернутся в меню, а затем обратно в галерею, я получаю код ошибки 1009:

TypeError: ошибка № 1009: невозможно получить доступ к свойству или методу ссылки на нулевой объект. в MusicTheorySwipe_fla :: MainTimeline / slideRightA () [MusicTheorySwipe_fla.MainTimeline :: frame6: 32] в MusicTheorySwipe_fla :: MainTimeline / fl_SwipeToGoToNextPreviousFrameA () [MusicTheorySwipe_flaureEventFrameA () [MusicTheorySwipe_flaureEvent] (симуляция MusicTheorySwipe_flaure.MainTimes) в время выполнения: фреймSwipe_flaureEvent :: фреймEndtime_flaureEvent :: FrameSwipe_flaureSimulation: 167 : SimulatedContentPlayer / clientSocketDataHandler ()

Что меня смущает, так это то, что я использую кадр 5 в этот момент, но я получаю сообщение об ошибке, ссылаясь на кадр 6. Мне кажется, что flash пытается отправить жест в обработчик событий в кадре 6, хотя я нахожусь на кадре 5 , что, как я предполагаю, связано с тем, что прослушиватель событий не удаляется. Однако, будучи новичком в коде, я не знаю, когда удалить прослушиватель событий без нарушения кода.

Вот ссылка на zip-архив, содержащий соответствующие файлы .fla, .swf и .xml. http://speedy.sh/5JP7c/MusicTheorySwipe.zip

Поскольку это метод, который я хотел бы использовать для многих, многих кадров, я был бы очень признателен за ваше время и помощь в решении этой проблемы.

ИЗМЕНИТЬ

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

Кадр 5:

Multitouch.inputMode = MultitouchInputMode.GESTURE;

stage.addEventListener(TransformGestureEvent.GESTURE_SWIPE , onSwipeA);
var currentGalleryItemA:Number = 1;
var totalGalleryItemsA:Number = 5;
function onSwipeA (e:TransformGestureEvent):void{

//User swiped towards right
if (e.offsetX == 1) {
    if(currentGalleryItemA > 1){
        currentGalleryItemA--;
        lsn113.x += 1280;
    }
}

//User swiped towards left
if (e.offsetX == -1) {
    if(currentGalleryItemA < totalGalleryItemsA){
    currentGalleryItemA++;
    lsn113.x -= 1280;
        if(currentGalleryItemA == totalGalleryItemsA){
        nextFrame()
        }
    }
}
}
stop();

Кадр 6:

stage.removeEventListener(TransformGestureEvent.GESTURE_SWIPE , onSwipeA);

Multitouch.inputMode = MultitouchInputMode.GESTURE;

stage.addEventListener(TransformGestureEvent.GESTURE_SWIPE , onSwipeB);
var currentGalleryItemB:Number = 1;
var totalGalleryItemsB:Number = 11;
function onSwipeB (e:TransformGestureEvent):void{

//User swiped towards right
if (e.offsetX == 1) {
    if(currentGalleryItemB > 1){
        currentGalleryItemB--;
        lsn112.x += 1280;
    }
}

//User swiped towards left
if (e.offsetX == -1) {
    if(currentGalleryItemB < totalGalleryItemsB){
        currentGalleryItemB++;
        lsn112.x -= 1280;
    }
    if(currentGalleryItemB == totalGalleryItemsB){
        nextFrame()
    }
}
}

stop();

И это все, что есть в ActionScript, но он все еще не работает. Любые идеи?


person Nick Scott    schedule 10.04.2016    source источник
comment
Вы определили прослушиватель TransformGestureEvent.GESTURE_SWIPE в кадре 5, а затем в кадре 6. Как только вы дойдете до кадра 6, оба начнут выполнение. Их нужно удалить, если они вам не нужны.   -  person SaachiTech    schedule 11.04.2016
comment
Да, я подумал, что это как-то связано с прослушивателем событий, я просто по какой-то причине сосредоточился не на том. Спасибо за совет.   -  person Nick Scott    schedule 11.04.2016


Ответы (2)


На кадре 2, когда вы переключаетесь на кадр 6, проверьте, есть ли на этапе прослушиватель событий fl_SwipeToGoToNextPreviousFrameA (), и если да, удалите его. Это должно исправить вашу ошибку.

person Snukus    schedule 10.04.2016
comment
Спасибо, Снукус. Я протестировал removeEventListener, который разрешает сообщение об ошибке, но теперь, когда я перехожу к следующему кадру, даже если код в порядке, жест смахивания не работает. Есть идеи, почему? Я также хотел бы использовать кнопки внутри фрагмента ролика, который перемещается жестом смахивания, для перехода к следующему кадру или другим кадрам на основной временной шкале. Я знаю, как это сделать с MovieClip(root).nextFrame();, но мне нужно удалить прослушиватель событий, прежде чем я выйду из кадра, и я не знаю, как это сделать, поскольку я просто получаю 1120 Access of Undefined Property, что бы я ни пробовал. - person Nick Scott; 11.04.2016
comment
Вы удалили как SwipeToGoToNextPreviousFrameA, так и B? Если так, свайп больше не будет работать. Вам нужно удалить A, когда вы покидаете кадр 6, и удалить B, когда вы покидаете кадр 5. - person Snukus; 11.04.2016
comment
Свайп отлично работает с кадром 5, но после перехода к кадру 6 он больше не работает. Я добавил: if(currentGalleryItem == totalGalleryItems){ stage.removeEventListener(TransformGestureEvent.GESTURE_SWIPE , onSwipe113); nextFrame() } Итак, если пользователь проводит пальцем влево и больше нет фрагмента ролика для прокрутки влево, пользователь переходит к следующему кадру. Это работает, и я не получаю сообщений об ошибках. Однако в следующем кадре функция смахивания не работает, хотя я добавил в сцену новый eventListener. - person Nick Scott; 11.04.2016
comment
gotoAndStop и Stop() - влияют ли они на выполнение скриптов? Я так не думаю, но у меня заканчиваются идеи ... - person Nick Scott; 11.04.2016

Вам нужно удалить слушателя на пару кадров.

Напишите эти строки на frame2 после всего кода.

stage.removeEventListener (TransformGestureEvent.GESTURE_SWIPE, fl_SwipeToGoToNextPreviousFrameA);

stage.removeEventListener (TransformGestureEvent.GESTURE_SWIPE, fl_SwipeToGoToNextPreviousFrameB);

Напишите эту строку в frame5, прежде чем определять слушателя.

stage.removeEventListener (TransformGestureEvent.GESTURE_SWIPE, fl_SwipeToGoToNextPreviousFrameA);

Напишите эту строку в frame6, прежде чем определять слушателя.

stage.removeEventListener (TransformGestureEvent.GESTURE_SWIPE, fl_SwipeToGoToNextPreviousFrameB);

и удалите оба из любого другого кадра, который вы можете перепрыгнуть из кадра 5 и кадра 6.

person SaachiTech    schedule 11.04.2016
comment
Я подозревал, что это могло быть так, но я просто попробовал это, и это не сработало. Я не знаю, не работает ли это addEventListener или removeEventListener, но по какой-то причине он работает с кадром 1, но не с кадром 2. - person Nick Scott; 11.04.2016
comment
Что вы имеете в виду: работать с кадром 1 и не работать с кадром 2? - person SaachiTech; 11.04.2016
comment
Извините, я имею в виду, что жест смахивания работает с кадром 5, но не с кадром 6. - person Nick Scott; 11.04.2016
comment
Убедитесь, что весь ваш энтерфрейм также удален. и запустите трассировку функции прослушивания frame5, чтобы знать, выполняется ли она до сих пор. Можно провести трассировку всех ваших методов в кадре 5 и кадре 6, и вы будете знать, что происходит. - person SaachiTech; 11.04.2016
comment
Я не указал никаких энтерфреймов. Это что-то, что мне нужно исправить? Я знаю функцию трассировки, но не знаю, как бы ее использовать в этой ситуации. Я попробовал trace(stage.EventListener), но получил ошибку: _Scene 1, Layer 'Actions', Frame 2, Line 30, Column 13 1119: Доступ к возможно неопределенному свойству EventListener через ссылку со статическим типом flash.display: Stage. _ - person Nick Scott; 11.04.2016
comment
внутри метода fl_SwipeToGoToNextPreviousFrameB поместите эту трассировку строки (Frame5 :: fl_SwipeToGoToNextPreviousFrameB) - person SaachiTech; 11.04.2016
comment
Хорошо, я добавил эту трассировку к кадрам 5 и 6, и кадр 5 работает нормально, отображая Frame5 :: fl_SwipeToGoToNextPreviousFrameB на выходе каждый раз, когда я смахиваю. Когда я смахиваю по кадру 6, с выводом ничего не происходит. - person Nick Scott; 11.04.2016
comment
Как ты тестируешь? - person SaachiTech; 11.04.2016
comment
Я просто ctrl + Enter-ing, чтобы проверить фильм. Я также пробовал ctrl + shift + Enter для режима отладки, но оба дают одинаковые результаты. Я также не знаком с режимом отладки, поэтому не могу гарантировать, что использую его в полной мере. - person Nick Scott; 12.04.2016
comment
Хорошо, в недавнем тестировании функция смахивания иногда возвращается после задержки, если я возился с сенсорным слоем, перемещаюсь и нажимаю на экран. Я не могу точно воспроизвести это. Иногда он возвращается быстро, иногда явно не возвращается. Не уверен, что вызывает возврат функциональности или ее отсутствие. - person Nick Scott; 12.04.2016
comment
@NickScott Я имею в виду, вы тестируете на реальном устройстве, потому что я не думаю, что вы можете дважды протестировать смахивание на ПК, используя сенсорный слой. У меня это сработало только один раз. Но если вы тестируете на реальном устройстве, оба кадра должны работать. - person SaachiTech; 12.04.2016