Saturday, July 24, 2010

RTS-like character movement using mouse in flash (Actionscript 3 tutorial)

In this lesson we will learn how to create a mouse click movement for our character!

The idea is simple: click anywhere on the screen, character walks there. A little more difficult to turn this into reality.

First of all, we need to create our character movieclip. Here's a step by step guide:

1) Create a movieclip on stage with instance name "char".

2) Find a sprite sheet of a unit walking, or draw your own. Make sure it has 4 directions - left, right, up and down.

3) In the "char" movieclip, create 4 frames.

4) Each frame must contain one unique movieclip of the character walking in a specific direction (example of char character: frame 1 - mc of guy walking down, frame 2 - right, frame 3 - up, frame 4 - left)

Make sure that the first frame of every animation movieclip is the guy standing.

5) Now you have a movieclip with 4 different animation movieclips on 4 different frames. Give those animation movieclips instance name of "w" (yes, 4 mc's with instance of "w", it is okay because they are on different frames)

6) Inside the char movieclip, set labels for the frames - "down", "right", "up" and "left", according to your MCs.

7) Put stop(); on each of the 4 frames in your char movieclip.

Now that we have everything set up, it is time for coding! Here is the full code with commentary. (The code should be on the main timeline)

// define all necessary variables

var iswalking = false; // is the character moving?
var goX = char.x; // goX - the point on the X axis to which char must move
var goY = char.y; // same as goX but on the Y axis
var movespeed = 5; // movespeed of our hero
var dir = "down"; // current direction of movement

stage.addEventListener(Event.ENTER_FRAME, loop);

function loop(Event)
{
 // animation handling

 if (iswalking == true)
 {
  char.w.play();
 }
 else
 {
  char.w.gotoAndStop(1);
 }

 // direction handling

 char.gotoAndStop(dir);

 // movement handling

 if ((goY-movespeed)>char.y)
 {
  char.y +=  movespeed;
  dir = "down";
  iswalking=true;
 }
 else if ((goY+movespeed)<char.y)
 {
  char.y -=  movespeed;
  dir = "up";
  iswalking=true;
 }
 else if ((goX-movespeed)>char.x)
 {
  char.x +=  movespeed;
  dir = "right";
  iswalking=true;
 }
 else if ((goX+movespeed)<char.x)
 {
  char.x -=  movespeed;
  dir = "left";
  iswalking=true;
 }
 else
 {
  iswalking = false;
 }

}

stage.addEventListener(MouseEvent.CLICK, setposition);

// set the position to which char must move on click

function setposition(MouseEvent){
 goX=mouseX
 goY=mouseY}

And here's what we get!



We can edit the code a little to add support for diagonal movement too.

var iswalking = false;
var goX = char.x;
var goY = char.y;
var movespeed = 5;
var dir = "down";

stage.addEventListener(Event.ENTER_FRAME, loop);

function loop(Event)
{
 // animation handling

 if (iswalking == true)
 {
  char.w.play();
 }
 else
 {
  char.w.gotoAndStop(1);
 }

 // direction handling

 char.gotoAndStop(dir);

 // movement handling

 if ((goY-movespeed)>char.y)
 {
  char.y +=  movespeed;
  dir = "down";
 }
 else if ((goY+movespeed)<char.y)
 {
  char.y -=  movespeed;
  dir = "up";
 }
  if ((goX-movespeed)>char.x)
 {
  char.x +=  movespeed;
  dir = "right";
 }
 else if ((goX+movespeed)<char.x)
 {
  char.x -=  movespeed;
  dir = "left";
 }
 
 if ((goY-movespeed)>char.y || (goY+movespeed)<char.y || (goX-movespeed)>char.x || (goX+movespeed)<char.x){
  iswalking = true;
 } else {
  iswalking=false
  }
}

stage.addEventListener(MouseEvent.CLICK, setposition);

function setposition(MouseEvent){
 goX=mouseX
 goY=mouseY}



Thanks for reading!

Update: Due to popular demand, I've uploaded the source file.

Related:

Actionscript 3 RTS game tutorial part 2
Actionscript 3 RTS game tutorial part 3
Actionscript 3 RTS game tutorial part 4
Actionscript 3 RTS game tutorial part 5

45 comments:

Laura said...

