AS Gamer Limelight Tutorial

spotlight
An Even Better AS3 OOP Flash Custom Cursor In the last tutorial we created a custom cursor, in this tutorial we'll address some issue...

AS Gamer Spotlight Tutorials

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



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.

Flash Game, use arrow keys to move.

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.


Where to Go Next?


February 6th, 2009 | Tutorials |

27 Responses to “AS3 Flash Games for Beginners: Character Movement / Handling Multiple Keypresses”

  1. brandon says:

    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 says:

    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. refrag says:

    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 says:

    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 says:

    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 says:

    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 says:

    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 says:

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

  9. TheKanos says:

    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 says:

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

  11. Asker says:

    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 says:

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

  13. JaneRadriges says:

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

  14. Rob says:

    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 says:

    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 says:

    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 says:

    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 says:

    Excellent Comment BN, thanks a lot :D

  19. J says:

    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. says:

    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. says:

    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 says:

    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 says:

    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 says:

    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 says:

    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 says:

    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.

Leave a Reply

Sponsors & Links

Build Flash Online advertisement advertisement advertisement