Tutorials

February 6, 2009

AS3 Flash Games for Beginners: Character Movement / Handling Multiple Keypresses

More articles by »
Written by: Par
basics1_tn

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

Movement is extremely important for any game in which you take the role character or object.  Bad movement can completely ruin your game, and good movement can make it feel well polished.  Of course, movement is just one part of your game, but it’s the foundation of everything your character will do, so you need to give it some attention.

This is the second article in the Flash Game Basics series. It picks up where the previous one left off.  The information in this article is not dependent on the previous other than the files being used and the assumption that you can add a Library Object to the stage using AS3.  If you would like to read the previous article first, it can be found here.  If you would like the source code and will just continue along, you can download the source code here.

Step 1: Using KeyObject Class by senocular

When we left off we had added our spaceship to the stage, front and center.  Now we need to make it move.  There are a couple ways we can do this, but the best way to handle keypresses, in my opinion, is found in a class written by an extremely talented programmer, senocular. You can download his class from his website by clicking this link. Just click download source file and save under the same directory as basics1.fla.  (Keep in mind this file is under the package “com.senocular.utils” so you will need to drop it in the utils folder inside senocular which is inside com. Our com folder should now have senocular and asgamer folders inside it.

Okay so we have senocular’s class ready, if you’ve programmed in AS2, you’ll notice senocular’s class gives you the isDown functionality of AS2. So let’s open our Ship class and start setting it up to work with senocular’s class.  We need to import two classes, Senocular’s KeyObject and the Flash Keyboard class. Then we’ll need to create an object of the KeyObject class, which requires the stage to be passed as a parameter.  Problem! we don’t have access to the stage in our Ship class. So we’ll have to pass it from Engine into Ship, No Problem!

Here’s our new Engine Class passing the stage into ourShip.

//our package... simply put, the directory structure to this file
package com.asgamer.basics1
{
	//list of our imports these are classes we need in order to
	//run our application. 
	import flash.display.MovieClip;
	import flash.display.Stage;
 
	//our Engine class it extends MovieClip
	public class Engine extends MovieClip
	{
		//our constructor function. This runs when an object of 
		//the class is created
		public function Engine()
		{
			//create an object of our ship from the Ship class
			var ourShip:Ship = new Ship(stage);
			//add it to the display list
			stage.addChild(ourShip);
 
			ourShip.x = stage.stageWidth / 2;
			ourShip.y = stage.stageHeight / 2;
		}
 
	}
 
}

And here’s our Ship class receiving the stage from Engine, including Keyboard, Stage, and KeyObject classes, and creating an object of the KeyObject class:

package com.asgamer.basics1{
 
	import flash.display.MovieClip;	import flash.display.Stage;
	import com.senocular.utils.KeyObject;
	import flash.ui.Keyboard;
 
	public class Ship extends MovieClip	{
 
		private var stageRef:Stage;
		private var key:KeyObject;
 
		public function Ship(stageRef:Stage)
		{
			this.stageRef = stageRef;
			key = new KeyObject(stageRef);
		}
 
	}
 
}

Okay the Breakdown!

  • Engine class.
    We just added stage into the parameters needed to create an object of the Ship class. We’ll need to add something to the Ship class in order to catch the parameter when it’s sent through, but as far as Engine goes, we’re done with it.
  • Ship class.
    We added three imports… We already discussed two of them, the Stage import was needed because we’re passing the stage through. So we need to know what to do with the stage, therefore, we import the Stage class.
  • Ship class.
    Class variables.
    We added two new class variables. One for the stage reference, stageRef, so we can reuse the stage in other functions in our Ship class.  The other variable is for our KeyObject so we can use it anywhere in the class as well.
  • Ship class.
    Our Constructor Function.
    We take the stageRef variable passed in from Engine and store it in the classes stageRef variable. The this. preceding stageRef tells Flash that it is addressing our class variable and not the one being passed into the function. Then we create our KeyObject and store it in our key variable. KeyObject gets the stage passed into it because we need the stage in order to check for key presses.

Step 2: Enter Frame Listener

Currently our game loads up shows our background and ship and nothing happens :( .  So to make something happen we’re going to write code that will execute everytime flash redraws a frame… in our case 30 times a second.  To do this we need to create an event listener.  So we’ll import a new class add our listener and create a new function. Here’s the new Ship class code.

package com.asgamer.basics1{
 
	import flash.display.MovieClip;
	import flash.display.Stage;
	import com.senocular.utils.KeyObject;
	import flash.ui.Keyboard;
	import flash.events.Event;
 
	public class Ship extends MovieClip	{
 
		private var stageRef:Stage;
		private var key:KeyObject;
 
		public function Ship(stageRef:Stage)
		{
			this.stageRef = stageRef;
			key = new KeyObject(stageRef);
 
			addEventListener(Event.ENTER_FRAME, loop, false, 0, true);
		}
 
		public function loop(e:Event) : void
		{
			y--;
		}
 
	}
 
}

The Breakdown!

  • We import flash.events.Event, because we are listening for an event now.
  • addEventListener(Event.ENTER_FRAME, loop, false, 0, true); Okay so our Ship is calling the addEventListener function. We need to pass the first two parameters: what kind of event we need and what function to call each time the event occurs.  The last three parameters are optional but setting the last one to true turns on weak referencing which is recommended. For more information read about it at Grant Skinner’s blog here.
  • public function loop(e:Event) : void. Our enter frame function. An event parameter is being passed to it, all event listeners pass an event parameter into the function they call, so be prepared to catch it. The : void just let’s Flash know this function returns nothing.
  • y–; Each time we enter frame, we move up 1 pixel. y– is the same as writing y-=1 or y = y -1.  Remember the equals sign is not equals in an algebraic sense, it more literally means store as.

Compile the game (CTRL+ENTER) and watch your ship fly off screen.

Step 3: Reading Key Presses.

Alright, let’s start reading when you press a key.  Delete the y– line.  And on with the if statements.

package com.asgamer.basics1{
 
	import flash.display.MovieClip;
	import flash.display.Stage;
	import com.senocular.utils.KeyObject;
	import flash.ui.Keyboard;
	import flash.events.Event;
 
	public class Ship extends MovieClip	{
 
		private var stageRef:Stage;
		private var key:KeyObject;
 
		public function Ship(stageRef:Stage)
		{
			this.stageRef = stageRef;
			key = new KeyObject(stageRef);
 
			addEventListener(Event.ENTER_FRAME, loop, false, 0, true);
		}
 
		public function loop(e:Event) : void
		{
			if (key.isDown(Keyboard.LEFT))
				x -= 2;
			else if (key.isDown(Keyboard.RIGHT))
				x += 2;
 
			if (key.isDown(Keyboard.UP))
				y -= 2;
			else if (key.isDown(Keyboard.DOWN))
				y += 2;
		}
 
	}
 
}

Let’s break this down.

  • We added two if else if statements. One to read our horizontal changes, the other to read our vertical changes.  So if the LEFT keyboard key is down we want to move x left 2 pixels. If the RIGHT key is down move right 2 pixels. The same goes for vertical movement.

Compile this thing. Test it out.

Here’s the final source code for this step:
AS Gamer – Flash Games for Beginners Part 2 Source

Awesome in the next tutorial, we’ll dive deeper into Movement Dynamics and do some easy tricks to make our ship animate in a slick 3D like manner.

Click here to see the next tutorial.

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.




51 Comments


 
 

  1. brandon

    Please tell how to do it without the senocular import. I’d like to be able to use all keys and not mimic as2 despite the usefulness of it. Thanks these tuts are great I cannot wait for more on the site


  2. Par

    For what reason do you want to learn how to do it without the senocular import? I can teach you how to write a class identical to his if that’s what you want. But there’s no reason for that, he’s already created a brilliant class that does exactly what we need. Why in the world would we want to write something else? Feel free to use the most common method of managing keypresses with as3 which involves creating a Boolean for every key to determine if it is down or not. Which is way more code and a lot less clean and easy to manage. I’ve used it for all my games because as far as I am concerned it is above and beyond the best method of handling key presses. Has nothing to do with the fact it emulates AS2′s method and every thing to do with it being clean and effective.

    I may at one point discuss writing how to handle key presses without using the KeyObject Class but for now I don’t know why you’d need anything else.


  3. Brandon:
    I’m in agreement with Par. senocular’s KeyObject class rocks.

    You also can use any key. Simply pass the correct uint to the key.isDown() function.

    e.g.

    var keyA:uint = 65; //uint code for “A”

    if (key.isDown(keyA)) {
    //do something
    }


  4. michael

    I’m sorry, but i can’t manage how to use Senocular’s keyObject with other keyboard’s letters than up,down,left…

    The last comment isn’t working, should it work?


  5. ananda

    Here’s our new Engine Class passing the stage into ourShip.
    var ourShip:Ship = new Ship(stage);
    because of the stage arguement i was shown compiler error.
    1136: Incorrect number of arguments. Expected 0.

    can anyone solve this?


  6. Par

    Use the number equivalent instead of Keyboard.E or whatever. You can find them here.
    http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/ui/Keyboard.html


  7. Par

    It’s in your Ship class. Either
    A) you don’t have your linkage setup correctly or
    B) you are not accepting the stage reference in the constructor of your Ship class.


  8. Acidmoxy

    I’m having the same problem as ananda, can anyone explain this problem in simple-ish terms?


  9. TheKanos

    Hey, Acidmoxy, and ananda.

    What Par means by you aren’t accepting the stage reference in the constructor of your ship class, is you didn’t setup your

    public function Ship()

    to take the extra parameter that the Engine class sends it. Change that to

    public function Ship(stageRef:Stage)

    and everything should work out okay. It’s easy to miss in the code example for the tutorial.


  10. Beast

    The key presses aren’t working. It says Access to undefined property…


  11. Asker

    I do what TheKanos says but it show up new error

    on compiler errors reported:
    1046: Type was not found or was not a compile-time constant: KeyboardEvent.

    source :
    private function keyPressed(evt:KeyboardEvent):void {
    private function keyReleased(evt:KeyboardEvent):void {

    is something wrong? please tell me how to fix it


  12. Nightrider

    @asker: did you import flash.events.KeyboardEvent?


  13. The best information i have found exactly here. Keep going Thank you


  14. Rob

    why does everyone make this so difficult… your tutorial is great for a lot of people it seems, but I am new to flash and still have very basic skills… I have another project already half built and I just want to add a character to it with 8 directional movement and without using complex imports and external class sheets. I just want the code on the timeline linking to the instance name of the symbol… can anyone help me with this please? its driving me crazy…

    email me, robert.cameron2@gmail.com


  15. Par

    Sorry Rob but your not going to get anywhere in flash without using the imports. Nothing will make the game for you. It can be extremely difficult at first, but that’s why you got to put in the effort to learn it. But importing other classes is required to do most anything with flash. You can get away with less imports on the flash timeline because it goes ahead and takes care of it for you but it’s a much more confusing method for managing your programming.


  16. Ben

    Hi, I’ve never done any programming before and I just got a free trial for Flash CS4. I have been looking at tutorials and kind of get some of the basics. I would LOVE to be able to make a game like this, but I have no idea what classes and imports are…

    Can anyone direct me to a good place (preferably free) to learn that type of things, so that I will be able to figure this all out?

    Thanks a ton. =D


  17. BN

    Rob, imports just point to other blocks of code to be used in your project. For instance if I wanted to do something on the timeline I could put the entire Engine class and entire Ship class and go into the flash directory and copy and paste every flash class into the timeline, but instead of actually going and opening up the flash directory and finding the .as files then copying and pasting them I simply include an

    import flash.display.MovieClip;

    All that is telling it to do is to look in the flash directory and use those .as files that define what the MovieClip class does so that you can use them in your coding. It is essentially copying and pasting the code that was created by Adobe into the top of your project.

    This is really powerful to organize your projects this way, and I really appreciate the tutorial organizing files in this way. I come from a C++ programming background, but I’m interested in Flash as well and this is how I am used to organizing my files, but instead of imports I use #includes and : in class definitions for inheritance. It was good to see this structure translated to Flash because it makes the transition that much easier.

    The good thing about doing it like this is that you can create stand alone classes that depend on no other code then just import them into other classes to use them instead of creating a long coding file in the timeline where variables can get mixed up to the point where none of the code can be reused. Like senocular did with his AS2-esque implementation of keyboard commands file, it is a stand alone class that others like us can use to enhance our game if our game needs some enhancements in movement.

    These first two tutorials in this series lay a lot of ground work that you should understand before moving on. It gives a good foundation for creating just about any game. I mean at the simplest level we know how to load a scene now, then we know how to add objects that we can control to it, and we can keep adding things in our Engine class to display then we can define their actions within their own specific class until we have a game.

    Rob, just follow these tutorials and create some kind of symbol for your character and make it its own class. Add it to the Engine() function using addChild() since this is our main entry point, and define your character’s behavior within it’s own class that you created (key commands for movement).


  18. Par

    Excellent Comment BN, thanks a lot :D


  19. J

    I’m still trying to get it working with WASD. I’ve tried refrag’s method of:
    var keyA:uint = 65;

    And I’ve tried using keycodes, but none of those work. Could you please explain to me how to use Senocular’s library with WASD?


  20. S.

    I keep getting the following error in the KeyObject.as script

    1119: Access of possibly undefined property stage through a reference with static type
    1120: Access of undefined property stage.
    1120: Access of undefined property stage.
    1119: Access of possibly undefined property stage through a reference with static type Class.

    it’s killing me, i’ve pretty much copy and pasted YOUR code to try and stop it, and i’m still getting it.


  21. S.

    ok it works if i download your sourcefile and run that, but as soon as I do it from my typed by hand source, something messes up. I have a fairly good understanding of where I’m defining the stage..and I don’t see anything different.


  22. 1136: Incorrect number of arguments. Expected 1.

    I am getting this error and I have check the linkage and also the setting that TheKanos talked about. What am I missing. Great tutorial by way.


  23. Aro

    I’m getting this error: “1137 Incorrect number of arguments. Expected no more then 0″ I think the passing is fine… maybe its got something to do with my name changes(ex.”Ship” and its functions are all called “Player”)? Note that it isn’t error 1136 but it is 1137.

    My passing from MethodMain(Engine) to Player(Ship) looks like this:

    MethodMain:
    //create an object of our ship from the Ship class
    var ship:Player = new Player(stage);
    //add it to the display list
    stage.addChild(ship);
    ship.x=stage.stageWidth/2;
    ship.y=stage.stageHeight/2;
    ship.width=80.7;
    ship.height=23.8;
    Player:
    public function Player(stageRef:Stage) {
    —CODE—
    }


  24. Aro

    Nvm I got it. I had the wrong link in my movieclip so the class function never started… I had “Player” as the class not “com.aro.eclipse1.Player”.


  25. pzUH

    i got these errors:
    Error: Error #2090: The Proxy class does not implement callProperty. It must be overridden by a subclass.
    at Error$/throwError()
    at flash.utils::Proxy/http://www.adobe.com/2006/actionscript/flash/proxy::callProperty()
    at com.asgamer.psw::pesawat/loop()

    i have no idea what i need to do…..


  26. shak-a-tak

    when I ctrl enter, nothing happens. the background pops up and that’s it. does anybody know what I’m doing wrong? I would appreciate any help I could get.


  27. shak-a-tak

    let me be more exact. I hit control enter, the background is the only thing to open, nothing happens after that. I have literally went through and copied and pasted the code provided as an example, but it doesn’t help. I have no idea what to do. so if anyone can help, please do.


  28. Rizz

    Is there any websites, anybody can refer me to, where they have highly in depth as3 tutorials where everything is explained? All details, nothing left up to assumption. I am too much a noob for this tutorial. Completely lost when you brought senocular’s code into the picture.


  29. TheUberhaus

    First of all, great tutorials, easy to follow and great explanations to all the code. Really well done.

    On to my problem, I get the same error as ananda and Acidmoxy:

    1136: Incorrect number of arguments. Expected 0.

    My code is pretty much a copy and paste of this with alternations of names and such. I have no clue what to do, if I alter the line:

    var char:character = new character(stage);

    to:

    car char:character = new character();

    instead I receive no error but the character won’t move.
    Any help or tips is appreciated,
    Thanks,

    TheUberhaus


  30. Hi.

    A small hint for the problem with “1136: Incorrect number of arguments. Expected 0.”

    Check if all – and I mean ALL – writtens of Ship or Engine (or whatever you use) is really typed the same way. I have the feeling AS3 is case sensitive. That was my error. My ship.as file was typed with lower s. But in script and in class linkage I typed with upper S.

    Please proofe it and let me know. :)

    LR


  31. Zatarra

    It’s interesting to see the effects of using different combinations of if and else if. For example:

    if
    else if
    else if
    else if

    = Diagonal movement is impossible.

    if
    if
    if
    if

    = If you hold down two opposing keys, the ship stops until one is released.


  32. Zee

    AS3 seems to have a lot of nice features and really easy to use thanks to the majority of classes that are already written for you by Adobe. I come from a C++, Javascript, Pearl, Php background and just learning AS3. It’s Object inheritance with : Is just like a number of languages and to access the properties of the object with the . Is also very familiar. Thanks for the Tutorial so far though its covering a lot of ground and very descriptive of what’s happening with the code.


  33. Matty

    Great tutorial. I’m taking an actionscript 3 class now and your tutorial has helped keep me ahead of the game. thank you very much.


  34. hi,

    everythings working fine, cya on the next page ;) great tut.

    peace
    jesta


  35. simon

    i think the problem possibly shak-a-tak is having (and the problem i’m definitely having) is i took your advice in not just having a background drawn on the first key layer and removing it entirely and writing a class for just that specific background as you suggested in the previous tutorial page (page1). it works beautifully and after repositioning it using your position method, it indeed does work, but now when i compile, i see nothing but the background and no ship on the screen.

    is this due to the background overlapping the class due to the implementation of the background? is there a way i can set the background to the actual background instead of it overlaying my ship?

    this is what (at least i think) is happening and i could use a solution.


  36. simon

    also another question i have for you is structure based:

    why does ship have to recieve stage from engine and not just directly? my question is is why does stage have to pass through engine first? is this good programming practice or is it impossible to set up this way and thats the reason you’re doing it this way?


  37. Scriptnoob

    I love this tutorial. Very informative and nice, up to the point where you drag in senoculars code. While I am sure that is a great bit of code and all, I am more interested in learning to write my own than to just copy paste someone elses code. I dont get an understanding of it that way.

    Now I have some weird output error TypeError: Error #1009: Cannot access a property or method of a null object reference.


  38. Par

    @Scriptnoob, it’s great to understand every line of code that makes your project run. And congrats to you if every project you write you read and make sense of every line that makes it up. However, there’s some code I have minimal desire to understand and am very thankful someone else wrote it for me. TweenMax and TweenLite for example. I’m just happy it works, I don’t really care if I know every last detail of how it works.

    Besides, if you are going to have this mentality, you better ask Adobe to give you the code for how MovieClip, Sprite, and every other class they wrote for Flash works. Sometimes, you just trust something works and go with it.


  39. dash

    can anyone help me im lost here when im run the CTRL+ENTER its cames up with error like this .ive already copy paste the keyobject.as into all folder hoping no error but its say like this whot should i do!! help me pls!!!

    compiler error
    C:\Users\dash\Documents\GAME\KeyObject.as, Line 1
    description
    5001: The name of package ‘com.senocular.utils’ does not reflect the location of this file. Please change the package definition’s name inside this file, or move the file. C:\Users\dash\Documents\GAME\KeyObject.as

    reply me at here or my email @devildash47@yahoo.com


  40. hello,

    I’ve made the code as I used to do but when I ctrl+enter my ship doesn’t move what can be wrong???


  41. I’m stuck at
    the ship is gone again

    Step 2: Enter Frame Listener
    Engine.as, line 17:
    var ourShip:Ship = new Ship(stage);

    But if I write it like
    the ship comes back bus I can’t move it

    var ourShip:Ship = new Ship();


  42. theGrundy

    1137 Incorrect number of arguments. Expected no more then 0

    I was getting this error and it was as TheKanos said

    my linkage was not correct because I had named my action script (as) file using a lower case s and given my class an upper case S for Ship.

    I needed to ensure the class name and as file name where the same. Then it all linked up fine.


  43. Thank you for this Tutorial!


  44. Brian

    I’ve checked to make sure all linkage is correct and all spelling is right, caps and all, and I keep getting error 1046 at line 13 (private var key:KeyObject;) “type was not found or was not a compile-time constant: KeyObject.” and error 1180 at line 19 (key = new KeyObject (stageRef);) “Call to a possibly undefined method KeyObject.” Anyone have any idea what’s up with that?

    I’m loving these tutorials so far, thank you so much for writing them, they’ve really helped me a lot.


  45. Hello ,

    Thanks for the great tutorial!

    I fixed the 1136 problem by editing engine file

    var ourShip:ship = new ship();
    // add stage
    var ourShip:ship = new ship(stage);

    Maybe this work for you too


  46. i am new to OOP and using all these classes and shiz, I usually just hack away until something works… but this is great, I am understanding so much more. so thank you for teaching.

    But I have a question, about getting touch gestures to control the object instead of keystrokes… would I have to create a class to handle ‘touch and drag events’ similar to the KeyObject class and implement it that way? And I could then create another class to handle ‘pinch to zoom’? I wish I could just pop it in the ship class but that doesn’t work (#1046 on the 2 functions for start & stop dragging)


  47. Abz

    First of all great tutorial everything is working great for me, I understand most of the stuff you have gone through.

    i have a question i hope someone can answer or direct me to some source that may help.

    I am making a brickbreaker game and basically have got the paddle working correctly moving with both the mouse input and senoculars keyboard class. i also have a ball which is moving and bouncing off each wall of the stage.

    The problem i am having is making the ball bounce off the padde.
    i have an engine class, paddle class and ball class. i have tried many things but come up with similar errors.

    i need to be able to have the position of the paddle and the ball and use hittestobject. i have tried similar to what you have done in this tutorial but my target object cannot be found.

    my files are here if anyone can help would be very grateful.
    http://dl.dropbox.com/u/14908348/brickbreaker.rar


  48. someone pass by

    Can I ask why use “stageRef:Stage” instead of using “stage” directly?


  49. Rme

    Im sure this is a really stupid question, but in step 2, you write a method called loop ,and it reads.

    public function loop(e:Event) : void
    {
    y–;
    }
    what is e? I dont see it declared anywhere else, are you creating a variable called “e”, or is this referencing something I dont see?


  50. Drei

    I saved all the files into 1 folder and not the same as the files are arranged when I downloaded it.
    What is the correct code now for the script below since the files are in 1 folder already?

    package com.senocular.utils

    Will it work when I remove the com.senocular code and just put utils instead?


 
 



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