AS3 Avoider Game Tutorial, Part 7: Keyboard Control

by Michael James Williams on February 17, 2009 · 258 comments

in Avoider Game Base,Tutorial

In this part of my AS3 and Flash CS3 conversion of Frozen Haddock’s avoider game tutorial, we’ll add keyboard controls. Don’t worry, we’ll keep the code separate so that it won’t interfere with the mouse controls we’ve already put in!

Click the image below to see how this will play:

screenshot

If you’ve not been following the tutorial, grab the zip file of the game so far here and extract it somewhere. Otherwise, copy the files you’ve been working on so far to a new folder, as usual.

Open the FLA file, and let’s get started.

Switching Control Schemes

Rather than removing the mouse controls entirely, let’s set things up so that we can switch between the two control schemes easily. Open AvoiderGame.as, and create a new Boolean variable at the class level named useMouseControl:

?View Code ACTIONSCRIPT3
8
9
10
11
12
13
14
public class AvoiderGame extends MovieClip 
{
	public var army:Array;
	public var enemy:Enemy;
	public var avatar:Avatar;
	public var gameTimer:Timer;
	public var useMouseControl:Boolean;

Remember, a Boolean is a variable that can only be one of two values: true or false. We’re going to use it as a “toggle”; if it’s true, mouse controls will work and keyboard controls won’t; if it’s false, keyboard controls will work and mouse controls won’t.

Since we haven’t written the keyboard control code yet, let’s set it to true so that we can test it out. The constructor is a fine place to do this:

?View Code ACTIONSCRIPT3
16
17
18
public function AvoiderGame() 
{
	useMouseControl = true;

Since useMouseControl is defined at the class level, it’ll be available throughout AvoiderGame.

At the moment, there are only two places where we’re referring to the mouse’s position in code. The first is in the constructor, where we set the initial position of the avatar to be wherever the cursor is:

?View Code ACTIONSCRIPT3
25
26
27
28
avatar = new Avatar();
addChild( avatar );
avatar.x = mouseX;
avatar.y = mouseY;

If the player’s not using the mouse to control the game, it’s going to be pretty annoying for them to have the avatar start out wherever the mouse happens to be. Let’s change that:

?View Code ACTIONSCRIPT3
25
26
27
28
29
30
31
32
33
34
35
36
avatar = new Avatar();
addChild( avatar );
if ( useMouseControl )
{
	avatar.x = mouseX;
	avatar.y = mouseY;
}
else
{
	avatar.x = 200;
	avatar.y = 250;
}

The code in the else section is only going to be run if the player is using keyboard control, and will place the avatar at the bottom-centre of the screen (adjust the numbers depending on what you think is best).

Before we test this, let’s change the other bit of code that references the mouse. It’s in the onTick() function and it’s exactly the same:

?View Code ACTIONSCRIPT3
54
55
avatar.x = mouseX;
avatar.y = mouseY;

Not surprisingly, our change will be very similar to before:

?View Code ACTIONSCRIPT3
54
55
56
57
58
59
60
61
62
if ( useMouseControl )
{
	avatar.x = mouseX;
	avatar.y = mouseY;
}
else
{
	//no keyboard code yet!
}

(Remember, line 61 is a comment and will be ignored by Flash; it’s just there as a reminder to us.)

If you save this and run it… well, you won’t see anything different, because we’ve set useMouseControl to true. That’s good, it means we can do whatever we like regarding keyboard control and it won’t mess up our existing mouse control code.

Change useMouseControl to false (in the constructor) and run it again.

screenshot

You’ll find the avatar starts at the bottom-centre of the screen and cannot be moved by the mouse. Great! Well, not so great for the player. But we’ll fix that.

Going Down

Remember when we first programmed the Enemy, and wrote the function moveDownABit()? By increasing the y-position of the enemy a little bit every tick, we simulated downwards motion. Let’s use the same strategy for the Avatar. Open up Avatar.as. It’s almost entirely empty — how exciting:

?View Code ACTIONSCRIPT3
1
2
3
4
5
6
7
8
9
10
11
package 
{
	import flash.display.MovieClip;
	public class Avatar extends MovieClip 
	{
		public function Avatar() 
		{
 
		}
	}
}

Add the new function:

?View Code ACTIONSCRIPT3
6
7
8
9
10
11
12
13
14
public function Avatar() 
{
 
}
 
public function moveDownABit():void
{
	y = y + 2;
}

Yep, this goes against what I said in the last part about hard-coding values. Don’t worry, we’ll change it soon.

The enemy objects have their movement functions called exactly once per tick. We need to call the appropriate movement functions for the avatar once per tick… but how do we know when it’s appropriate?

Ideally, we’d do something like this (in the onTick() function):

?View Code ACTIONSCRIPT3
54
55
56
57
58
59
60
61
62
63
64
65
if ( useMouseControl )
{
	avatar.x = mouseX;
	avatar.y = mouseY;
}
else
{
	if ( downKeyIsBeingPressed )
	{
		avatar.moveDownABit();
	}
}

In AS2 we could have done exactly that — but not in AS3. Now we’re living in the futuristic world of Events, and we have to do a little more to make this work.

You see, we can’t detect whether a given key is being pressed at a given time — that functionality is gone. But with event listeners, we can detect when a given key has been pushed down, and we can also detect when a given key has been lifted up again. If we have detected that a key has been pushed down and we have not yet detected that the same key has been lifted up, well, it’s a pretty safe bet that the key is being pushed down at that very moment, right?

[If this isn't clear, imagine that every time you press the B key, your computer says aloud "the B key has just been pressed", and every time you take your finger off the B key, your computer says "the B key is no longer being pressed". Someone listening to your computer would have a pretty good idea of whether or not you were pushing the B key even if they weren't looking at your hands.]

Enough talk. Let’s get the code in.

First, we need another Boolean to take note of whether the Down key is currently being pressed. Let’s call it downKeyIsBeingPressed. It needs to go in AvoiderGame.as, at the same places where we set up useMouseControl:

?View Code ACTIONSCRIPT3
14
15
16
17
18
19
20
public var useMouseControl:Boolean;
public var downKeyIsBeingPressed:Boolean;
 
public function AvoiderGame() 
{
	downKeyIsBeingPressed = false;
	useMouseControl = false;

(I’m assuming here that the player isn’t holding down the Down key as he starts the game.)

Now we need to detect when the player is pressing and releasing keys. You will probably not be surprised to find that we use event listeners for this. This should all be very simple to do, but unfortunately (and despite keyboard control being a Very Useful Feature for a lot of applications) Flash seems to go out of its way to make things confusing. Please bear with me through this next section, it’s not hard, just irritating :)

Flash vs. Developers

Let’s start by adding the event listeners. Add these lines to the end of the AvoiderGame.as constructor function:

?View Code ACTIONSCRIPT3
44
45
addEventListener( KeyboardEvent.KEY_DOWN, onKeyPress );
addEventListener( KeyboardEvent.KEY_UP, onKeyRelease );

Guess what? Yep, Flash needs to be told about KeyboardEvent, so import it at the top:

?View Code ACTIONSCRIPT3
3
4
5
6
7
import flash.display.MovieClip;
import flash.utils.Timer;
import flash.events.TimerEvent;
import flash.ui.Mouse;
import flash.events.KeyboardEvent;

First we’ll create the onKeyPress event listener, which will be triggered whenever a key is pushed down:

?View Code ACTIONSCRIPT3
49
50
51
52
public function onKeyPress( keyboardEvent:KeyboardEvent ):void
{
 
}

(Remember to create this outside of the constructor function but inside the class.)

How do we know which key is being pressed? Well, every key has a unique ID number, called a key code, and the event object stores the key code of whichever key triggered the event. Obviously it would be inconvenient if we had to remember every single ID, so Flash helps us out by giving us a class, Keyboard, that stores all these codes.

Of course, we have to import it:

?View Code ACTIONSCRIPT3
3
4
5
6
7
8
import flash.display.MovieClip;
import flash.utils.Timer;
import flash.events.TimerEvent;
import flash.ui.Mouse;
import flash.events.KeyboardEvent;
import flash.ui.Keyboard;

Go back to the onKeyPress event handler and add the following:

?View Code ACTIONSCRIPT3
50
51
52
53
54
55
56
public function onKeyPress( keyboardEvent:KeyboardEvent ):void
{
	if ( keyboardEvent.keyCode == Keyboard.DOWN )
	{
		downKeyIsBeingPressed = true;
	}
}

If you’re using Flash to write your AS files, then as soon as you type Keyboard. you’ll see a big list of all the different keys available appear.

The onKeyRelease event listener is very similar:

?View Code ACTIONSCRIPT3
58
59
60
61
62
63
64
public function onKeyRelease( keyboardEvent:KeyboardEvent ):void
{
	if ( keyboardEvent.keyCode == Keyboard.DOWN )
	{
		downKeyIsBeingPressed = false;
	}
}

Obviously it’s very important to have downKeyIsBeingPressed set to false here and true above.

Alright, so, in theory we should now be able to tell whether the Down key is currently being pressed from any point within AvoiderGame. This means we can add in our ideal code from earlier to the onTick() function:

?View Code ACTIONSCRIPT3
77
78
79
80
81
82
83
84
85
86
87
88
if ( useMouseControl )
{
	avatar.x = mouseX;
	avatar.y = mouseY;
}
else
{
	if ( downKeyIsBeingPressed )
	{
		avatar.moveDownABit();
	}
}

If you save it and run it this will not work. Sorry. We have to make a couple of changes first.

For one thing, Keyboard Event listeners have to be added to the stage. To quote the AS3 LiveDocs: “The Stage class represents the main drawing area. The Stage represents the entire area where Flash® content is shown.”

Simple enough. Go back to the constructor function and change the addEventListener calls from this:

?View Code ACTIONSCRIPT3
47
48
addEventListener( KeyboardEvent.KEY_DOWN, onKeyPress );
addEventListener( KeyboardEvent.KEY_UP, onKeyRelease );

to this:

?View Code ACTIONSCRIPT3
47
48
stage.addEventListener( KeyboardEvent.KEY_DOWN, onKeyPress );
stage.addEventListener( KeyboardEvent.KEY_UP, onKeyRelease );

Will this work now? No, we’ll get an error:

TypeError: Error #1009: Cannot access a property or method of a null object reference.

The problem is, stage is actually null at this point. Why? Well, an object only has access to stage if it’s been addChild-ed to the document class, or to another object that has been addChild-ed to the document class or… etc. But look at the code in DocumentClass.as:

?View Code ACTIONSCRIPT3
40
41
42
43
44
playScreen = new AvoiderGame();
playScreen.addEventListener( AvatarEvent.DEAD, onAvatarDeath );
playScreen.x = 0;
playScreen.y = 0;
addChild( playScreen );

The AvoiderGame() constructor function — and therefore the stage.addEventListener() lines — is run when new AvoiderGame() is run. But the addChild( playScreen ) line — which is required for playScreen to actually have a stage — isn’t run until after that point.

We get around this by using another event listener. This one is going to be triggered when that addChild( playScreen ) line is called. We can then add the stage.addEventListener() lines within that event handler. Confusing? Let’s write the code, it’ll make it clearer.

First, in AvoiderGame.as, replace

?View Code ACTIONSCRIPT3
47
48
stage.addEventListener( KeyboardEvent.KEY_DOWN, onKeyPress );
stage.addEventListener( KeyboardEvent.KEY_UP, onKeyRelease );

with

?View Code ACTIONSCRIPT3
46
addEventListener( Event.ADDED_TO_STAGE, onAddToStage );

(Don’t delete the onKeyPress and onKeyRelease event handler functions, we’ll need them later!)

Naturally we need to import this Event class…

?View Code ACTIONSCRIPT3
3
4
5
6
7
8
9
import flash.display.MovieClip;
import flash.utils.Timer;
import flash.events.TimerEvent;
import flash.ui.Mouse;
import flash.events.KeyboardEvent;
import flash.ui.Keyboard;
import flash.events.Event;

Now, create a new event handler for this Event.ADDED_TO_STAGE event:

?View Code ACTIONSCRIPT3
50
51
52
53
54
public function onAddToStage( event:Event ):void
{
	stage.addEventListener( KeyboardEvent.KEY_DOWN, onKeyPress );
	stage.addEventListener( KeyboardEvent.KEY_UP, onKeyRelease );
}

Save it and run it. Hooray, it works!

Although… try pressing any of the other keys on the keyboard while the game is running. You’ll probably notice the mouse flashing to different symbols. If you have the FLA open, rather than an AS file, you’ll be able to see the different buttons in the toolbar being selected as you press different letter keys.

This is another of Stephen Calender’s obstacles for Flash game development, and it’s incredibly irritating if you want to use keys that also happen to be used by Flash. Fortunately, there is a solution. When your game is running, click Control > Disable Keyboard Shortcuts:

screenshot

Voilà, no more problems.

[Jake let me know that this behaviour still exists in CS4 -- but luckily, so does the solution.]

Four-Way Movement

It’s now pretty simple to set the code up to detect other keys. Just take what we’ve already done and multiply it.

Class variables:

?View Code ACTIONSCRIPT3
17
18
19
20
21
public var useMouseControl:Boolean;
public var downKeyIsBeingPressed:Boolean;
public var upKeyIsBeingPressed:Boolean;
public var leftKeyIsBeingPressed:Boolean;
public var rightKeyIsBeingPressed:Boolean;

Constructor function:

?View Code ACTIONSCRIPT3
23
24
25
26
27
28
public function AvoiderGame() 
{
	downKeyIsBeingPressed = false;
	upKeyIsBeingPressed = false;
	leftKeyIsBeingPressed = false;
	rightKeyIsBeingPressed = false;

onKeyPress event handler:

?View Code ACTIONSCRIPT3
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
public function onKeyPress( keyboardEvent:KeyboardEvent ):void
{
	if ( keyboardEvent.keyCode == Keyboard.DOWN )
	{
		downKeyIsBeingPressed = true;
	}
	else if ( keyboardEvent.keyCode == Keyboard.UP )
	{
		upKeyIsBeingPressed = true;
	}
	else if ( keyboardEvent.keyCode == Keyboard.LEFT )
	{
		leftKeyIsBeingPressed = true;
	}
	else if ( keyboardEvent.keyCode == Keyboard.RIGHT )
	{
		rightKeyIsBeingPressed = true;
	}
}

I’ll leave you to figure out the onKeyRelease event handler :)

Perhaps you are thinking that I am a bit of a hypocrite, because back in Part 2 I said that it was bad to copy and paste code like that. Fair point! Actually, it would be much better to use an array of Booleans to store the states of every single key. I encourage you to have a go at that yourself (I did leave some hints in the comments of one of the earlier parts, if you get stuck). Alternatively, there’s a great piece of code here that’ll handle it all for you, the credit for which goes to the ever-excellent senocular. (If you’re having trouble getting this code to work, Monkeyman has written a great comment explaining what to do here.)

Now, I don’t fancy having four functions, moveDownABit(), moveUpABit(), etc., so I’m going to suggest we generalise moveDownABit(), just as we did with the Enemy code.

Go back to Avatar.as and change your moveDownABit() function to this:

?View Code ACTIONSCRIPT3
11
12
13
14
15
public function moveABit( xDistance:Number, yDistance:Number ):void
{
	x += xDistance;
	y += yDistance;
}

We now need to pass the directions through from AvoiderGame.as, so reopen that file. Start by changing what we already had, from this:

?View Code ACTIONSCRIPT3
109
110
111
112
if ( downKeyIsBeingPressed )
{
	avatar.moveDownABit();
}

to this:

?View Code ACTIONSCRIPT3
109
110
111
112
if ( downKeyIsBeingPressed )
{
	avatar.moveABit( 0, 3 );
}

That’ll work, but we shouldn’t be writing “3″ explicitely, should we? Try this instead:

?View Code ACTIONSCRIPT3
109
110
111
112
if ( downKeyIsBeingPressed )
{
	avatar.moveABit( 0, 1 );
}

And in Avatar.as:

?View Code ACTIONSCRIPT3
11
12
13
14
15
16
public function moveABit( xDistance:Number, yDistance:Number ):void
{
	var baseSpeed:Number = 3;
	x += ( xDistance * baseSpeed );
	y += ( yDistance * baseSpeed );
}

See what we’re doing? If not, let’s add in the other three directions and make it a bit clearer. Go back to AvoiderGame.as:

?View Code ACTIONSCRIPT3
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
if ( downKeyIsBeingPressed )
{
	avatar.moveABit( 0, 1 );
}
else if ( upKeyIsBeingPressed )
{
	avatar.moveABit( 0, -1 );
}
else if ( leftKeyIsBeingPressed )
{
	avatar.moveABit( -1, 0 );
}
else if ( rightKeyIsBeingPressed )
{
	avatar.moveABit( 1, 0 );
}

You see, the two parameters now define the direction of movement, rather than the speed. Speed is defined inside the Avatar class, which makes sense (and also follows the standard set by the Enemy class).

However, you can affect the relative speed of the avatar from the AvoiderGame class. For example, you could make WSAD the “walking” controls, which make the avatar move at half the speed, simply by adding lines like this:

?View Code ACTIONSCRIPT3
if ( sKeyIsBeingPressed )
{
	avatar.moveABit( 0, 0.5 );
}

Setting Some Boundaries

If you run the game now, you’ll see that it’s possible to move the avatar outside of the playing field, and therefore avoid all the enemies entirely!

To get round this, all we have to do is write some code to check, every tick, whether the avatar somewhere it shouldn’t be, and move it back into the playing field if so.

I think the best place for this is in AvoiderGame.as, in the onTick() function, immediately after all the code we’ve just written. Let me demonstrate with this code snippet:

?View Code ACTIONSCRIPT3
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
if ( useMouseControl )
{
	avatar.x = mouseX;
	avatar.y = mouseY;
}
else
{
	if ( downKeyIsBeingPressed )
	{
		avatar.moveABit( 0, 1 );
	}
	else if ( upKeyIsBeingPressed )
	{
		avatar.moveABit( 0, -1 );
	}
	else if ( leftKeyIsBeingPressed )
	{
		avatar.moveABit( -1, 0 );
	}
	else if ( rightKeyIsBeingPressed )
	{
		avatar.moveABit( 1, 0 );
	}
}
 
//we should check the avatar's position here
//and move it if we need to
 
var avatarHasBeenHit:Boolean = false;
for each ( var enemy:Enemy in army ) 
{
	enemy.moveABit();

Where isn’t the avatar allowed? Let’s start with horizontal movement: the avatar can’t go left of the playing field. Now, we know that the left side of the play screen has an x-coordinate of zero (check the diagram in the first part of this tutorial for a reminder). So if the avatar’s x-coordinate is less than zero, it must be to the left of the play screen:

?View Code ACTIONSCRIPT3
139
140
141
142
if ( avatar.x < 0 )
{
	//avatar is left of play screen
}

What shall we do about it? It’s pretty simple — we just move the avatar back to the left edge:

?View Code ACTIONSCRIPT3
139
140
141
142
if ( avatar.x < 0 )
{
	avatar.x = 0;
}

Actually, because the avatar’s registration point is right in its centre, half-way across its width, this will let the avatar get half-way out of the screen:

screenshot

You can keep it like this if you like, but I’d rather make sure the whole avatar was inside the screen. Fortunately this is easy too; we can just change our code like this:

?View Code ACTIONSCRIPT3
139
140
141
142
if ( avatar.x < ( avatar.width / 2 ) )
{
	avatar.x = avatar.width / 2;
}

If that’s confusing, just bear in mind that avatar.x refers to the x-coordinate of the centre of the avatar. The centre is, naturally, half a width away from the left-hand side. (Of course, if your avatar’s registration point isn’t centred, you’ll have to measure the distance yourself.)

This makes the avatar stop at the left side of the screen as if it were a wall:

screenshot

The other three directions can be added similarly:

?View Code ACTIONSCRIPT3
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
if ( avatar.x < ( avatar.width / 2 ) )
{
	avatar.x = avatar.width / 2;
}
if ( avatar.x > 400 - ( avatar.width / 2 ) )
{
	avatar.x = 400 - ( avatar.width / 2 );
}
if ( avatar.y < ( avatar.height / 2 ) )
{
	avatar.y = avatar.height / 2;
}
if ( avatar.y > 300 - ( avatar.height / 2 ) )
{
	avatar.y = 300 - ( avatar.height / 2 );
}

The numbers 400 and 300 are the width and height of my game. Bonus points for you if you use the soft-coding tip I talked about in Part 6 instead ;)

Challenges

We’re getting to the point now where you understand a lot of concepts, and it’s actually more beneficial for you to have a go at using them yourself rather than having someone else tell you every single step to take. If you’re lacking inspiration, here are some ideas to get you started.

How about changing the menu screen to have two buttons — one for mouse control, and one for keyboard control? Hint: pass the value of useMouseControl through the AvoiderGame() constructor, like we do with the enemy’s position in the Enemy() constructor.

You might have found that the game is considerably harder with keyboard controls than with mouse controls. How about altering the rate at which enemies appear if the player is using the keyboard?

You’ve got four-way movement sorted; now how about eight-way movement? Hint: you can check if ( ( downKeyIsPressed ) && ( leftKeyIsPressed ) ). Be careful — the Pythagorean Theorem tells us that if you move three pixels down and three pixels left within a single tick, you’ll travel further (and therefore faster) than if you just move three pixels down or three pixels left. How can you get around that? UPDATE: Rasmus Wriedt Larsen wrote a tutorial on doing exactly this. Check it out here.

It’s always irritating to have to switch between keyboard and mouse. Can you make it so that the Start and Restart buttons can be pressed by hitting the space bar?

Don’t forget to have a go at making an array of booleans to hold the state of all your keys at once, or to use senocular’s KeyboardObject class, as mentioned above.

If you’d like a hand with any of these challenges, stick a note in the comments box below. If you’ve got any of your own, I’d love to hear them :)

Wrapping Up

That’s it for this week. As usual you can grab the zip file here.

In Part 8, we’ll add a preloader, an essential requirement for any Flash game.

{ 258 comments… read them below or add one }

Monkeyman June 30, 2010 at 9:42 pm

@Michael: That sounds like a good idea, and I’d love to do it, but we’ll see. I’m actually having trouble putting up my tutorials lately, as my internet connection has been all but completely unresponsive. It takes forever to accomplish anything, including uploading videos to Youtube. But there is a possibility of getting faster internet, so I’m hopeful things can get better.

Michael Williams July 5, 2010 at 7:49 pm

Dang, Monkeyman, that’s irritating. I hope you get your internet sorted!

Doom July 5, 2010 at 11:40 pm

Hi,
I have a noob question :3 (I’m trying to figure out the Challenges).
I added a new button on the main screen, one to handle mouse controls, the other for keyboard.

And since we have a “public var useMouseControl:Boolean;” that pretty much controls if Mouse or keyboard is being used, I thought it would be an easy fix..

So in my DocumentClass.as i tried to change the “useMouseControl” value from true to false depending on what button i press. But I am unsure how to change that value from another class. Just typing “useMouseControl = true;” didn’t work.

But as soon as i typed “playScreen.useMouseControl = true;” it works. How come? I can understand if i have to type “AvoiderGame” before useMouseControl but why playScreen? :) thanx

