Klye
Klye

Reputation: 104

AS3: Can't get lines to clear

So what I have set up is the pattern unlock screen with the dots and you draw your pattern then the screen unlocks. But the issue is the pattern won't be terminated unless you end the mouse cursor directly on a dot. If you go pass the dot nothing will happen but the lines will stay on the screen and you'll still be at the lock screen. Then the used will have to click to clear the lines and try it again. I've been playing around with it but cant seem to figure out why it's working like this.

Here's the code

package
{
    import flash.display.Sprite;
    import flash.events.MouseEvent;
    import fl.transitions.Tween;
    import fl.transitions.easing.Strong;
    import flash.display.Shape;



    public class Main extends Sprite
    {    
        private var lineContainer:Shape = new Shape();
        private var dots:Array = []; // Stores the in stage movieclips
        private var pattern:Array = []; //The pattern entered by the user 
        private var pass:Array;

        public function Main():void
        {
            dots = [one,two,three,four,five,six,seven,eight,nine]; //add the clips in stage
            pass = [one,four,seven,eight,five,two]; //The correct pattern to proceed
            addChildAt(lineContainer, this.getChildIndex(one)); //the line container right behind the first dot.
            addListeners();
        }

        private function addListeners():void //adds the listeners to each dot
        {
            var dotsLength:int = dots.length;

            for (var i:int = 0; i < dotsLength; i++)
            {
                dots[i].addEventListener(MouseEvent.MOUSE_DOWN, initiatePattern);
                dots[i].addEventListener(MouseEvent.MOUSE_UP, stopPattern); 

            }
        }

        /* Adds a mouse over listener and uses it to add the number of the dot to the pattern */

        private function initiatePattern(e:MouseEvent):void
        {
            pattern = []; //reset array
            lineContainer.graphics.clear(); //clear lines

            for (var i:int = 0; i < dots.length; i++)
            {
                dots[i].addEventListener(MouseEvent.MOUSE_OVER, addPattern);
            }

                    addPattern(e); //trigger the mouse over for this element
        }

        private function addPattern(e:MouseEvent):void
        {
            if (pattern.indexOf(e.currentTarget) == -1) { 
                pattern.push(e.currentTarget); //adds the pattern on mouse over
                drawLines();

                var dot:MovieClip = MovieClip(e.currentTarget);
                if(dot.currentFrame < 2) dot.play(); //play only if on the first frame
            }
        }

        private function drawLines():void {
            lineContainer.graphics.clear(); //clear the current lines
            lineContainer.graphics.lineStyle(5, 0x00FF00); //thickness (8px) and color (green) of the lines

             if (pattern.length > 1) { //don't draw if there aren't at least two dots in the pattern
             lineContainer.graphics.moveTo(pattern[0].x + pattern[0].width * .0, pattern[0].y + pattern[0].height * .0); //move to first
         for (var i:int = 1; i < pattern.length; i++) {
        lineContainer.graphics.lineTo(pattern[i].x + pattern[i].width * .0, pattern[i].y + pattern[i].height * .0); //draw a line to the current dot
    }
          }

              lineContainer.graphics.endFill();

        }

        private function stopPattern(e:MouseEvent):void //stops storing the pattern on mouse up
        {
            for (var i:int = 0; i < dots.length; i++)
            {
                dots[i].removeEventListener(MouseEvent.MOUSE_OVER, addPattern);
                dots[i].gotoAndStop(1); //go back to the first frame
            }

            checkPattern();
        }

        private function checkPattern():void //compares the patterns
        {
            var pLength:int = pass.length;
            var correct:int = 0;

            for (var i:int = 0; i < pLength; i++) //compares each number entered in the user array to the pass array
            {
                if (pass[i] == pattern[i])
                {
                    correct++;
                }
            }

            if (correct == pLength) //if the arrays match
            {
              //Hides Sign In
              MovieClip(root).LockScreen.visible = false;
              MovieClip(root).RTID.visible = false;
              MovieClip(root).SignIn.visible = false;
              //Turns On Main Menu
              MovieClip(root).gamemenu_mc.visible = true;
              MovieClip(root).biggamesmenu_mc.visible = true;
              MovieClip(root).totaltextmenu_mc.visible = true;
              MovieClip(root).tmenu_mc.visible = true;
              MovieClip(root).smenu_mc.visible = true;
              MovieClip(root).optionsmenu_mc.visible = true;
            }

            pattern = []; //clears the user array
            lineContainer.graphics.clear(); //clear the lines

        }
    }
}

