Tutorials

February 27, 2009

AS3 Character Movement: Following Mouse with Easing

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

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

Honestly this is an addendum to the previous tutorial in this series. This is a simple adjustment to the code we have already wrote but it will give us character movement that eases towards the mouse position instead of keeping a constant speed. It’s a relatively useful effect, I used it in one of my games, Entropy, for the opponent’s paddle movement. So here we go, let’s make our character follow the mouse easing its way into the position.

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

First grab this source code: As3 Character Movement: Follow the Mouse Source code

This is the final source code from this tutorial:  AS3 Character Movement: Follow the Mouse Controls

Alright so just ignore the Engine class. We don’t need it. Open our Hero class which should look like this:

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;
			}
 
		}
 
	}
 
}

and testing our movie we get this:

Okay but if you read the previous tutorial, this is nothing new. I know… I know. Let’s do something new.

Step 1: Making our Character ease into a new position

Alright, get this… you can delete everything in the loop. We don’t need any of it. But if you want to keep the rotation of our hero changing based on the direction he is going… leave the distance lines in, the radian line, and the rotation line.  You can go ahead and delete all the conditional statements, we don’t need them.

We only need two simple lines to make our easing work.  Here’s the code:

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 = 7;
 
		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);
			rotation = radian * 180 / Math.PI;
 
			x -= (x - stageRef.mouseX) / speed;	//easing
			y -= (y - stageRef.mouseY) / speed; 	//easing
 
		}
 
	}
 
}

Simple huh? Let me explain.

  • x -= (x – stageRef.mouseX) / speed; This does all the magic.  One huge difference in the way it works though. The higher speed is the slower our Hero moves.  In turn, the lower speed is the faster our Hero moves.  Why? Well let’s look at it.  x – stageRef.mouseX, this is the distance between our hero and the mouse. When we divide the distance by speed it as long as speed is greater than one we get a smaller number than the distance. Then we subtract it from x and it moves our Hero closer to the mouse. So let’s draw out a scenario.
  • Here’s some fake data about our Hero and Mouse.
    x = 30
    stageRef.mouseX = 180
    speed = 7
  • so let’s put that in our formula.
    (30 – 180) / 7 = -21.428
    x = 30 – (-21.428) = 51.428

    So our change in x was 21.428.  When we do this on the next frame… you’ll notice the change in x is less because the distance is closer.

    (51.428 – 180) / 7 = -18.367
    x = 51.428 -(-18.367) = -69.795

    Notice the change was 18.367 this time. As we get closer to our destination point our movement gets smaller and smaller. That’s easing.

Here’s the swf.

And here is the final source:

AS3 Character Movement: Following Mouse with Easing Source Code Zip Archive

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.




9 Comments


  1. Just noticed that (Math.sqrt(yDistance*yDistance + xDistance*xDistance) < speed) should be

    (Math.sqrt(yDistance*yDistance + xDistance*xDistance) < speed).

    ST.


  2. Par

    LOL as far as the comment looks… you’ve wrote the same thing twice. But I think I know what you are talking about, I’ll fix it.


  3. Dennis

    I’d like to be able to embed te AS into the swf. Not set the AS class as linkage for the MC. Please help. Thanks


  4. Andrew

    Nice tut!


  5. John

    Whats a good way to add a max speed with easing? I tried:
    if (xMovement > maxSpeed) {
    xMovement = maxSpeed;
    }
    if (xMovement < -maxSpeed) {
    xMovement = -maxSpeed;
    }
    I did the same thing with y… it didn’t seem to work right.


  6. Dallas

    I managed to fudge something together.

    The previous tutorial used code that would only allow the Hero to travel at the maximum speed. This tutorial calculates movement based off of the speed(sort of like using the speed as an acceleration). That’s the key.

    ——
    if (Math.sqrt(yDistance*yDistance + xDistance*xDistance) < (speed*speed))
    {
    x -= (x – stageRef.mouseX) / (speed);
    y -= (y – stageRef.mouseY) / (speed);
    }
    else
    {
    x += Math.cos(radian) * speed;
    y += Math.sin(radian) * speed;
    }
    ——

    The ‘if’ statement executes the easing statements once the the distance between the mouse and the Hero is equal to the speed*speed, giving you a comfortable amount of room to slow down.

    The ‘else’ statement executes the original movement statement (which used speed as the maximum speed) whenever the Hero is too far away from the mouse to begin easing.

    What you have left is an object that will move at a maximum speed until it reaches a point to start easing gently to a rest at your mouse position.

    Hope I got this right.


  7. Joy

    Hi, your tutorial has been most helpful. However, If I would like to add more than one ball to the stage to move around at once like a cluster, how would I do this? Thank you in advance


  8. Chompy

    I know this probably seems like a stupid question but I’m struggling with something close to this. I want the “hero” to stay in the same position but to rotate depended on where the mouse cursor is. Any suggestions?



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