Wednesday, March 05, 2008

Actionscript 3.0 Smooth character movement

Smooth Character Movement
In actionscript 3.0 when you program an object to move following a keypress, the object moves once then pauses before continue the moment. This is the way I have achieved smooth movement, not certain its the best or easiest way but anyway heres what I did:

Using the example of moving left

Under your 'keydown' function for the left key, type mLeft = true;
Then under your 'enterFrame' function, have an if statement saying:

if (moveLeft) {
myCharacter.x = myCharacter.x - 10;
}


Then, under your 'keyup' function for the left key, type mLeft = false;

You will need to define the following variables for the different keys:

var moveLeft:Boolean = false;
var moveRight:Boolean = false;
var moveUp:Boolean = false;
var moveDown:Boolean = false;

(the last two if you are moving the character up and down as well as left and right)

All the code:

//Defining the variables
var moveLeft:Boolean = false;
var moveRight:Boolean = false;
var moveUp:Boolean = false;
var mDown:Boolean = false;


//Adding Event listeners
stage.addEventListener(KeyboardEvent.KEY_UP, reportKeyUp);
stage.addEventListener(KeyboardEvent.KEY_DOWN, reportKeyDown);
stage.addEventListener(Event.ENTER_FRAME, EnterFrame);

//KeyDown function
function reportKeyDown(event:KeyboardEvent):void {
if (event.keyCode == Keyboard.LEFT) {
moveLeft = true;
}
if (event.keyCode == Keyboard.RIGHT) {
moveRight = true;
}

if (event.keyCode == Keyboard.UP) {
moveUP = true;
}
if (event.keyCode == Keyboard.DOWN) {

moveDOWN= true;
}
}

//Key Up Function
function reportKeyDown(event:KeyboardEvent):void {
if (event.keyCode == Keyboard.LEFT) {
moveLeft = false;
}

if (event.keyCode == Keyboard.RIGHT) {
moveRight = false;
}
if (event.keyCode == Keyboard.UP) {
moveUP = false;
}

if (event.keyCode == Keyboard.UP) {
moveDOWN = false;
}
}

//Enter Frame Function (this happens over and over repeatedly)
function EnterFrame(event:Event):void {
if (moveLeft){
myCharacter.x -= 10;
}
if (moveRight){
myCharacter.x +=10;
}

if (moveUp){
myCharacter.y -=10;
}
if (moveDown){
myCharacter.y +=10;
}

}
}

I *think* that this should work, if it doesn't I apologise and please comment and tell me what the error says or what is happening.

17 comments:

Adam said...

Where you have if statements that say
"if (moveUp = true)" these can be shortened to

"if (moveUp)"

and for false:

"if (!moveUp)"

keep at it fella!

Unknown said...

ah i did know that, stupid mistake, cheers though :D

Gav Cooper said...

THANKS Chris!

I really needed this... I follow your explanation better than 8-bitrocket's.

Gav Cooper said...
This comment has been removed by the author.
Gav Cooper said...

damn i hate those pointless spam people who comment on blogs, i get em too. you can easily delete thier comments Chris...

I don't even see the point in thier posts, thier links lead nowhere!

Unknown said...

There are some naming scheme issues with your script. The variables set at the beginning begin with "M" while when they're used later on they begin with "Move".

Unknown said...

cheers Bryce, missed that! Made the changes

Von Talavang said...

Man,
that code works perfect

full code and some fixs

//Defining the variables
var moveLeft:Boolean = false;
var moveRight:Boolean = false;
var moveUp:Boolean = false;
var moveDown:Boolean = false;

//Adding Event listeners
stage.addEventListener(KeyboardEvent.KEY_UP, reportKeyUp);
stage.addEventListener(KeyboardEvent.KEY_DOWN, reportKeyDown);
stage.addEventListener(Event.ENTER_FRAME, EnterFrame);

//KeyDown function
function reportKeyDown(event:KeyboardEvent):void {
if (event.keyCode == Keyboard.LEFT) {
moveLeft = true;
}
if (event.keyCode == Keyboard.RIGHT) {
moveRight = true;
}
if (event.keyCode == Keyboard.UP) {
moveUp = true;
}
if (event.keyCode == Keyboard.DOWN) {
moveDown= true;
}
}

//Key Up Function
function reportKeyUp(event:KeyboardEvent):void {
if (event.keyCode == Keyboard.LEFT) {
moveLeft = false;
}
if (event.keyCode == Keyboard.RIGHT) {
moveRight = false;
}
if (event.keyCode == Keyboard.UP) {
moveUp = false;
}
if (event.keyCode == Keyboard.DOWN) {
moveDown = false;
}
}

//Enter Frame Function (this happens over and over repeatedly)
function EnterFrame(event:Event):void {
if (moveLeft) {
myCharacter.x -= 10;
}
if (moveRight) {
myCharacter.x +=10;
}
if (moveUp) {
myCharacter.y -=10;
}
if (moveDown) {
myCharacter.y +=10;
}

}

thanks a lot

QuantumGuy said...

The code gets my character to move, but the smoothness you spoke of is not there. My guy is still pausing once and then continuing. :(

Anarch13 said...

Nice one. Youre the only guy i found on the www. who could explain me this in common sense.. but one thing xD sorry hehe... IF you use 2 keys at the same time like UP and LEFT it moves diagonally. i want to disable this because it messes up my animation

Yoily Weiss said...

Hi. Interesting read; the one problem is that, in the original post, both key listeners are named reportKeyDown! I suggest naming the second on reportKeyUp... ;)

Thanks for sharing!

(It's really nice to have explanations geared to beginners. 8bitrocket, for example, can be very hard to follow, as Gav Cooper says.)

Anonymous said...

Perfect!
I had been searching for so long for this piece of code. Until now, you had to spam the arrow keys to get the character to continue his movements :P
Thanks heaps!

Adaksh said...

My character doesn't stop moving downward even after I let go of the Down key. I can't figure it out. Do you know why?

Unknown said...

Adaksh, not sure if this is still relevant (I've not checked this blog in years) but if you are using this code then the moveDown function will only be working whilst the down button is being pressed:

if (event.keyCode == Keyboard.DOWN) {
moveDOWN = true;
}

Anonymous said...

Perfect
Thank you so much

Anonymous said...

Perfect Thank you

muhammad nawaz said...

var moveLeft:Boolean = false;
var moveRight:Boolean = false;
var moveUp:Boolean = false;
var moveDown:Boolean = false;

//Adding Event listeners
stage.addEventListener(KeyboardEvent.KEY_UP, reportKeyUp);
stage.addEventListener(KeyboardEvent.KEY_DOWN, reportKeyDown);
stage.addEventListener(Event.ENTER_FRAME, EnterFrame);


//KeyDown function
function reportKeyDown(event:KeyboardEvent):void {
if (event.keyCode == Keyboard.LEFT) {
moveLeft = true;
}
if (event.keyCode == Keyboard.RIGHT) {
moveRight = true;
}
if (event.keyCode == Keyboard.UP) {
moveUp = true;
}
if (event.keyCode == Keyboard.DOWN) {
moveDown= true;
}
}

//Key Up Function
function reportKeyUp(event:KeyboardEvent):void {
if (event.keyCode == Keyboard.LEFT) {
moveLeft = false;
}
if (event.keyCode == Keyboard.RIGHT) {
moveRight = false;
}
if (event.keyCode == Keyboard.UP) {
moveUp = false;
}
if (event.keyCode == Keyboard.UP) {
moveDown = false;
}
}

//Enter Frame Function (this happens over and over repeatedly)
function EnterFrame(event:Event):void {
if (moveLeft){
myCharacter.x -= 10;
}
if (moveRight){
myCharacter.x +=10;
}
if (moveUp){
myCharacter.y -=10;
}
if (moveDown){
myCharacter.y +=10;
}

}


this code is having many errors, try this.