Upvotes: 0

Views: 132

Answers (2)

BadFeelingAboutThis
BadFeelingAboutThis

Reputation: 14406

All you need to do is add the MOUSE_UP listener on the stage instead of each dot.

  1. Remove this line in the addListeners method:

    dots[i].addEventListener(MouseEvent.MOUSE_UP, stopPattern); 
    
  2. In the initiatePattern method, add this line:

    stage.addEventListener(MouseEvent.MOUSE_UP, stopPattern); 
    
  3. In the stopPattern method, add this line:

    stage.removeEventListener(MouseEvent.MOUSE_UP, stopPattern);
    

Now no matter where to cursor is when you release the mouse (as long as the application has focus), it will stop the pattern.

Also (as per some comments), mouse events work just fine on mobile devices as long as you haven't enabled multitouch.


HERE is what the modified methods should look like now:

    private function addListeners():void //adds the listeners to each dot
    {
        var dotsLength:int = dots.length;

        for (var i:int = 0; i < dotsLength; i++)
        {
            dots[i].addEventListener(MouseEvent.MOUSE_DOWN, initiatePattern);
        }
    }

    /* Adds a mouse over listener and uses it to add the number of the dot to the pattern */

    private function initiatePattern(e:MouseEvent):void
    {
        pattern = []; //reset array
        lineContainer.graphics.clear(); //clear lines

        for (var i:int = 0; i < dots.length; i++)
        {
            dots[i].addEventListener(MouseEvent.MOUSE_OVER, addPattern);
        }

        stage.addEventListener(MouseEvent.MOUSE_UP,stopPattern);
        addPattern(e); //trigger the mouse over for this element
    }

    private function stopPattern(e:MouseEvent):void //stops storing the pattern on mouse up
    {
        for (var i:int = 0; i < dots.length; i++)
        {
            dots[i].removeEventListener(MouseEvent.MOUSE_OVER, addPattern);
            dots[i].gotoAndStop(1); //go back to the first frame
        }

        stage.removeEventListener(MouseEvent.MOUSE_UP,stopPattern);
        checkPattern();
    }

And just for fun, here is a slightly more efficient way to check for the correct pattern.

    private function checkPattern():void //compares the patterns
    {
        var correct:Boolean = true;

        for (var i:int = 0; i < pass.length; i++) //compares each number entered in the user array to the pass array
        {
            if (pattern.length != pass.length || pass[i] != pattern[i]) //this way if they select less than the correct amount of dots, it won't error, and you stop the loop as soon as there's something incorrect
            {
                correct = false;
                break;
            }
        }

        if (correct) //if the arrays match
        {.....

Upvotes: 3

sotrh
sotrh

Reputation: 406

Your only checking the pattern on a MOUSE_UP event. You need to check it in MOUSE_OVER. Add a call to checkPattern() in addPatern().

if (pattern.indexof(e.currentTarget)==-1) {
   patern.push(e.currentTarget);
   drawLines();

   var dot:MovieClip = MovieClip(e.currentTarget);
   if(dot.currentFrame < 2) dot.play();

   checkPattern(); // <---
}

As the user moves the mouse over the dots, the program calls addPatern() which then checks the pattern to see if it is correct. (aka. if (correct=pLength))

EDIT:

You need to put the call to clear the lines and the pattern in the if statement where you actually check if the pattern is correct. That's why the lines aren't rendering.

if (correct==pLength)
{
  ...

  // Set pattern to [], clear screen, etc.
}

Upvotes: 1

Related Questions