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:
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.
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)
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)
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?
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)
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