Michael Williams July 7, 2010 at 6:55 pm

Hey Doom, good question.

Remember that playScreen is an instance of the AvoiderGame class.

Think of it this way: if you want to control the x property of a specific enemy, you don’t write:

Enemy.x = 10;

…you write:

enemy.x = 10;

…where enemy (small “e”) is an instance of the Enemy class.

Does that help? We can talk about this some more if you like.

Doom July 8, 2010 at 12:12 am

Hi,
Yeah I understand it a bit better now thanx :)
But I’m still curious of why the “playScreen” part has to be there at all.

I’m used to Lingo (script language to Macromedia Director), where i just say “global enemy” and the enemy value is accessible from anywhere. No need to type playScreen.Enemy. Just “Global enemy / enemy = 1″ etc.

So I find it confusing and a bit irritating if I have to locate exactly where a value is kept, if I wan’t to access it from another class :/ (is there a nice tutorial explaining in more depth how to use these things? :) )

Michael Williams July 8, 2010 at 1:47 pm

Hey Doom,

I’m working on it ;)

I know this’ll sound like a lame answer, but basically… that’s just the way it is. AS2 had global variables, but in AS3 every variable belongs to an object, and every object is an instance of a class. (That’s why AS3 is called an “object oriented” programming language.)

As for it being confusing, think about this: imagine that I write “global x” inside Enemy and also inside Avatar. Then, in AvoiderGame, I write “x = 10;”. What’s that going to do?

