8 way Character Movement

First of all, I want to say: If you are completely new at ActionScript, then you should check out Michael James Williams tutorials, starting here

Now one of the problems I see in many games are the movement of the main character. Just take a look at two games at ArmorGames: Medieval Rampage, Hands of War RPG.
I think this is rather strange as it is very easy to manage. First of all I want to show how you make a character move, this is really not complicated. We’re going to make a game with correct movement with WASD and arrow keys.

First of all, we need something to move, I drew a little man for this purpose:
movement1
Make him a symbol and call the instance man. And I made a little part of the checked floor so we can keep in mind how much he moved, more on this later. I placed my little guy on the middle of the floor.
movement2
Now we need to write some come for this little guy to move.
First I want you to make a new AS file and call this main, link to this as the Documentclass in Flash. Let Main extend MovieClip and remember to import.
Then we’re going to add some Boolean variables for each direction and a variable to hold our speed, take a look:

1
2
3
4
5
6
7
8
9
10
11
package
{
	import flash.display.MovieClip;
 
	public class Main extends MovieClip
	{
		public var leftIsPressed = false;
		public var rightIsPressed = false;
		public var upIsPressed = false;
		public var downIsPressed = false;
		public var speed:Number=100;

Then we’re going to add some eventlisteners to the keyboard (These should be self explained):

15
16
			stage.addEventListener(KeyboardEvent.KEY_DOWN, atKeyDown);
			stage.addEventListener(KeyboardEvent.KEY_UP, atKeyUp);

Remember to import:

3
	import flash.events.KeyboardEvent;

Then we need to write some functions for these eventlisteners:

19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
		function atKeyDown(event:KeyboardEvent)
		{
			if ( event.keyCode == 37 || event.keyCode == 65 )
			{
				leftIsPressed = true;
			}
			if ( event.keyCode ==38 || event.keyCode == 87 )
			{
				upIsPressed = true;
			}
			if ( event.keyCode == 39 || event.keyCode == 68 )
			{
				rightIsPressed = true;
			}
			if ( event.keyCode == 40 || event.keyCode == 83 )
			{
				downIsPressed = true;
			}
		}
 
		function atKeyUp(event:KeyboardEvent)
		{
			if ( event.keyCode == 37 || event.keyCode == 65 )
			{
				leftIsPressed = false;
			}
			if ( event.keyCode == 38 || event.keyCode == 87 )
			{
				upIsPressed = false;
			}
			if ( event.keyCode == 39 || event.keyCode == 68 )
			{
				rightIsPressed = false;
			}
			if ( event.keyCode == 40 || event.keyCode == 83 )
			{
				downIsPressed = false;
			}
		}

The keyCodes I’ve used is:

  • 37: left arrow key
  • 38: up arrow key
  • 39: right arrow key
  • 40: down arrow key
  • 65: A
  • 67: D
  • 83: S
  • 87: W

Now, all we have is some Boolean variables telling us if we’re pressing one of the direction buttons. That’s not fun. Let’s add a loop to handle the movement. First of, lets add a timer (once again, remember to import flash.utils.Timer):

15
16
17
18
19
		public var gameTimer:Timer;
 
		public function Main()
		{
			gameTimer=new Timer(500);

Now the reason of that high a delay is that we’re going to move the character a lot, so having a small delay would make him jump off the screen, not good! Let’s add an eventlistener and start the timer (remember to import flash.events.TimerEvent):

23
24
			gameTimer.addEventListener(TimerEvent.TIMER, onTick);
			gameTimer.start();

All we need to do now is make the loop function:

27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
		function onTick(even:TimerEvent):void
		{
			var xSpeed:Number=0;
			var ySpeed:Number=0;
 
			if (leftIsPressed)
			{
				xSpeed-=speed;
			}
			if (rightIsPressed)
			{
				xSpeed+=speed;
			}
			if (upIsPressed)
			{
				ySpeed-=speed;
			}
			if (downIsPressed)
			{
				ySpeed+=speed;
			}
 
			man.x+=xSpeed;
			man.y+=ySpeed;
		}

Notice that I made to variables, xSpeed and ySpeed, you could have just updated the mans x and y position, but if both up and down are pressed flash has to update the players position twice, with this code it’s only once (this will also have an other benefit later on). I also made an if statement to all our buttons, you could have made it like this:

		function onTick(even:TimerEvent):void
		{
			if (leftIsPressed)
			{
				xSpeed-=speed;
			}
			else if (rightIsPressed)
			{
				xSpeed+=speed;
			}
			if (upIsPressed)
			{
				ySpeed-=speed;
			}
			else if (downIsPressed)
			{
				ySpeed+=speed;
			}
 
			man.x+=xSpeed;
			man.y+=ySpeed;
		}

But if the player pressed both left and an other button at the same time, he would always move left, now he is just not moving at all. This is great. Anyway, check it out. (click to it to activate, use arrow keys or WASD to move – you have to hold them for 0.5 second)
(Either JavaScript is not active or you are using an old version of Adobe Flash Player. Please install the newest Flash Player.)

Now we made a simple movement, just as almost every other game out there, this may be fine for some games (fx platformers), but for a top-down game we need to do a little more of work. Can you find the error yourself?
What if I told you to take one sped forward, and afterwards take a step where you moved both forward and just as much to the left, would you have taken a 40 % lager step? I think not, but our little guy is doing just exactly this right now. Many times walking diagonally like this could change the gameplay a lot! I’ve made a green circle to show where the player actually should be going.(click to it to activate, use arrow keys or WASD to move – you have to hold them for 0.5 second)
(Either JavaScript is not active or you are using an old version of Adobe Flash Player. Please install the newest Flash Player.)
How to fix this you ask?
Phythagoras. If you don’t know what this is, then I would surges you checked out Michael James Williams post on this

Now in our case we know what the speed is, but we do not know how much the guy has to walk horizontally or vertically. How to figure that out?
speedeq
Now we just need to do this:

49
50
51
52
53
			if(xSpeed!=0 && ySpeed!=0)
			{
				xSpeed = (xSpeed * Math.sqrt(2))/2;
				ySpeed = (ySpeed * Math.sqrt(2))/2;
			}

And there we are, everything is done. You can check it out here: (click to it to activate, use arrow keys or WASD to move – you have to hold them for 0.5 second)
(Either JavaScript is not active or you are using an old version of Adobe Flash Player. Please install the newest Flash Player.)

I made a zip file for all of you. ZIP LINK

If you have been following Michael James Williams AvoiderGame tutorials, you can see how to implement it here

Posted on June 9th, 2009
Filed under ActionScript 3, Flash, Tutorial |

4 Responses to “8 way Character Movement”

  1. AS3: Diagonal Movement in the Avoider Game
    June 7th, 2009 at 13:05

    […] you haven’t read my Character Movement tutorial yet, do so here. Second of all, you should have read the base tutorials by Michael James Williams, do that here. […]

  2. Avoider Game: Boundaries, Diagonal Movement and a Forum — Michael James Williams
    June 10th, 2009 at 01:33

    […] based on his own 8-way Character Movement. Check out the avoider game version at AvoiderGame.com (where […]

  3. A Freelancer’s Flash Bash [4] | Freelance Flash Games News
    July 23rd, 2009 at 00:42

    […] Rasmus Wriedt Larsen has a new series on Buttons and Menus in AS3, and a nice post on using 8 way character movement. […]

  4. The Baisc Controls of a Car | Rasmus Wriedt Larsen - Flash Game Development
    August 2nd, 2009 at 23:19

    […] going to be any explanation about how to do that, if you can’t do this please read the ‘8 way character movement‘ tutorial I […]

Leave a Reply