开发者问题收集

在 ActionScript 中删除事件监听器的问题

2016-04-10
150

我对 Flash 并不陌生,但对 ActionScript 有点菜鸟,尝试在 Flash Pro(或者更确切地说是 Animate CC)中构建一个应用程序,该应用程序将(希望)教授用户音乐理论(如何读乐谱等)。我想要的是将不同的课程放在不同的帧上,并设置单独的“屏幕”,用户可以滑动浏览。我使用了 Adob​​e 在其滑动图库模板中提供的滑动代码的多个副本。

在第 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: Error #1009: Cannot access a property or method of a null object reference. at MusicTheorySwipe_fla::MainTimeline/slideRightA()[MusicTheorySwipe_fla.MainTimeline::frame6:32] at MusicTheorySwipe_fla::MainTimeline/fl_SwipeToGoToNextPreviousFrameA()[MusicTheorySwipe_fla.MainTimeline::frame6:16] at runtime::ContentPlayer/simulationSendGestureEvent() at runtime::SimulatedContentPlayer/clientSocketDataHandler()

让我感到困惑的是,我此时正在使用第 5 帧,但我收到引用第 6 帧的错误。在我看来,即使我在第 5 帧上,Flash 也试图向第 6 帧中的事件侦听器发送手势,我猜这是由于事件侦听器未被删除。但是,由于我是代码新手,我不知道何时应该在不破坏代码的情况下删除事件监听器。

这是包含相关 .fla、.swf 和 .xml 文件的 zip 链接。 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();

这就是现在所有的操作脚本,但它仍然不起作用。有什么想法吗?

2个回答

在第 2 帧切换到第 6 帧时,检查舞台是否有事件侦听器 fl_SwipeToGoToNextPreviousFrameA(),如果有,则将其删除。这应该可以修复您的错误。

Snukus
2016-04-10

您需要在几帧处移除侦听器。

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);

并从任何其他可以从 frame5 和 frame6 跳转的帧中移除这两者。

Sameer Kumar Jain
2016-04-11