Doom July 8, 2010 at 1:54 pm

Hi,
Ah ok i see. Well then i guess I’ll just have to learn how to use this system :)
Really good that you’re working on a tutorial, will help me alot to understand it better.

And yeah I agree that problems may occur when using globals (as in your example), but I always tend to make unique Globals. So if done right, it rarely causes any trouble :)

Big thanx for the awnsers!

Nando July 10, 2010 at 6:18 am

Hi i have a problem because i tri to make what you said about change between keyboard and mouse with space bar so i add :

if( keyboardEvent.keyCode == Keyboard.SPACE)
{
         useMouseControl = !useMouseControl;
}

in the onKeyPress Function so i can switch betweenkeyboard an mouse but my problem is that while i use the keyboard, the mouse still in the same place so when i change to mouse mi buddy jump from one place to another and i don’t find a function or a variable to make a function with that change the position of the mouse. Can you help me??

Thank a lot by the way!!

Michael Williams July 23, 2010 at 11:55 am

@Doom: Unique globals, okay, yeah, I guess that’d help :) But what if you want to use the same files in different projects? Or to share files with other people?

@Nando: I’m a little confused about what you mean. When you’re using the keyboard, the avatar is still following the mouse? Is that right?

Bigfoot August 4, 2010 at 6:51 pm

