Hello there. This is the sixth part of the Making Games in ActionScript 3 using FlashDevelop
By now we’ve got almost all the basic building blocks to make a simple game. All that is missing is how to get some input. Last time we touched on it a little bit using the mouseX and mouseY properties.
Those are the most straightforward to get at, but other inputs aren’t very complicated either. Let’s start with the mouse button.
Note that it’s mouse button, not buttons, one of the limitations of the Flash platform is that you only have access the to the left click.
Right click gives a menu, and there’s no getting around that.
To get the most of out of this part we need to start with making a Player class. Check back in part three for how to add a class but name it Player this time. Add an instance of the player to your Main class and make sure it’s on the stage. If you’re too lazy just get the prepared project here.
Getting input brings us back to the event handling we started with in last part, in your Enemy class’ constructor add an event listener for MouseEvent.CLICK:
addEventListener(MouseEvent.CLICK, handleClick);
Once this is done we add the handler method, use the neat CTRL+1 autocompletion or just type this out (copypaste is cheating).
private function handleClick(e:MouseEvent):void {
trace("clicked enemy");
}Give the Enemy a click, and gasp at the fantasticness of the traced output. You will notice that if you click outside the enemy nothing is traced. This is because we are listening for clicks on that specific object. If you add multiple enemies they will each have their own handler for clicks.
Sometimes this is great, other times, not so great. What if you have a whole bunch of enemies and want to do something in your main class when any one of them is clicked. You can use this exact method and let the enemy call a function on your Main class, but that’s not very pretty code.
Adding a listener to each one from the Main class is a possibility, since a handler can handle events from many “dispatchers” (things that broadcast events are called dispatchers). But, we don’t want to repeat ourselves unless we absolutely have to.
So, we’re going to do it the neat way. Add another listener, this time in the Main class. Do it the exact same way, but let’s put a different trace in so we can tell them apart:
private function handleClick(e:MouseEvent):void {
trace("clicked in main");
}For this example to work we’ll need a couple of extra enemies. Since we don’t really need a reference to them we can do it like this:
for (var i:int = 0; i < 5; i++) {
var tmpEnemy:Enemy = new Enemy();
tmpEnemy.x = Math.random() * 800;
tmpEnemy.y = Math.random() * 600;
addChild(tmpEnemy);
}What we do here is first a small loop, this is a classic for loop, if you need to read up on what the arguments are a quick googling should help you out. Then we create a temporary variable to hold a reference to the enemy we’re about to create. We use that to position the enemy at a random spot on the stage. Math.random() returns a random number between zero and one, we multiply that with the stage size we’ve set in the project properties (800×600 is the default in FlashDevelop). The Math class contains all the math related methods, so we’ll see more of that in a later parts of these tutorials.
Run it and give any Enemy a good clickin’, you should see both the trace statements in your output. The attentive log reader notices that the enemy’s trace always arrives before the main trace. This is because of something called event bubbling.
This means that when a object added as a child to something receives a click (or any other event) this event will bubble up the hiearachy to it’s parent. The parent will in turn bubble it further and so on. Thus, by listening for click events on our Main class we’re getting all clicks in the whole application. Almost.
The click registration respects the objects shape (it doesn’t handle images with alpha though). A good way to visualise this is to set the enemys propety buttonMode to true. This will give you the hand cursor whenever you’re in a position that would click that object.
If you want to listen for all clicks you will need to add a listener to the stage. This will give you all clicks even those that aren’t really on anything, but we’re not going to need that right now.
Knowing what got clicked is real easy when you’re only listening for clicks on a specific object, but as you’ve seen that’s not always the case.
You have probably noticed that the event handling functions accept an argument. I (and Flash Develop) almost always name this e:
private function handleClick(e:MouseEvent):void
But you can name it however you want, it will have to be there however since that’s where all the information about the event goes.
You can use FlashDevelops autocompletion to take a look what properties are available, there’s quite a lot of them. We’ll focus on the one named target for now.
The target is the object that initally dispatched the event. In our case that will be either one of the enemies or your new Player class, assuming this is the listener we set up in Main.
This property is an object which is one of the most basic datatypes in Flash. This is because the thing that dispatched the event could be of any type. To get at the actual Enemy we’ll need to cast it.
If all you care about is what class the target was you can do it like this:
if (e.target is Enemy) {
trace("run away");
}This is pretty straightforward, the is operator compares the target to a class and evaluates to true if it’s a match. But there are other neat tricks you can do which are especially useful if you want to do something with the target.
Try assigning your enemy to a variable in the handler:
var targetEnemy:Enemy = e.target;
The compiler will whine about this, since we’re trying to put a generic object into something that’s meant to hold an enemy. To get around this we need to specify that this infact is what we want to do:
var targetEnemy:Enemy = e.target as Enemy;
Now, if this succeeds the enemy will be accesible via the variable, if it fails the variable will be null. This combined with the fact that in actionscript everything can be evaluated as a Boolean lets us do like this:
var targetEnemy:Enemy = e.target as Enemy;
if(targetEnemy) {
targetEnemy.y += 20;
}If you click the player the cast will fail and targetEnemy will be null. null will evaluate as false, and a reference will be true so we can safely do stuff with our enemy inside. Neat, huh?







