Reputation: 104
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
Reputation: 14406
All you need to do is add the MOUSE_UP
listener on the stage instead of each dot.
Remove this line in the addListeners method:
dots[i].addEventListener(MouseEvent.MOUSE_UP, stopPattern);
In the initiatePattern method, add this line:
stage.addEventListener(MouseEvent.MOUSE_UP, stopPattern);
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
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