I’m going through your tutorials again… I worry that because I haven’t been using it, I won’t remember anything, but going through it again I find that I remember more and understand more every time. :)
I was trying to make the space bar start the game from the menu screen without looking at code I’ve already created, and happily I was successful. But I was having a weird problem, where even after the game started if I pressed the space bar the game would “restart” – or seem to, it was really just throwing another instance of playScreen on top of the one I was currently playing.
After reading your comments I think this is something that will be fixed in chapter 12 on focusing, but as a band-aid solution I changed my onStart function (within DocumentClass) to look like this:

public function onStart( navigationEvent:NavigationEvent ):void
{
    if( playScreen == null )
    {
        playScreen = new AvoiderGame();
        playScreen.addEventListener( AvatarEvent.DEAD, onAvatarDeath );
        addChild( playScreen );

    menuScreen = null;
}

}

In that way I check if playScreen is still null, and only if it is will I create an instance of playScreen. Using trace() I can see that menuScreen is still ‘hearing’ me press the space bar, so it’s not a perfect solution… ;)

Josh August 20, 2010 at 4:00 pm

Pretty sure you hate me by now, but I have a question.

I was messing with the keyboard controls and such, and doing things my way (which makes things more complicated than they should be because I fail at this), I’ve come to the conclusion that some things aren’t needed…

