Detecting mouse gestures in Flash with AS3 – Fixed
Talking about Actionscript 3 and Flash.
This is the reprise of an old post about detecting mouse gestures. Since I am making a quick game for my daughter using mouse (or finger gestures), I took the old algorithm and fixed a bug which prevented to correctly detect the up-right movement. Moreover, I optimized a bit the cde to avoid small movement detection.
This is the resut, draw something in the upper left sector:
The theory is fully explained in the original post, at the moment I am optimizing the code zooming the filtered mouse movement in order to achieve more precision when the user draws tiny lines.
This is the source code:
package { import flash.display.Sprite; import flash.events.MouseEvent; import flash.events.Event; import flash.text.TextField; public class Main extends Sprite { private var drawing:Boolean=false; private var freeMouse:Sprite=new Sprite(); private var stepMouse:Sprite=new Sprite(); private var dirMouse:Sprite=new Sprite(); private var pX,pY,pX2,pY2:int; private var directions:TextField=new TextField(); private var lastDirection:Number; private var currentDirection:Number=-1; public function Main():void { graphics.lineStyle(4,0x000000); graphics.moveTo(320,0); graphics.lineTo(320,480); graphics.moveTo(0,240); graphics.lineTo(640,240); addChild(freeMouse); addChild(stepMouse); addChild(dirMouse); addChild(directions); stepMouse.x=320; dirMouse.y=240; directions.x=320; directions.y=240; directions.height=240; addEventListener(Event.ENTER_FRAME,update); stage.addEventListener(MouseEvent.MOUSE_DOWN,startDrawing); stage.addEventListener(MouseEvent.MOUSE_UP,stopDrawing); } private function startDrawing(e:MouseEvent):void { if (! drawing) { directions.text=""; lastDirection=-1; drawing=true; freeMouse.graphics.clear(); freeMouse.graphics.lineStyle(1,0x0000ff); freeMouse.graphics.moveTo(mouseX,mouseY); stepMouse.graphics.clear(); stepMouse.graphics.lineStyle(1,0xff0000); stepMouse.graphics.moveTo(mouseX,mouseY); dirMouse.graphics.clear(); dirMouse.graphics.lineStyle(1,0x00ff00); dirMouse.graphics.moveTo(mouseX,mouseY); pX=pX2=mouseX; pY=pY2=mouseY; } } private function stopDrawing(e:MouseEvent):void { drawing=false; } private function update(e:Event):void { if (drawing) { freeMouse.graphics.lineTo(mouseX,mouseY); var dX=pX-mouseX; var dY=pY-mouseY; var distance:Number=dX*dX+dY*dY; if (distance>400) { stepMouse.graphics.lineTo(mouseX,mouseY); var angle:Number=Math.atan2(dY,dX)*57.2957795; var refinedAngle:Number; var directionString:String; if (angle>=22*-1&&angle<23) { refinedAngle=0; directionString="Left\n"; } if (angle>=23&&angle<68) { refinedAngle=Math.PI/4; directionString="Up Left\n"; } if (angle>=68&&angle<113) { refinedAngle=Math.PI/2; directionString="Up\n"; } if (angle>=113&&angle<158) { refinedAngle=Math.PI/4*3; directionString="Up Right\n"; } if (angle>=158||angle<157*-1) { refinedAngle=Math.PI; directionString="Right\n"; } if (angle>=157*-1&&angle<112*-1) { refinedAngle=- Math.PI/4*3; directionString="Down Right\n"; } if (angle>=112*-1&&angle<67*-1) { refinedAngle=- Math.PI/2; directionString="Down\n"; } if (angle>=67*-1&&angle<22*-1) { refinedAngle=- Math.PI/4; directionString="Down Left\n"; } pX2-=Math.sqrt(distance)*Math.cos(refinedAngle); pY2-=Math.sqrt(distance)*Math.sin(refinedAngle); if (refinedAngle!=lastDirection) { lastDirection=refinedAngle; } else { if (currentDirection!=lastDirection) { directions.appendText(directionString); currentDirection=lastDirection; } } dirMouse.graphics.lineTo(pX2,pY2); pX=mouseX; pY=mouseY; } } } } }
As always you can download the source code. Next time, optimized gesture detection, plus the capability of recognizing simple shapes.
Never miss an update! Subscribe, and I will bother you by email only when a new game or full source code comes out.