1

I'm not new to flash, but I'm a bit of a noob with actionscript, trying to build an app in flash pro (or rather, animate cc) which will (hopefully) teach the users music theory (how to read music, etc.). What I want is to have different lessons on separate frames, with separate "screens" which the user can swipe through. I'm using multiple copies of the swipe code which adobe provides in their swipe gallery template.

On frame 5, I use the following:

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

Frame 6 is almost identical, just with different names for variables, functions, etc.:

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

There is also a button as part of the movieclip "lsn112" which is being swiped. Don't know if this is relevant or not, but the code is:

stop();

fwdtest.addEventListener(MouseEvent.CLICK, GoRootNext112);

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

It works fine to a point, but I think an eventlistener is not being removed properly. When the user swipes through the gallery, it works as expected. They can then move onto the next gallery, which also works as expected. No errors so far. However, if they then go back to the menu, and then back to the gallery, I get an error code 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()

What confuses me is that I am using frame 5 at this point, yet I get an error referencing frame 6. It appears to me that flash is attempting to send a gesture to the eventlistener in frame 6, even though I'm on frame 5, which I'm guessing is down to an eventlistener not being removed. However, being new to code, I don't know when to remove the eventlistener without breaking the code.

Here's a link to a zip containing the relevant .fla, .swf and .xml files. http://speedy.sh/5JP7c/MusicTheorySwipe.zip

As this is the method I would like to use over many, many frames, I would really appreciate your time and help in resolving this.

EDIT

Ok, I've simplified the code as best I can, to try and eliminate any suspects.

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

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

And that's all the actionscript there is now, yet it's still not working. Any ideas?

Nick Scott
  • 11
  • 4
  • 1
    You've defined a listener TransformGestureEvent.GESTURE_SWIPE on frame 5 and then on frame 6. Once you reach on frame6 both will start executing. You need to remove those once you dont need them – Sameer Kumar Jain Apr 11 '16 at 06:04
  • Yeah, I'd figured it was something to do with an eventlistener, I was just focusing on the wrong one for some reason. Thanks for the tip. – Nick Scott Apr 11 '16 at 07:49

2 Answers2

0

On frame 2 when you switch to frame 6 check if stage has the event listener fl_SwipeToGoToNextPreviousFrameA() and if so remove it. That should fix your error.

Snukus
  • 1,302
  • 9
  • 17
  • Thanks Snukus. I've tested a removeEventListener, which resolves the error message, but now when I get to the next frame, even though the code is fine, the swipe gesture doesn't work. Any ideas why? I'd also like to use buttons within the movieclip that's being moved by the swipe gesture to navigate to the next frame or to other frames on the main timeline. I know how to do this with `MovieClip(root).nextFrame();`, but I need to remove the event listener before I leave the frame, and I don't know how to do that, as I just get a 1120 Access of Undefined Property whatever I try. – Nick Scott Apr 11 '16 at 07:58
  • Did you remove both SwipeToGoToNextPreviousFrameA and B? If so the swipe won't work anymore. You need to remove A when you leave frame 6 and remove B when you leave frame 5. – Snukus Apr 11 '16 at 11:16
  • Swipe works great on frame 5, but once taken to frame 6, it no longer works. I've added: `if(currentGalleryItem == totalGalleryItems){ stage.removeEventListener(TransformGestureEvent.GESTURE_SWIPE , onSwipe113); nextFrame() }` So if the user swipes towards the left, and there's no more of the movieclip to scroll to the left, it takes the user to the next frame. It works, and I don't get any error reported. However, in the next frame, the swipe function doesn't work, even though I've added a new eventListener to the stage. – Nick Scott Apr 11 '16 at 12:00
  • `gotoAndStop` and `Stop()` - do they affect the running of scripts? I don't think so, but I'm running out of ideas... – Nick Scott Apr 11 '16 at 12:06
0

You need to remove the listener at couple of frames.

Write these lines on frame2 after all of your code

stage.removeEventListener (TransformGestureEvent.GESTURE_SWIPE, fl_SwipeToGoToNextPreviousFrameA);

stage.removeEventListener (TransformGestureEvent.GESTURE_SWIPE, fl_SwipeToGoToNextPreviousFrameB);

Write this line on frame5 before you define listener

stage.removeEventListener (TransformGestureEvent.GESTURE_SWIPE, fl_SwipeToGoToNextPreviousFrameA);

Write this line on frame6 before you define listener

stage.removeEventListener (TransformGestureEvent.GESTURE_SWIPE, fl_SwipeToGoToNextPreviousFrameB);

and remove both from any other frame you can jump from frame5 and frame6.

Sameer Kumar Jain
  • 2,074
  • 1
  • 13
  • 22
  • I had suspected that might be the case, but I just tried that and it didn't work. I don't know if it's the addEventListener or the removeEventListener which isn't working, but for some reason it works on frame 1, but not frame 2. – Nick Scott Apr 11 '16 at 13:08
  • What do you mean work on frame 1 and dont work on frame 2? – Sameer Kumar Jain Apr 11 '16 at 13:09
  • Sorry, I mean the swipe gesture works on frame ***5*** but not on frame 6. – Nick Scott Apr 11 '16 at 13:18
  • Make sure all your enterframe also removed. and run trace on frame5 listenre function so you know if that is still executing. May be put trace on all of your methods on frame5 and frame 6 and you will know what going on. – Sameer Kumar Jain Apr 11 '16 at 13:23
  • I haven't specified any enterframes. Is that something I need to fix? I know the trace function but not sure how I'd use it in this situation. I tried `trace(stage.EventListener)` but got an error: _Scene 1, Layer 'Actions', Frame 2, Line 30, Column 13 1119: Access of possibly undefined property EventListener through a reference with static type flash.display:Stage. _ – Nick Scott Apr 11 '16 at 13:46
  • inside fl_SwipeToGoToNextPreviousFrameB method put this line trace("Frame5::fl_SwipeToGoToNextPreviousFrameB") – Sameer Kumar Jain Apr 11 '16 at 13:47
  • Ok, I added that trace to frame 5 and 6, and frame 5 works fine, displaying "Frame5::fl_SwipeToGoToNextPreviousFrameB" in the output everytime I swipe. Nothing happens to the output when I swipe on frame 6. – Nick Scott Apr 11 '16 at 20:03
  • How are you testing? – Sameer Kumar Jain Apr 11 '16 at 20:35
  • I'm just ctrl+Enter-ing to test movie. I've also tried ctrl+shift+Enter for debug mode, but both give identical results. I'm also not familiar with debug mode, so I can't guarantee I'm using it to its fullest. – Nick Scott Apr 11 '16 at 21:53
  • Ok, in recent testing, swipe functionality sometimes returns after a delay if I fiddle about with "touch layer", "relocate" and clicking on the screen. I can't sem to be able to replicate it accurately. Sometimes it comes back quickly, sometimes apparently not at all. Not sure what's causing the return of the functionality, or the lack of it. – Nick Scott Apr 11 '16 at 22:14
  • @NickScott I mean are you testing in real device because I don't think you can test swipe on PC using touch layer twice. It work only once for me. But if you test in actual device both frame must work – Sameer Kumar Jain Apr 12 '16 at 04:55