anywho, the code in my playscreen class is:
It’s basically how you make the keyboard work, the if statements for the booleans seem pointless to me, why not just stick it in the other if statements?

package  {

import flash.display.MovieClip
import flash.utils.Timer
import flash.events.TimerEvent
import flash.events.Event;
import flash.events.KeyboardEvent;
import flash.ui.Keyboard;

public class PlayScreen extends MovieClip

{
public var avatar:Avatar;
public var gameTimer:Timer;
public var downIsPressed:Boolean;
public var upIsPressed:Boolean;
public var leftIsPressed:Boolean;
public var rightIsPressed:Boolean;

 public var speedX:Number = 0;
 public var speedY:Number = 0;
 public var friction:Number = 0.98;
 public var ax:Number = 0;
 public var ay:Number = 0;

public function PlayScreen()        
{
    avatar = new Avatar;
    addChild(avatar);

    gameTimer = new Timer(25);
    gameTimer.addEventListener(TimerEvent.TIMER, onTick);
    gameTimer.start();

    addEventListener( Event.ADDED_TO_STAGE, onAddToStage );
}
public function onAddToStage(event:Event)
{
    stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyPress);
    stage.addEventListener(KeyboardEvent.KEY_UP, onKeyRelease);
}
public function onKeyPress(keyboardEvent:KeyboardEvent):void
{

    if(keyboardEvent.keyCode == Keyboard.DOWN)
    {
        downIsPressed = true;
        trace("a down was pressed");
    }
    else if(keyboardEvent.keyCode == Keyboard.UP)
    {
        upIsPressed = true;
    }
    else if(keyboardEvent.keyCode == Keyboard.LEFT)
    {
        leftIsPressed = true;
    }
    else if(keyboardEvent.keyCode == Keyboard.RIGHT)
    {
        rightIsPressed = true;
    }

    if(downIsPressed)
    {
        ay = 0.5;
        trace("downwaspressed")
    }
    if(upIsPressed)
    {
        ay = -0.5;
    }
    if(leftIsPressed)
    {
        ax = -0.5
    }
    if(rightIsPressed)
    {
        ax = 0.5
    }

}
public function onKeyRelease(keyboardEvent:KeyboardEvent):void
{
    ay = 0;
    ax = 0;
    if(keyboardEvent.keyCode == Keyboard.DOWN)
    {
        downIsPressed = false;
    }
    else if(keyboardEvent.keyCode == Keyboard.UP)
    {
        upIsPressed = false;
    }
    else if(keyboardEvent.keyCode == Keyboard.LEFT)
    {
        leftIsPressed = false;
    }
    else if(keyboardEvent.keyCode == Keyboard.RIGHT)
    {
        rightIsPressed = false;
    }


}
public function onTick(timerEvent:TimerEvent):void
{
    speedX = speedX * friction;
    speedY = speedY * friction;
    speedY = speedY + ay;
    speedX = speedX + ax;




    avatar.moveABit(speedX,speedY)




}

}

}

Michael Williams August 21, 2010 at 12:34 am

Sorry for the delay on these replies.

@Bigfoot: Bigfoot! Long time no speak — how’ve you been? Shoot me an email some time :)

Good call — this is something that will be addressed in Chapter 12. (It’s basically because the event listener gets attached to the stage, rather than to the menu screen, and therefore remains even after the menu screen has been removed.) Cool solution though!

@Josh: Haha not at all; questions are good. It’s great to see you experimenting with doing things your own way.

Interesting point. No, in this case, there’s no need to keep the if-checks for downIsPressed, upIsPressed, etc. separate to the checks for keyboardEvent.keyCode. My code differs a bit: the if-checks for downIsPressed, upIsPressed etc. all cause the actual movement, and so should go in the onTick() function. In your code, they don’t cause the movement — I mean, they don’t call the avatar.moveABit() function — so they don’t need to go in onTick().

You’ve still got the actual call to avatar.moveABit() in onTick(), which is just as it should be :)

Josh August 21, 2010 at 7:10 pm

Hi, I know this is completely off topic, but can you explain:

rotation = Math.atan2(mouseY – y, mouseX – x) / Math.PI * 180;

to me?
I found it online as a way for an object to rotate to follow the mouse (it’s not actually working for me, but seeing as I don’t know what it’s doing I can’t actually try and fix it)
All I know is that it’s getting (I think) the tan of (mouseY-y)-(mouseX-x) then dividing it by pi and timesing it by 180… I assume the 180 is for the actual angle portion of getting a rotation number, but I don’t know how the rest of it works.

If you do happen to mind, can you point me to something to read about it?

Josh August 21, 2010 at 7:15 pm

Oops!
I actually found:

instanceNameOfArrowClip.onMouseMove = function() {
    this._rotation = Math.atan2(_root._ymouse - this._y, _root._xmouse - this._x) / Math.PI * 180;
    updateAfterEvent();
};

But changed it to go into my “moveABit” function in the avatar class to what it is above.

Michael Williams August 22, 2010 at 6:47 pm

Hey Josh,

I’ve actually written about angles before in a separate post: Angles in Flash. Check it out, and if it doesn’t answer your question, please post the same question in the comments of that post.

Snowcap August 23, 2010 at 7:34 am

Hello Michael,

I have a question, but before I get to that I would like to comment on your tutorials. They are some of the best I’ve seen. Your explanations are clear and to the point (and you do not repeat yourself =] ).

Anyways I’ve made a couple of side scrollers and found this useful for setting the boundaries…

function checkKeys() {
    if(Key.isDown(Key.RIGHT) && spriteX < 510) {
    spriteX += steps;
    knight.legs.play();
    } else if(Key.isDown(Key.LEFT) && spriteX > 40) {
    spriteX -= steps;
    knight.legs.play();
    }
    if(Key.isDown(Key.UP) && arrowActive == false) {
        knight.arms.play();
        attachMovie("arrow","arrows", 8);
        arrows._x = spriteX;
        arrows._y = spriteY + 50;
        arrowActive = true;
    }
}

510 is the right side of the stage and 40 is the left.

The way you showed it works great as well, but the constant bouncing back into the stage was annoying to me. I thought it would look better without the constant repositioning…