This is awesome! However, it seems like my player is "ice-skating", it doesn't walk when I tell it to move a direction (it moves on the screen though. Yay! Actionscript that doesn't catch fire with compiler errors when I run it!)I put stop(); in the frames of the char movie clip, but when I take it out, an error (TypeError: Error #1009: Cannot access a property or method of a null object reference.
at Untitled_fla::MainTimeline/loop()) pops up. thank you

Kirill Poletaev said...

Do you have frames labeled as "left", "down", etc? Re-read the tutorial and do every step carefully, it should work.

Jesse said...

I have a question..I adopted the code used above and used it to make a tank move left,right,up, and down with different movieclips for each direction. Since the movieclip is able to move diagonal with the second batch of code how can I write the code to make the tank appear to be moving diagonal. I made the movieclip already in the instance frame but I can't figure out the logic, I need the logic like this but for diagonal movement:

else if ((goY+movespeed)<char.y)
{
char.y -= movespeed;
dir = "up";

Can anyone shed some light on this?

Thanks!

Kirill Poletaev said...

You will need to combine 2 directions together and make an if() out of that. For example:

if ((goX-movespeed)>char.x && (goY+movespeed)<char.y)
{
char.y -= movespeed;
char.x += movespeed;
dir = "upright";
}


But you will need to check for diagonal directions before you check for singles and make sure they are linked by else's.

Anonymous said...

i am using this code on a car and i followed all of the instructons and used the exact code and it says

TypeError: Error #1009: Cannot access a property or method of a null object reference.
at cartest_fla::MainTimeline/loop()

please i need some help.

Kirill Poletaev said...

You should read the tutorial more carefully - you probably missed out the part where you create and give instance names to movie clips.

jesse said...

Hi again. I have everything working good. New question. Is it possible to make it so I have to click on my movieclip first and then select where I want it to move to? I ask this because I want to be able to have multiple movieclips that I can move around, but I want them to be independent.

Kirill Poletaev said...

Yeah, everything is possible!
Just set a flag variable for the movie clip, which is toggled by clicking on it. Then move the movie clip only when the flag is toggled.

jesse said...

Hey sorry to bug you...Can you provide an example of how to set that up?

Kirill Poletaev said...

Yeah, that's a good question and I will make a tutorial on that. It will come out on November 6th

Anonymous said...

I can't seem to get this to work, I test the movie, and this error comes up in the output:

TypeError: Error #1009: Cannot access a property or method of a null object reference.
at LogInFrontScreen_fla::MainTimeline/loop()

Over and over, and the character spins in circles. Could you help?

Kirill Poletaev said...

The code is fine, I just re-tested it again and it works. You probably forgot to give instance names for some of the objects. Do you have the 'w' movieclip inside the 'char' movieclip?

Let me know if the problem still exists. If you can't figure it out, you can e-mail me the .fla and I'll take a look at it.

Anonymous said...

Hi there first of all great tut. I've changed it slightly to only travel along the X axis but like others I have had the 1009 error. I'm sure I have the whole w instance name right. I click char-left/right frames and both instances names are w.

Any suggestions?

Kirill Poletaev said...

FIX: Put stop(); on each of the 4 frames in your char movieclip.

It worked fine without that for me, but for some people it only works with the stops.

Main post updated.

Anonymous said...

Thanks so much for that fix Kirill, it worked perfectly!!

Anonymous said...

I have engaged a small problem here... I read the tutorial very carefully and thoroughly, yet I cannot detect the cause of the error. I have tried many things but it just wont work out.

Error:
1046: Type was not found or was not a compile-time constant: char.

Did I miss out something concerning the linkage between char and actionscript or is it something else? How can I fix this?

Kirill Poletaev said...

Error 1046 happens when you have the same names for an object on stage and a class in library. Do you have a movieclip in library with class linkage "char"? Change it to something else and it should work.

Anonymous said...

Oh yeah it does!! Thanks!!!
I put the instance name and linkage with the same name. Thus the error.
However, my character too is ice skating, and I see no malfunction within the labels, any ideas?

Kirill Poletaev said...

I just copy-pasted the code to a newly created document with a 'char' movieclip and a 'w' movieclip inside with an animation and it worked just fine. I tested with both of the given scripts.

Anonymous said...

Do you have the flash file for this? :) Because I can't seem to really understand it :| Don't worry. I'll credit you~ <3

Anonymous said...

Do I require some sort of specific program for this or do you script on the regular Flash ActionScript Window?
Also as for the animation of the unit walking, does it require anything or can I simply draw a frame-by-frame figure swinging his arms?

My problem is that my character does move, diagonally and all, tho the actual animation of the figure isn't being played.

Thank you.

Kirill Poletaev said...

You can draw whatever you want for animation and the actions panel is the only place to write code in flash.

z said...

Thank you for posting this. The work done here is a great tutorial. I was able to implement the diagonal portion as well and plan on continuing working through all of your examples. I'm also going to try and change the 'select multiple units' to a click and hold rather than hold control. Thanks again.

daniel/dawnland said...

Greetings Kirill!
I just want to thank you for fantastic tutorials!
I have worked in flash for many years and I was getting warm using AS2, when AS3 appeared and I have ignored it till now.
Thanks again!

/Daniel

GP said...

(and each of the 4 frames has a stop();)

Kit said...

May you give me the .Fla? its kinda' annoying, i maded it then it don't work, may you?
you may send it to me by my email
rodri923@gmail.com
Facebook? www.facebook.com
Twitter? www.twitter.com
Tumblr? www.tumblr.com
Mixpod? www.mixpod.com
if not you may attack the file in my email.
Thank you Kirill! BTW its ok if you dont give.

Kirill Poletaev said...

I've sent you the source file.

Anonymous said...

Hi,

can you also send me the fla file? I tried the tutorial but i dont get it finished because i dont understand 1-2 steps of your tutorial
arantis@gmx.de

THANKS for the nice tutorial. It was exactly what iam searching for :)

Anonymous said...

Hi Kirill,

Still a beginner learning as3 , please send me the source fla file.
zorenc@yahoo.com

Thank you Kirill

Kirill Poletaev said...

http://www.multiupload.com/YM4ATJJ1CR

Anonymous said...

HI Kiril, this is a great tutorial, but I can't get my sprite to do the walking actions, the code is fine and I followed everything, I have no compile errors, and the sprite moves wherever I click, it just hovers though... lol

Why is this?

Kirill Poletaev said...

Check out the source file that I've put up, hope it helps!

Anonymous said...

For anyone having issues with their characters not walking properyly or ice skating lol try putting "nextFrame()" instead of "play()" it worked for me :)

example:

Before

if (iswalking == true)
{
char.w.play();
}
else
{
char.w.gotoAndStop(1);
}


After

if (iswalking == true)
{
char.w.nextFrame();
}
else
{
char.w.gotoAndStop(1);
}

Anonymous said...

i can not get the source file . it's showing "this file is no longwe available"
can you mail me the source file or fix the source file link
mail : abir.ruet@gmail.com

Kirill Poletaev said...

Reuploaded to Filesmelt.

Anonymous said...

hey kirill :)
can you please send me the code? because i really don't figure it out why its not working o.o
and i can't open the download file, it's damaged or sth..

my email is lilee_sashimi@hotmail.com

Kirill Poletaev said...

Reuploaded to mediafire: http://www.mediafire.com/?gumyndyq7hguu6a

Anonymous said...

Hi kirill,
Please tell me what should I do if I want the character to move at 30 degrees while going up and coming down?

Anonymous said...

Package {
import flash.display.MovieClip;
import flash.events.MouseEvent;

public class whatever extends MovieClip
{
Does this look right for the beginning of of it? I am very new too! Thanks for the help, awesome tutorial! :)

Kirill Poletaev said...

"Package" is written with a "p", not a "P". Otherwise, it seems fine. You might find my OOP tutorials useful!

Anonymous said...

Thanks, appreciate it! I'll check it out.

CkNish said...

Hello. I love your tutorial as it has helped me immensely. But I'm facing problems applying the code to my game with some modifications. Could you take a look at it please?

https://docs.google.com/file/d/0Byox6fkr_rlKcTlTWVhnbkdTbFk/edit

bob kent said...

zup kirill :), I just got to see your tutorials while browsing at google for actionscript 3 tutorials and I find your blog very awesome, anyways the link on to download here is broken.., any mirror sites where i can download this? thanks

BagiBagi Blog Area said...

hi kirill I see your tutorial interesting, but I can't find source code because file has been deleted. please send me source file.
email: bagibagi23@gmail.com
thanks

Putri Natasya said...

Wonderful tutorial! Can you send me the source file, please? I cant download it. It is deleted...
Email:nuramani06@gmail.com
Thank you!

Post a Comment