thank you for such a great tutorials! I’ve completed all of them now, got a question: I’ve made Player class to be “extends Bitmap”. The problem is that it doesn’t let to handle mouse click event. What is a common workaround for this?
thanks again!
Glad you like them!
I adress this exact problem in part 4, the trick is to have your player extend Sprite and add another child to that one with the actual graphics.
Thank you for answering! Yeah, I’ve got the trick from previous part, but do I correctly understand that I’ll need to make the Player (that extends Sprite) display nothing, while having a Bitmap child?
One more question
Let’s say I want a little animated spark appear on my game object (a gem, for instance). I may guess that the easiest way will be to make it a vector animation in Flash CS4, save it as .swf and embed it into the game, like you embed leek.swf in Part 3. But is there another way to make it without using Flash? I mean maybe there are other programs that allow simple vector animation authoring with swf export?
Also, here are a few ideas on possible new tutorials (feel free to ignore them
:
1)Organizing main game loop
2)Display list objects (and tweening using external libs) VS blitting sprites
3)Creating simple UI
Once again – thank you for great tutorials!
Yeah, having the Player class “empty” is exactly what I suggest, that’s the most flexible way IMO.
I stick to the Flash Authoring tool (what you call Flash CS4) to do my vector graphics, but nowadays the full specs for swf are publically available, so there should be other tools that can export to that format aswell. Although I don’t have any good suggestions.
A Sprite blitting tutorial is not anything that’s going to be covered here anytime soon, it is possible in Flash, but it does go against much of the good parts of the tech and is in my opinion a step back. It is however useful for some effects, but I wholeheartedly recommend sticking with the regular Displaylist.
But the other two will most certainly be touched upon in upcoming parts.
Thank you! Looking forward to next parts!
hrm…
I tried typing it in and copypaste and:
for (var i:int = 0; i < 5; i++) {
Output asks for a right parenthesis before the semicolon after the 5 and a semicolon to the right of the i++ but when I add those things it throws more errors.
I wonder if I am just attempting to put this in the wrong place. Where exactly does the loop go? I have tried it in a variety of places and still run into the same errors.
it seems i have some html escaping issues with the code-blocks, the & lt; is supposed to be a “less than” sign <
i’ll look into fixing this asap!
Any luck with fixing the & lt; ? I just added your Making Games in ActionScript 3.0 series as the first tutorial that people should try if they want to learn AS3 game programming, but I know mistakes like this could really confuse beginners who don’t know any better! (click my name to see the article I wrote)
Otherwise, I really like the clarity and thoroughness of your tutorials. If you find the time to make any more, I will be eager to read them.
Great tutorial, thanks for sharing!
awesome tutorials
learned quite a bit from it
Aaaaaaahhhhhhhhhh hurr.
I spent two hours trying to work out an apparently nonsensical “Access of undefined property x in package player” error message. I finally randomly guessed the problem: I had saved the Player class in a folder called “Player”, instead of in the root folder. All the code referred to the Player folder correctly, but the word must be reserved for something else in Actionscript, because when I renamed the folder it worked perfectly.
Ok, now that I’ve proved my credentials as a total n00b, I’ll give you a little feedback on what it’s like for a novice to read these tutorials. The information is great, it’s broken down well step-by-step, and it’s explained clearly for the most part, but towards the middle you stop explaining where to put things: a lot of passages say “now add this code” without any hint as to where to write it. I muddled through mostly by trial and error.
But I got there in the end! It feels like a victory, but it’s daunting to think how much there is still to learn.
Thanks for taking the time to write out this very helpful tutorial. You’ve earned good internet karma!
Huh. That should be a “troubled” emoticon, not an angry one.
I’m using the most update version of FlashDevelop (3.0.6) and when I try using “e.target” the compiler comes back with tears in it’s eyes and proceeds to tell me “Error: Access of undefined property e”. Can anyone explain to me why the e.anything expression won’t work?
Thanks
@LopTank – Did you put the e:GumMixEvent in the arguments for the eventhandler? (See the second code block in the post)
When I put the trace for “Clicked in the main” It only shows up when I click on the gnome along with the other trace. And nothing shows up when I just click the background. I put everything where u said, maybe I should check the source files real quick
Nevermind I figured it out, the click in the main detects it for all the enemies. It’s a bit unclear there.
These are great, two thumbs up!
My ship sails in the morning.
I wonder when the next part will be posted…
Hey! Very helpful tutorials. Thanks for helping guys like me get started in ActionScript 3.
Hello grapefrukt,
I really like your tutorials, however I have a problem. I have added the Click eventlistener to my Enemy class which extends Sprite, yet the event doesn’t occur when I try to do it runtime.
What could be the problem?
I really like this tutorial series. Should be required reading for anyone trying to get up to speed on Action Script 3 with Flash Develop. I see the last installment was posted a year ago
. Sure hope it picks up again, it’s very helpful!
Hi grapefrukt,
Thanks for the tutorial! I am having a little trouble with adding another listener in the main class. I get an error Duplicate function definition. Could you post the final code?