I tried implementing something like this on the avatar, but I failed =(

I tried placing these bounds in the onTick constructor, but like I said Fail. Could you give me some help?

Thank you

Snowcap August 23, 2010 at 7:49 am

Ok so I fixed some things and realized that there is no constant bouncing… lol XD
But can you still explain to me why it won’t let me do it this way.

Michael Williams August 23, 2010 at 4:39 pm

Hey Snowcap, thanks for the kind words!

Nice technique, separating the position from the object like that.

What’s your code for the avatar like at the moment? Why does it fail?

Snowcap August 23, 2010 at 6:59 pm

Hey Michael,

so this is the if statement in the onTick function that checks whether to use mouse controls or keyboard controls. avatarX and avatarY are public vars that I instantiated in the AvoiderGame class and they have the values of avatar.x and avatar.y respectively. winHeight = window height, winWidth = window width.

            /* If useMouseControl is true then mouse controls are selected,
               Else keyeboard controls are selected.*/
            if(useMouseControl) {
                avatar.x = mouseX;
                avatar.y = mouseY;
            } else {
                if(downKeyIsBeingPressed && avatarY < winHeight) {
                    avatar.moveABit(0, 1);
                } else if(upKeyIsBeingPressed && avatarY > 0) {
                    avatar.moveABit(0, -1);
                } else if(rightKeyIsBeingPressed && avatarX < winWidth) {
                    avatar.moveABit(1, 0);
                } else if(leftKeyIsBeingPressed && avatarX > 0) {
                    avatar.moveABit(-1, 0);
                }
            }

Is it in the wrong if statements?

Thanks

Snowcap August 23, 2010 at 7:12 pm

Sorry for putting this into two comments, just realized I never explained how it was failing. At first avatar would just go out of bounds. Then I found the problem. Now its the issue where half of the avatar is in bounds and the other half is out. I’m pretty sure I need to use the avatar’s width / 2 and height / 2, but how would I put that in the if statement?

Thanks again =)

Rootzm August 25, 2010 at 5:22 am

I’m having some trouble with getting the switch between keyboard and mouse control. I’m getting an error code “1180: Call to a possibly undefined method controlScheme” when I try to call the “controlScheme” function in the AvoiderGame.as file. Here are some code changes I’ve made below. If anyone could help, that would be great.

AvoiderGame.as
deleted line:

useMouseControl=false;

added function:

public function controlScheme (controlSchemeVar:Number)
        {
            if (controlSchemeVar == 1)
            {
                useMouseControl = true;
            }
            else if (controlSchemeVar == 2)
            {
                useMouseControl = false;
            }

    }

NavigationEvent.as
added:

public static const TOGGLE:String ="toggle";

MenuScreen.as
added where toggleKM is the instance name of my button to be pushed as a toggle between keyboard and mouse:

public function MenuScreen() 
        {
            Mouse.show();
            startButton.addEventListener( MouseEvent.CLICK, onClickStart );
            toggleKM.addEventListener (MouseEvent.CLICK, onClickToggle);
        }

added function:

public function onClickToggle (event:MouseEvent):void
        {
            dispatchEvent (new NavigationEvent (NavigationEvent.TOGGLE));
        }

DocumentClass.as
added class variable:

public var toggleVariable:Number = 1;

added to document class function:

menuScreen.addEventListener (NavigationEvent.TOGGLE, onRequestToggle);

added new public function:

public function onRequestToggle(navigationEvent:NavigationEvent):void
        {
            if (toggleVariable == 2)
            {
                toggleVariable -= 1;
            }
            else
            {
                toggleVariable += 1;
            }
        }

Revised onRequestStart function:

public function onRequestStart( navigationEvent:NavigationEvent ):void
        {

        playScreen = new AvoiderGame();
        playScreen.addEventListener( AvatarEvent.DEAD, onAvatarDeath );
        playScreen.x = 0;
        playScreen.y = 0;
        addChild( playScreen );

    controlScheme(toggleVariable);

    menuScreen = null;
}   

I’m almost there with this method but it doesn’t like my variable set up or something. I hope my code formatting worked for this post. If it would be better to email someone my file, I can do that too.

Michael Williams August 27, 2010 at 11:57 pm

@Snowcap: How’s your algebra? You’re going to need it ;)

(Hint: Remember that avatar.x (and avatarX) are set to the centre point of the avatar, not either edge.)

@Rootzm: Thanks for the detailed breakdown, makes it much easier!

You have the right idea, and you’re really close to getting this working. In fact, I think the only problem is in your DocumentClass.onRequestStart() function, where you call controlScheme(toggleVariable). Calling it like that, it’s trying to run DocumentClass.controlScheme(toggleVariable), and that doesn’t exist — hence the error.

I don’t want to spell it out because that would rob you of solving the last piece, so have another look at that line and let me know if you need another hint :)

Rootzm August 29, 2010 at 6:47 pm

Thank you for your help. That did the trick. I was not referencing the class before calling the function as you hinted. I ended up having another problem where I was trying to call AvoiderGame.controlScheme(toggleVariable). I wasn’t using the instance of the class instead of the class itself. Rookie mistake.

Now I’m trying to get the mouse/keyboard decision on an Options screen linked from the main menu. I got it semi-working but am having problems with the variables I assign getting wiped out as navigation screens get nulled (i think that’s what’s happening). I may just make a globalvariable class that doesn’t get nulled and see how it goes. Maybe not the most efficient? I need to read and research on it.

Anyway. I’m rambling. Thanks again for the help

Michael Williams August 30, 2010 at 10:56 pm

Awesome :)

Hmm, not sure what you mean about the variables getting wiped out, but if the classes containing those vars get removed then yeah that could cause a problem.

Allie August 31, 2010 at 4:18 pm

I am beyond stuck on the first challenge. I don’t even know what the problem is to ask for help on. All it’s saying is 1120: Access of undefined property useMouseControl. I have no idea where to define it, I have no idea what’s going on.

Sorry to be such a noob, but please help :S

Mushyrulez September 1, 2010 at 4:07 am

In AvoiderGame.as, under ta class functions, do ya have something like this?

public var useMouseControl:Boolean;

If ya don’t then ya need ta add that :P (rereading articles help solve ta problem 90% of ta time!)

Allie September 1, 2010 at 9:23 am

Yeah I already had that in there. I’ve fiddled around and somehow managed to get it to the point where it’s not broken… but it’s not working still if you get what I mean. There are no compiler errors, but now both the “start with mouse” and “start with keyboard” buttons use the mouse.

I’ve reread the tutorial what seems like a thousand times, I just can’t seem to get Flash (CS4 for the record, so I don’t know if things are different) to understand that I want the “start with keyboard” button to use the keyboard!

Mushyrulez September 3, 2010 at 11:56 pm

Constructor function, useMouseControl = true?

:P That’s the only thing I can think of.

