Tutorials

February 25, 2009

AS3 Character Movement: Follow the Mouse Controls

More articles by »
Written by: Par
Tags: , , , , , , ,
mousecontrols

Share on TwitterShare on TumblrSubmit to StumbleUponSave on DeliciousDigg ThisSubmit to reddit

This is another tutorial in the character movement series. So far on AS Gamer we’ve discussed different ways to move your game’s hero with the keyboard. Today we are going to discuss how to move your player with the mouse. There’s a few ways this can be done, we can set a default speed that our character always moves at or create movement controls where our character eases into the new position. Both movement styles are extremely useful it just depends on which mouse movement method you are wanting to use for your game. First we’re going to talk about controlling the character at a steady speed following our mouse.

You are reading AS3 Character Movement Read more from this series of articles.

Step 1: Getting Started with the Source Code

Okay, so to make sure we are all on the same playing field before we get started, please download the source code here:

Character Movement: Following the Mouse Beginners – Zip Archive

There’s nothing difficult in this zip file.  Only our .fla and two .as files.  Our MouseControlled.fla contains two MovieClips:

  • background – simply a graphic movieclip
  • character – our game character with class linkage to com.asgamer.mousecontrolled.Hero.

The document class is com.asgamer.mousecontrolled.Engine.  As a result our two as files are Hero.as and Engine.as both found in the com/asgamer/mousecontrolled folder.  Now here’s our starting code for each:

Engine.as

package com.asgamer.mousecontrolled
{
 
	import flash.display.MovieClip;
 
	public class Engine extends MovieClip
	{
 
		public function Engine() : void
		{
			var hero:Hero = new Hero(stage);
			addChild(hero);
		}
 
	}
 
}

and Hero.as

package com.asgamer.mousecontrolled
{
 
	import flash.display.MovieClip;
	import flash.events.*;
	import flash.display.Stage;
 
	public class Hero extends MovieClip
	{
 
		var stageRef:Stage;
 
		public function Hero(stageRef:Stage) : void
		{
			x = stageRef.stageWidth/2;
			y = stageRef.stageHeight/2;
 
		}
 
	}
 
}

Okay quick breakdown:

  • Engine simply creates a new instance of our hero class and adds it to the Engine display list. We pass a reference to the stage through to hero.
  • Our hero class excepts the stage as the variable stageRef and then is used to position our hero in the center of the stage.
  • I didn’t remember to apply our stageRef parameter to the stageRef class variable. So go ahead and do it now. Simply add this.stageRef = stageRef; as a line inside our Hero constructor function.

Alright that’s our source code. Let’s do something with it.

Step 2: Making our Character follow the mouse

This is actually incredibly simple and it’s kinda like writing some basic AI. Our character needs to know the location of the mouse, once he knows it then he goes towards it. The only thing complex here is we are using some trig functions, that said, AS3 does all the work for us so we just write a couple lines and everything is working great.

Alright…. I’m going to post an updated version of the Hero code and then I’ll break it down after the fact.

package com.asgamer.mousecontrolled
{
 
	import flash.display.MovieClip;
	import flash.events.*;
	import flash.display.Stage;
 
	public class Hero extends MovieClip
	{
 
		var stageRef:Stage;
		var speed:Number = 10;
 
		public function Hero(stageRef:Stage) : void
		{
			x = stageRef.stageWidth/2;
			y = stageRef.stageHeight/2;
 
			this.stageRef = stageRef;
 
			addEventListener(Event.ENTER_FRAME, loop, false, 0, true);
 
		}
 
		private function loop(e:Event) : void
		{
 
			var yDistance:Number = stageRef.mouseY - y;
			var xDistance:Number = stageRef.mouseX - x;
 
			var radian:Number = Math.atan2(yDistance, xDistance);
			x += Math.cos(radian) * speed;
			y += Math.sin(radian) * speed;
 
		}
 
	}
 
}

The breakdown:

  • var speed:Number = 10; We create a new class variable called speed.  It’s a number and we set it to 10. It’s going to be how fast our hero moves towards the mouse.
  • this.stageRef = stageRef; don’t forget to add this line so we can use our stage reference in our loop function.
  • addEventListener(Event.ENTER_FRAME, loop, false, 0, true); If you have kept up with AS Gamer you have seen this a dozen times… It’s simply each time a frame is displayed (30 frames a second for us) we run the loop function.
  • var yDistance:Number = stageRef.mouseY – y; We’re going to need to know the distance our mouse is from our character. We do this by getting our mouse y position(at the stage) and subtracting it by our Hero’s y position.  We do the same for x.
  • var radian:Number = Math.atan2(yDistance, xDistance); Okay, not complicated so don’t freak out about it. Adobe’s LiveDocs explains Math.atan2 as this: Computes and returns the angle of the point y/x in radians, when measured counterclockwise from a circle’s x axis (where 0,0 represents the center of the circle). But even simpler… Let’s just say it will return is the correct angle in radians that we want our character to move in.
  • x += Math.cos(radian) * speed; So here’s the deal, a cosine and sine always return a number between -1 and 1. If you pass the radian angle we get above into Math.cos it let’s us know how far we need to move in x each frame to move towards our mouse. We can multiple it by speed to increase the amount moved.  Changing our Y value is exactly like changing our X value except we use Math.sin to get the correct value.

Compile your flash and let’s see what you get.

Uhm… it works. But it jitters like crazy when it reaches the mouse. Let’s fix the way we control our hero so that he doesn’t jitter when he reaches the mouse position.

Alright… updated code below:

package com.asgamer.mousecontrolled
{
 
	import flash.display.MovieClip;
	import flash.events.*;
	import flash.display.Stage;
 
	public class Hero extends MovieClip
	{
 
		var stageRef:Stage;
		var speed:Number = 10;
 
		public function Hero(stageRef:Stage) : void
		{
			x = stageRef.stageWidth/2;
			y = stageRef.stageHeight/2;
 
			this.stageRef = stageRef;
 
			addEventListener(Event.ENTER_FRAME, loop, false, 0, true);
 
		}
 
		private function loop(e:Event) : void
		{
 
			var yDistance:Number = stageRef.mouseY - y;
			var xDistance:Number = stageRef.mouseX - x;
 
			if (Math.sqrt(yDistance*yDistance +  xDistance*xDistance) < speed)
			{
				x = stageRef.mouseX;
				y = stageRef.mouseY;
			}
			else
			{
				var radian:Number = Math.atan2(yDistance, xDistance);
				x += Math.cos(radian) * speed;
				y += Math.sin(radian) * speed;
				rotation = radian * 180 / Math.PI;
			}
 
		}
 
	}
 
}

Explaining the source code:

  • if (Math.sqrt(yDistance*yDistance + xDistance*xDistance) < speed). Remember the Pythagorean theorem? Well it is great for game design! Actually anything geometry and trig is excellent for game design. Anyway, this is simply the Pythagorean theorem, to find the distance our hero is from the mouse. Then if it’s less than our speed we…
  • set x = stageRef.mouseX; Why? Because if our speed is greater than our distance our hero will go past our mouse. Then when he tries to turn around and go back to our mouse he goes too far again and misses. So if our character is closer to the mouse than his speed… we just set him to the mouse position.
  • Then we wrap all our old code in an else statement. This just insures that it doesn’t run unless we need it to.
  • rotation = radian * 180 / Math.PI; Let’s say you want your hero to rotate in the direction he is facing. There’s some more details to making this work effectively for a real character (face, eyes, all that) but simply convert your radians to degrees and you’re ready to go. The formula for converting radians to degrees is simply radians * 180 divided by Pi. That’s what we do above.

Here’s that swf.

Alright! It’s finished. Here’s the source code for controlling your character with the mouse:

Character Movement: Following the Mouse Zip Archive

Until next time, go make a game!

Similar Posts:


Share on TwitterShare on TumblrSubmit to StumbleUponSave on DeliciousDigg ThisSubmit to reddit


About the Author

Par
Hey! Don't be surprised, I'm a flash developer. While Flash is definitely one of my favorite languages to develop in, most of all I just like making games. If you want to see the games I've developed so far head over to my website, DigitallyBold, in the link below. If you want to know more about what I'm working on now and in the future be sure to follow me on twitter.




11 Comments


  1. Rajneesh

    Hi, Great Job.

    I like the way of making tutorials as simple as possible.
    I got very much knowledge about game development in AS3.
    Thanks. I will remeber you all the time in my life.
    Keep it up.


  2. pafke

    I wanted to intergrate this in a game, but the game I want to make requires the character to move on a mouseclick. So what I’m looking for is a way to activate this code on a mouseclick, and stop it when the character has reached it’s position. How do I do this?


  3. tutzkie

    ooppppssss… i think i found a way to delete it.. anyway thanks… hehe… nice tutorial… it helped me alot… =D


  4. josh

    Hey, looks good. The only problem I’m having is when I run this in my code it does something different :( It when I have the mouse in the bottom left quadrant (relevant to the object) it just snaps to the mouse position.

    Any ideas?


  5. josh

    nevermind, i was using Math.atan, you’re using Math.atan2 … I didn’t know they performed different calculation :(


  6. The Yellow Flash

    Thank you…. ive used this on my project thanks…


  7. Coco

    Hi, first of all – thanks for the great tutorials:-) I have used to Character Movement: Follow the Mouse Controls.
    But I experienced one problem: I started on a new fla project in CS5 and had the exact same code as you, but I got the error: “1136:Incorrect number of arguments. Expected 0.” for the following line of code in Engine: var hero:Hero = new Hero(stage);
    I tried removing ‘stage’ in Hero() and the error was gone but the ball didn’t move.
    I have also downloaded your files and noticed they are from CS4, so I tried saving my fla file as CS4 and now I didn’t get the error and the ball was moving:-)
    Could this really have been the problem??? I’m not sure…


  8. Vipul Khandelwal

    This is good, but the character do not completing the whole path where mouse moves. so can you please fix it up…..???

    if it is done, that will be be great for me…!!


  9. Tikithehut

    Hi, thanks for the sweet tutorial. Straightforward and gave good insight into mouse controlled character movement.

    I’m running into a strange problem though. The movement stops working when my character actually touches the mouse.Actually, that seems to trigger it most often, but sometimes it will break without the mouse touching it at all.

    Oddly enough while trying to trouble shoot the issue, I set a trace(x) within the enter frame event listener and it fixed the problem completely. I have no idea why. When I take away the trace function, the problem happens again.

    Do you know why that might be the case? I can send you my code if that’s helpful.


  10. BigMistake

    I’ve done this tutorial, but I want to do two things which just aren’t working right now:

    first of all, I want the ball to collide against the wall without clipping, but I’ve tried too many stuff in the code.

    Second, I want to limit the area in which the ball can move around. Anybody got suggestions? :S


  11. bladelock

    hello, may i just ask, which is the “hero” exactly?



Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="" highlight="">


Advertisement