Detecting mouse gestures in Flash with AS3

In computing, a pointing device gesture or mouse gesture is a way of combining pointing device movements and clicks which the software recognizes as a specific command.

Pointing device gestures can provide quick access to common functions of a program. They can also be useful for people who have difficulties typing on a keyboard.

For example, in a web browser, the user could navigate to the previously viewed page by pressing the right pointing device button, moving the pointing device briefly to the left, then releasing the button.

(Source: Wikipedia)

What I am try to do is a quick and simple AS3 script able to recognize mouse gestures.

I always start describing the idea and the script, then showing the result.

Today, I’ll start from the result:

As you can see the movie contains four quadrants.

Upper left quadrant: This is the quadrant where you should draw with the mouse: press mouse button and draw while keeping the mouse pressed. As you can see, the blue line represent your mouse movements

Upper right quadrant: The red line represents your filtered mouse movement. I don’t want to keep track of every short movement, so I am showing only movements larger than 20 pixels

Lower left quadrant: The green line represents the evolution of the filtered mouse movement, limiting the possible directions to eight: up, down, left, right and the diagonals

Lower right quadrant: A textual representation of the green line, removing duplicate movements. I mean something like “left left left right” will became “left right”.

Now you can see the code… without comments as it’s just some canvas drawings and I need to add some features during next days.

package {
	import flash.display.Sprite;
	import flash.events.MouseEvent;
	import flash.events.Event;
	import flash.text.TextField;
	public class gesture extends Sprite {
		public var drawing:Boolean=false;
		public var freemouse:Sprite=new Sprite();
		public var stepmouse:Sprite=new Sprite();
		public var dirmouse:Sprite=new Sprite();
		public var the_grid:grid=new grid();
		public var px,py,px2,py2:int;
		public var directions:TextField=new TextField();
		public var latest_direction:Number;
		public function gesture():void {
			addChild(the_grid);
			addChild(freemouse);
			addChild(stepmouse);
			addChild(dirmouse);
			addChild(directions);
			stepmouse.x=250;
			dirmouse.y=200;
			directions.x=250;
			directions.y=200;
			directions.height=200;
			addEventListener(Event.ENTER_FRAME,on_enter_frame);
			stage.addEventListener(MouseEvent.MOUSE_DOWN,on_mouse_down);
			stage.addEventListener(MouseEvent.MOUSE_UP,on_mouse_up);
		}
		public function on_mouse_down(e:MouseEvent):void {
			if (! drawing) {
				directions.text="";
				latest_direction=-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;
			}
		}
		public function on_mouse_up(e:MouseEvent):void {
			drawing=false;
		}
		public function on_enter_frame(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 refined_angle:Number;
					var string_dir:String;
					if (angle>=22*-1&&angle<23) {
						refined_angle=0;
						string_dir="Left\n";
					}
					if (angle>=23&&angle<68) {
						refined_angle=Math.PI/4;
						string_dir="Up Left\n";
					}
					if (angle>=68&&angle<113) {
						refined_angle=Math.PI/2;
						string_dir="Up\n";
					}
					if (angle>=113&&angle<158) {
						refined_angle=Math.PI/4*3;
						string_dir="Up Right\n";
					}
					if (angle>=135||angle<157*-1) {
						refined_angle=Math.PI;
						string_dir="Right\n";
					}
					if (angle>=157*-1&&angle<112*-1) {
						refined_angle=- Math.PI/4*3;
						string_dir="Down Right\n";
					}
					if (angle>=112*-1&&angle<67*-1) {
						refined_angle=- Math.PI/2;
						string_dir="Down\n";
					}
					if (angle>=67*-1&&angle<22*-1) {
						refined_angle=- Math.PI/4;
						string_dir="Down Left\n";
					}
					px2-=Math.sqrt(distance)*Math.cos(refined_angle);
					py2-=Math.sqrt(distance)*Math.sin(refined_angle);
					if (refined_angle!=latest_direction) {
						directions.appendText(string_dir);
						latest_direction=refined_angle;
					}
					dirmouse.graphics.lineTo(px2,py2);
					px=mouseX;
					py=mouseY;
				}
			}
		}
	}
}

Now you are almost ready to use mouse gestures in your code... you just should add some Levenshtein distance adjustment and you're done... I'll show you how to do this next time. Do you already have a clue?

Download the source code.

Get the most popular Phaser 3 book

Through 202 pages, 32 source code examples and an Android Studio project you will learn how to build cross platform HTML5 games and create a complete game along the way.

Get the book

215 GAME PROTOTYPES EXPLAINED WITH SOURCE CODE
// 1+2=3
// 100 rounds
// 10000000
// 2 Cars
// 2048
// A Blocky Christmas
// A Jumping Block
// A Life of Logic
// Angry Birds
// Angry Birds Space
// Artillery
// Astro-PANIC!
// Avoider
// Back to Square One
// Ball Game
// Ball vs Ball
// Ball: Revamped
// Balloon Invasion
// BallPusher
// Ballz
// Bar Balance
// Bejeweled
// Biggification
// Block it
// Blockage
// Bloons
// Boids
// Bombuzal
// Boom Dots
// Bouncing Ball
// Bouncing Ball 2
// Bouncy Light
// BoxHead
// Breakout
// Bricks
// Bubble Chaos
// Bubbles 2
// Card Game
// Castle Ramble
// Chronotron
// Circle Chain
// Circle Path
// Circle Race
// Circular endless runner
// Cirplosion
// CLOCKS - The Game
// Color Hit
// Color Jump
// ColorFill
// Columns
// Concentration
// Crossy Road
// Crush the Castle
// Cube Jump
// CubesOut
// Dash N Blast
// Dashy Panda
// Deflection
// Diamond Digger Saga
// Don't touch the spikes
// Dots
// Down The Mountain
// Drag and Match
// Draw Game
// Drop Wizard
// DROP'd
// Dudeski
// Dungeon Raid
// Educational Game
// Elasticity
// Endless Runner
// Erase Box
// Eskiv
// Farm Heroes Saga
// Filler
// Flappy Bird
// Fling
// Flipping Legend
// Floaty Light
// Fuse Ballz
// GearTaker
// Gem Sweeper
// Globe
// Goat Rider
// Gold Miner
// Grindstone
// GuessNext
// Helicopter
// Hero Emblems
// Hero Slide
// Hexagonal Tiles
// HookPod
// Hop Hop Hop Underwater
// Horizontal Endless Runner
// Hundreds
// Hungry Hero
// Hurry it's Christmas
// InkTd
// Iromeku
// Jet Set Willy
// Jigsaw Game
// Knife Hit
// Knightfall
// Legends of Runeterra
// Lep's World
// Line Rider
// Lumines
// Magick
// MagOrMin
// Mass Attack
// Math Game
// Maze
// Meeblings
// Memdot
// Metro Siberia Underground
// Mike Dangers
// Mikey Hooks
// Nano War
// Nodes
// o:anquan
// One Button Game
// One Tap RPG
// Ononmin
// Pacco
// Perfect Square!
// Perfectionism
// Phyballs
// Pixel Purge
// PixelField
// Planet Revenge
// Plants Vs Zombies
// Platform
// Platform game
// Plus+Plus
// Pocket Snap
// Poker
// Pool
// Pop the Lock
// Pop to Save
// Poux
// Pudi
// Pumpkin Story
// Puppet Bird
// Pyramids of Ra
// qomp
// Quick Switch
// Racing
// Radical
// Rebuild Chile
// Renju
// Rise Above
// Risky Road
// Roguelike
// Roly Poly
// Run Around
// Rush Hour
// SameGame
// SamePhysics
// Save the Totem
// Security
// Serious Scramblers
// Shrink it
// Sling
// Slingy
// Snowflakes
// Sokoban
// Space Checkers
// Space is Key
// Spellfall
// Spinny Gun
// Splitter
// Spring Ninja
// Sproing
// Stabilize!
// Stack
// Stairs
// Stick Hero
// String Avoider
// Stringy
// Sudoku
// Super Mario Bros
// Surfingers
// Survival Horror
// Talesworth Adventure
// Tetris
// The Impossible Line
// The Moops - Combos of Joy
// The Next Arrow
// Threes
// Tic Tac Toe
// Timberman
// Tiny Wings
// Tipsy Tower
// Toony
// Totem Destroyer
// Tower Defense
// Trick Shot
// Tunnelball
// Turn
// Turnellio
// TwinSpin
// vvvvvv
// Warp Shift
// Way of an Idea
// Whack a Creep
// Wheel of Fortune
// Where's my Water
// Wish Upon a Star
// Word Game
// Wordle
// Worms
// Yanga
// Yeah Bunny
// Zhed
// zNumbers