Narinik September 13, 2010 at 10:28 pm

I dont know about other people but I like being able to move my characters in a direction and speed, and with their speed defined in their own classes i just have to pass them a direction. so i modifed the moveABit(0,1) etc to read moveABit(90).(down)

so the moveABit function looks like

x += (Math.cos(dirpi180) * baseSpeed);
y += (Math.sin(dirpi180) * baseSpeed);

in the class i set

public static const pi180:Number = Math.PI/180;

so i only have to calc it once and all the instances can ref it. now i can just pass whatever degree i want the avatar to go in eg moveABit(45) and he will go down and right.

in flash 0 degrees is right.

Narinik September 13, 2010 at 10:30 pm

Whoops that should be

x += (Math.cos(dir * pi * 180) * baseSpeed);
y += (Math.sin(dir * pi * 180) * baseSpeed);

need to multiply the degree(in degrees) by PI/180 to convert to radians, wich is what the Math.cos/sin functions expect.

Michael Williams October 4, 2010 at 10:17 pm

I’m back from holiday!

@Mushyrulez: Good points, either of those could well be (have been) the problem.

@Allie: Still stuck on this? I’m back now.

@Narinik: Good tip, thanks!

Rob October 5, 2010 at 4:02 pm

Hey there, Michael. Thanks for the great tutorials! They’ve been really helpful and I refer to them a lot.
I’ve still been having a problem with the KEY_UP event. (Sorry if it’s not appropriate to post a link to a game I made, but the problem I’m talking about occurs occassionally in the game). In the platform game here…
http://www.girlguiding.org.uk/guides/games/jumpup.htm
…when you move left or right, sometimes the KEY_UP event doesn’t seem to trigger for a few seconds. It’s as if the key presses are ‘cached’ somehow, but I know that’s not what’s happening.
I’ve basically got KEY_DOWN and KEY_UP listeners set up on the stage in my Game class with listener functions that trigger booleans that correspond to the arrow keys and space bar. Functions elsewhere use the booleans to determine if the character should move (virtually identical to the avoider game).
Do you think it might have something to do with focus? But then why does it only do it occassionally, and why, if focus has changed, does the key work once again a few frames later?
A bit puzzled, so any tips would be well appreciated.
Cheers.

Michael Williams October 6, 2010 at 1:05 am

Hey Rob,

You made an official game for the UK Girl Guides? That’s pretty cool :)

Yeah, I see the problem you’re talking about. When you run the game through Flash CS, does it display any messages in the Output panel?

Rob October 6, 2010 at 9:08 am

Hey there, again.
Thanks for the quick reply (and sorry for bugging you so soon after your holiday).
It doesn’t generate any errors, if that’s what you mean. I’ve still got two traces in there, so those still generate output. But no errors.
I’ve been wondering if later levels SEEM to run a bit slower, so maybe I missed a ‘removeEventListener’ somewhere or something’s running that’s not supposed to – but I think I’ve been pretty careful about all that (removing all of the event listeners before removing each game level and so on).
It doesn’t do it very often, but it’s slightly annoying that it does it at all. I had decided to ignore it, but a few people who I got to test the game noticed it too.

Michael Williams October 7, 2010 at 3:47 am

Hey Rob,

No worries. I actually got back a couple weeks ago, so I’m well rested now ;)

Try removing the traces (there’s an option that allows you to omit traces automatically in the Publish Settings if you prefer). I’ve found that traces slow games down massively, which is incredibly annoying when you’re trying to debug something.

Alan November 4, 2010 at 5:54 pm

Hi! I have a quick one.

Concerning that .width property you used for avatar.width . I was thinking of using it to avoid hard-coding while making my enemies (since I don’t want them to spawn sliced from the left and right sides of the screen as well).

My original code was:

var randomX:Number = Math.random()750+25;

That’s with my enemy 50 pixels wide (my screen is 800, so 750 = 800-225 , 25=50/2; a bit large, I know, planning to change it later). I tried to avoid writing that half-width numerically in the equation.

Now I thought it to be something like this:

var driftX:Number =DocumentClass.SCREEN_HEIGHTEnemy.xSpeed;
var randomX:Number =Enemy.width+Math.random()(Math.abs(driftX)+DocumentClass.SCREEN_WIDTH-2*Enemy.width)-driftX;

(I’ve added the functionality to have enemies appear all over the screen even if the xSpeed != 0)
Here I have plenty of static constants and variables, and I was planing to avoid using them at least for the width and height of the enemy. But, the .width can be used only with instances, not classes (that was my conclusion, anyway). Which is OK, except that I need the width value before I actually make an instance of Enemy (since I need the randomX position). Can I somehow get those values through the class or something, or should I just make more constants? And isn’t there a way to get the screen (or stage, whatever) size through a command or property? (using .width and .height on playScreen crossed my mind, but I’d rather not do that if I can avoid it). I would really like to experiment with my design (since I’m drawing my own graphics) without having to change the code every time I change a dimension.

This wasn’t so quick after all :P My bad. Also, I tried to be clear, but I’m not that good at English so if you can’t understand a part of what I’ve said ask me and I’ll try to clarify.

Alan November 4, 2010 at 5:56 pm

EDIT: note that some asterisks made my code look commented. Please ignore that :P

Jorge Lara December 21, 2010 at 10:39 pm

Hi, I’m trying to modify code for START with a spacebar, likke this:

public class MenuScreen extends MovieClip 
    {
        public function MenuScreen() 
        {
            StartButton.addEventListener( MouseEvent.CLICK, onClickStart );
            MouseControl.addEventListener( MouseEvent.CLICK, onClickMouseControl );
            addEventListener(KeyboardEvent.KEY_DOWN, onKey );

as you saw, i want to add an Event Listener for keyboar, but it only “listen” if (first) I click on the screen, what can i do so solve?
thanks.

Robert January 25, 2011 at 10:53 pm

I used the keyboard control method described here and applied it to another game, but I replaced onTick with my function, but my function doesn’t seem to work :/. What could be the problem?

public function moving() {
            if ( downKeyIsBeingPressed ) {
                player.moveABit( 0, 1 );
            } else if ( upKeyIsBeingPressed ) {
                player.moveABit( 0, -1 );
            } else if ( leftKeyIsBeingPressed ) {
                player.moveABit( -1, 0 );
            } else if ( rightKeyIsBeingPressed ) {
                player.moveABit( 1, 0 );
            }
        }

Mohammed Abdulqadir April 19, 2011 at 6:39 pm

 hi i need you help in fixing you coding 
your coding does not let the character move in two ways in the same time so if you can fix it please 
and please contact me at st1021080185@iat.ac.ae 

Mohammed Abdulqadir April 27, 2011 at 5:00 pm

 hi can any one help me to fix this coding i need it to be able to move the character in two direction please answer fast this is important and please contact me at st1021080185@iat.ac.ae

maxG May 31, 2011 at 11:07 am

great tutorial, i am following it for a school project and have done most of your challenges but i have no idea what to do for different buttons for different control schemes besides make another button and give it an instance name, could you please “start me off ” on the coding or atleast give another hint

Michael James Williams May 31, 2011 at 6:40 pm

Hey maxG!

First thing to do is to get another button doing something, anything. Insert a trace() statement that just says, “hi, you clicked me” when you click it.

Next thing to do is to make it possible to change your control scheme by changing one variable. Like, you have a Boolean called useKeyboard or whatever, and when you set it to “true” it means the keyboard is used.

Then hook the two up!

maxG May 31, 2011 at 9:08 pm

hmm thanks, i now have a useMouseControl and a useKeyboardControl Boolean that can each change the control scheme and two buttons that each can take you to the the playscreen but i don’t know how to code it so one takes you to a playScreen where useMouseControl = true;
and the other to a playScreen where useKeyboardControl = true; i feel close but i think i might need another hint

maxG June 4, 2011 at 11:04 am

here is my code:

 menuScreen.addEventListener( NavigationEvent.START, onRequestStart ); menuScreen.addEventListener( NavigationEvent.KEYBOARD, keyboardControl );

public function onRequestStart( navigationEvent:NavigationEvent ):void
{
playScreen = new AvoiderGame();
playScreen.addEventListener( AvatarEvent.DEAD, onAvatarDeath );
playScreen.x = 0;
playScreen.y = 0;
addChild( playScreen );
useMouseControl = true;
menuScreen = null;
}
public function keyboardControl( navigationEvent:NavigationEvent ):void
{
playScreen = new AvoiderGame();
playScreen.addEventListener( AvatarEvent.DEAD, onAvatarDeath );
playScreen.x = 0;
playScreen.y = 0;
addChild( playScreen );
useKeyboardControl = true;
menuScreen = null;
} this is in my document class and i have added a new NavigationEvent of KEYBOARD i have no compiler errors but useMouseControl and useKeyboardControl don’t do anything in my document class but they do in my avoidergame class

Tyler S June 9, 2011 at 9:32 pm

Hey Michael,

I think this is a great tutorial and it has really helped me start leaning how to code, however i am completely baffled on the last “challenge” of using an array of booleans to hold the state of all the keys at one time and was wondering if you could give me a hint or two

Thanks,
Tyler

GabeTHEGeek July 24, 2011 at 2:27 pm

I had major issues with this is CS5 when coding the keyboard events. I kept getting a

“1119: Access of possibly undefined property keyCode through a reference with static type flash.events:Event.”

To solve this I changed the code from::

public function onKeyRelease( keyBoardEvent:KeyboardEvent ):void
        {
            if ( keyBoardEvent.keyCode == Keyboard.DOWN )
            {
                downKeyIsBeingPressed = false;
            }
        }

To this :::


public function onKeyRelease(event:KeyboardEvent ):void
        {
            if ( event.keyCode == Keyboard.DOWN )
            {
                downKeyIsBeingPressed = false;
            }
        }

I figure it was a CS5 problem more than a AS3 problem. I just thought I'd post it if anyone else had an issue.

Kevin February 9, 2012 at 6:46 pm

Hey, i am trying to do the “press space” for restart button, it works fine when i lose i press space but if i restart again any other key i press makes me restart.. I’m trying to figure it out but idk how.. :/

my GameOverScreen.as

package 
{
    import flash.display.MovieClip;
    import flash.display.SimpleButton;
    import flash.text.TextField;
    import flash.events.KeyboardEvent;
    import flash.ui.Keyboard;
    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.ui.Mouse;

public class GameOverScreen extends MovieClip 
{
    public var spaceKeyIsBeingPressed:Boolean;

public function GameOverScreen() 
{
    spaceKeyIsBeingPressed = false;
    Mouse.hide();
    restartButton.addEventListener( Event.ADDED_TO_STAGE, onAddToStage );
}

public function onAddToStage( event:Event ):void
{
    stage.addEventListener( KeyboardEvent.KEY_DOWN, onKeyPress );
    stage.addEventListener( KeyboardEvent.KEY_UP, onKeyRelease );
} 

public function onKeyPress( keyboardEvent:KeyboardEvent ):void 
{
    dispatchEvent( new NavigationEvent( NavigationEvent.RESTART ) );
}

public function onKeyRelease( keyboardEvent:KeyboardEvent ):void
{
    if ( keyboardEvent.keyCode == Keyboard.SPACE )
    { 
        spaceKeyIsBeingPressed = false;
    }
}
public function setFinalScore( scoreValue:Number ):void
{
    finalScore.text = scoreValue.toString();
}

public function setFinalClockTime( clockValue:Number ):void
{
    finalClockTime.text = Math.floor( clockValue / 1000 ).toString();
}

}

}

Kevin February 9, 2012 at 6:50 pm

Hey, i’m trying to do the “press space” challenge for my restart button, but when i lose, i click space it restarts but i can’t move again any key i press “restarts” the game over and over!
here’s my codes in GameOverScreen.as:

package 
{
    import flash.display.MovieClip;
    import flash.display.SimpleButton;
    import flash.text.TextField;
    import flash.events.KeyboardEvent;
    import flash.ui.Keyboard;
    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.ui.Mouse;

public class GameOverScreen extends MovieClip 
{
    public var spaceKeyIsBeingPressed:Boolean;

public function GameOverScreen() 
{
    spaceKeyIsBeingPressed = false;
    Mouse.hide();
    restartButton.addEventListener( Event.ADDED_TO_STAGE, onAddToStage );
}

public function onAddToStage( event:Event ):void
{
    stage.addEventListener( KeyboardEvent.KEY_DOWN, onKeyPress );
    stage.addEventListener( KeyboardEvent.KEY_UP, onKeyRelease );
} 

public function onKeyPress( keyboardEvent:KeyboardEvent ):void 
{
    dispatchEvent( new NavigationEvent( NavigationEvent.RESTART ) );
}

public function onKeyRelease( keyboardEvent:KeyboardEvent ):void
{
    if ( keyboardEvent.keyCode == Keyboard.SPACE )
    { 
        spaceKeyIsBeingPressed = false;
    }
}
public function setFinalScore( scoreValue:Number ):void
{
    finalScore.text = scoreValue.toString();
}

public function setFinalClockTime( clockValue:Number ):void
{
    finalClockTime.text = Math.floor( clockValue / 1000 ).toString();
}

}

}

Kevin February 9, 2012 at 6:53 pm

Sorry seems i typed it twice :/ i’m having a connection problem :/

Leave a Comment

Writing code? Write <pre> at the start and </pre> at the end to keep it looking neat.

Anti-Spam Protection by WP-SpamFree

Previous post:

Next post: