Monday, June 2, 2008

Flash Game Tutorials, Lesson 1 App Screens

Danny Burbol's How to make a falling blocks style Flash Game Tutorials


Lesson 1: Intro to Flash/ActionScript 3 and App Screens



A Link To: All Lessons' Table Of Contents
A Link To: The Original Flash Game that started all this

This is a Flash tutorial for introducing some of the basics parts of ActionScript 3 that you'll need to make any Flash Game. It's presented with a goal in mind. We will be using these building blocks to set up a basic framework for making some simple games screen that we'll be able to switch between by click on buttons on the various screens.

Here's a link to my falling blocks game, it's the reason I started making this tutorial.



I've been programming console games in c/c++ for years, but Actionscript 3 is pretty new to me. So rather than gloss over everything, I plan on making a more in-depth "how to" for people who have some programming knowledge, but are new to Flash and AS3.

A work of caution to artist and non-programmers: Making game with Flash using AS3 doesn't *involve* programming, it *is* programming. This tutorial can't teach you how to program, I'm sorry, it's just a topic all to itself, and it's a huge topic at that. So use your best judgment as-to whether or not you want to go through with this tutorial, I don't want to waste your time or make you frustrated. Also, if anyone reading this had some good links for helping others learn some the the basics of programming and programming practices, please leave a comment so others can benefit. (Thanks!)

By the end of this tutorial we will have a flash application that shows a few screen and lets you click buttons to go between them. For example: a "someone presents" screen, a title screen, a credits screen, and a game screen that we can click buttons to go between.


So by the of this tutorial, you will have a framework, something like this:










Elements I'll be explaingin in this tutorial:


  • Make a .fla file
  • Make a few movie clips (one per screen)
  • Make a few buttons (for switching screen)
  • Make a .as file
  • Make a class
  • Hook flash to automatically run ActionScript
  • Hooking up movieclips to work like classes in ActionScript
  • Hooking up buttons to work like member variables of classes in ActionScript
  • Catch Generic Flash Events
  • Make and Catch Your own Events


Elements I won't be explaining:


  • I won't be explaining "how to program", but I will be volunteering as much insight as I can about the Actionscript I'll be showing. Regardless, if you don't know what a "class" or "event" is and you've never heard of "public", "private", "extends", or "override", please stop now. You will be disappoint about halfway through this tutorial. Instead, go check out some programming tutorials and come back to this one later.



Step 01: How to Create a new Flash .fla file:




  1. open flash
  2. if you're not presented with a splash screen that has the option for creating a new .fla file, then go to the "File" menu and select "New..." In the popup, highlight "Flash File (ActionScript 3.0)" and then click "OK"
  3. this creates an "Untitled" file. So before we do anything, goto "File" > "Save As..." and save it. For this tutorial, I'm going to call it AGreatGame.fla



Step 02: How to create a few game screens with Movieclips






  1. First of all, we've got lots of great toolbars and window. I'll give a brief description of them *as we use them*, rather than a long list of every single element of the interface. (Also, if you're looking for a long list of every item on in the interface, try the "help" menu, there's lots of element by element information in there. That's where I started.)
  2. Let's start with the "Stage". The stage is the panel that's most likely in the center of your screen with a big blank square on it. You'll also note it has a "timeline" at the top with a "Layer 1" and below that a bar with the word "Scene 1". "Scene 1" is talking about our blank Stage, that white box we're looking at. I just wanted to warn you ahead of time, the process we're about to go through for making screens that we can click and navigate around with are all done in actionscript. So what you see right now is pretty much what you're always going to see, even when you get to the end of my "falling blocks" tutorials. "Scene1" will always be blank. So don't panic or let it bother you.
  3. Resize your flash movie so we're all using the same dimensions. Do this by clicking on the Properties tab at the bottom of the screen. If you don't see it, try the menu bar: Window > Properties > Properties. Now click the Size button and make your movie's dimensions 550 x 400 pixels (if it's not already.)
  4. Next we're going to make a screen in the game by making a movieclip.
  5. Click on the "Library" tab to see the "Library" panel (or find it in the menubar: Window > Library. If something onscreen disappears, then do it again: Window > Library. Basically, you want that "Library" item to have the check next to it in the "Window" menu.
  6. Make a new movie clip:

    1. In Our blank Library, somewhere in the white space below "Name" and "Type", right-click and select "New Symbol..."


    2. I'm going to make the title screen first, so I'm naming this movie clip "TitleScreen_mc". Note the "_mc" which means "movie clip". This is not required I just like to see the name of something and know instantly what it is. It's the programmer in me.
    3. Make sure you've got "Type" set to "Movie clip".
    4. Click OK.

  7. Note the stage has changed. See the bar where it used to say "Scene 1" now says "Scene 1" followed by "TitleScreen_mc". That bar will always tells us our location. The last word will always be the items we are currently editing. It's just like navigating folders on your computer. That same way we can have folders in folders we can also have Moiveclips in Movieclips. So if you ever get lost, look there and it will tell you where you are and what you're currently editing.
  8. Now, let's make a background for our screen.

    1. In the timeline, where it says "Layer 1", double click the words "Layer 1" and rename it to "background".
    2. Now, in the same row we just named "background", click on the first box under the "1" (the box has an empty circle in it) This box is frame 1.


    3. Next, click on the Rectangle tool (looks like a rectangle, below the line and above the pencil)
    4. Briefly, I'll just say, note the bottom of the toolbar you just clicked on. There is a pencil and a bucket, both with a square of color. These are going to be the border color and the interior color of the rectangle you are about to draw. So pick a couple colors you like.
    5. Draw a rectangle on the stage. Don't worry about size, we're going to make it exact by edit the numbers after we create it.


    6. Now got down to the Properties tab (remember, we used this to set the size of the movie.
    7. The movie is 550 x 400, so let's make the box the same size. Set:

      1. W: 550
      2. H: 400
      3. X: 0
      4. Y: 0

    8. Odds are, you're rectangle is in the bottom right corner of the screen and goes out of the stage window. If you hold down the Space bar, your mouse cursor will turn into a hand. As long as you hold down the space bar, you can click and drag to move around the Stage (so you'll see the scroll bars moving instead of the rectangle moving). Do this to center the rectangle on screen... or you can just use the scroll bars.



  9. Now we'll give the screen some text

    1. Look up at our layers in the timeline.
    2. Right-click on the word "background" and select "Insert Layer"
    3. Double click on the new layer's text and re-label it "desc"
    4. If "desc" is not above "background", then click and drag the "desc" layer upward to be above "background"
    5. Notice how the boxes under frame "1" in the timeline are different. "desc" is an empty circle, while "background" is a solid black circle. This is because the "background" layer has something on it (the rectangle), while the "desc" layer is empty.
    6. Click on the box for frame 1 for the "desc" layer. (which has the empty circle in it)
    7. Now select the Text Tool from the tool bar (looks like the letter "T", and is below the quill and above the line)
    8. Note all the great stuff in the properties tab at the bottom of the screen. You can do all sorts of stuff to your font. So pick whatever you'd like, just make sure you pick a different color than your background.
    9. Now click somewhere on your rectangle and you'll get a text box to type in. You can pull on the handles on the edges of the box to adjust the text box's size and how the text will wrap to the next line.
    10. Give your game a title. I called mine: "Danny Burbol's Simple Game Screen Tutorial."



  10. Play with the layers. Notice you can click and drag the "desc" layer to be below the "background" layer. Notice how you can't see the title text when it's below the "background". This is a useful thing to know. Layers are your friend. Also, if you drag the "desc" layer back to the top, you can hide it by clicking the dot under the icon of the eye. Next to they eye, is a toggle for the lock. The lock means you won't be able to select or edit anything on that layer, and the colored box isn't really that useful but it toggles between drawing the layer or just drawing the layer's outline.
  11. Lock the "desc" and "background" layers by clicking on the dots in each layer below the lock icon. (this way we don't mess them up while we do the next step)


  12. Next we will add some buttons for letting the player go from screen to screen. We're going to have 4 screens. This title screen, a "someone presents" screen, a credits screen, and a game screen. On this Title screen, we're going to want a button to go to the credits screen and a button to play the game. So let's do that.

    1. Create a new layer in the timeline and call it "buttons". (remember how we added the "desc" layer? Double check the last step if you need a refresher).
    2. Make sure to click on frame 1 of the" buttons" layer.
    3. Now rather than making our own buttons, let's just use some of the stock buttons Flash was kind enough to share with us.

      1. In the menu bar: "Window" > "Common Libraries" > "Buttons". This will give you the "Library-Buttons.fla panel
      2. Find a button you like and drag from the "Library-buttons" panel to the "library" panel. (Pick a button that already had text on it.) --Note: *don't* drag it directly to the stage, drag it from one library to another.
      3. In the "Library" panel, double click the button's text name and change it to "Play_btn". (I'm not talking about the "enter" text, I'm talking about the text name it's listed as in your "Library" for your AGreatGame.fla)
      4. Drag a second copy of the button over to your library and name this one: "Credits_btn"
      5. In your "Library", double click the little button icon next to the words "Credits_btn".
      6. Notice how the button is on the stage and the location bar now reads: "Scene 1 Credits_btn"
      7. Also notice that the timeline for buttons looks different than the movie clip did. Instead of having frame numbers across the top, there is "up", "over", "down", "hit".
      8. Locate the layer with the button's text on it and unlock it if needed. (I like to turn the layer's visibility off and on until I'm sure I've found the layer that has the button's text on it. Note, my button's text started out as "Enter")
      9. Once you've unlocked the layer with the button text, double click the button text on the stage to edit it to say "Credits".
      10. Now go back to your "Library" panel, double click the button icon for "Play_btn" and change this button's text to "Play" (refer to the steps above if you need a review on how to do that.)
      11. The two buttons are ready to put in on your title screen. Go back to the "TitleScreen_mc" by double clicking on the little movie clip icon next to the "TitleScreen" text in the "library"
      12. With the TitleScreen_mc on the stage, and the first frame of the "buttons" layer selected, drag a copy of "Credits_btn" and "Play_btn" from the Library panel to the stage.




  13. Finally, we have all the elements for this screen. To keep our Library from getting too cluttered, you can right-click in the Library and select "New Folder". I named my folder "fTitleScreen". Again, I like names that say what they are. In this case, the "f" means "folder"... but at the same time, Flash doesn't like it when two things in the library have the same name. The first time I did this, I name my Title Screen movie clip, "TitleScreen"... and then when I tried to make a folder called "TitleScreen", Flash wouldn't let me. So by getting into the habit of post-fixing and pre-fixing names, I avoid any problems like this.
  14. Now, go back to the beginning of these steps and create a few more screens with a few more buttons. When you're done you should have:

    1. IntroScreen_mc

      1. Some text that says: "Presented by " or "A Production"
      2. A button named "SkipIntro_btn" that says "Skip Intro" on it.

    2. CreditsScreen_mc

      1. Some text that says: "Credits"
      2. Some more text that says: "This game was made by "
      3. Some more text that says: "Special thanks to the totally helpful flash tutorial on DannyBurbol.com" (well, it'd be nice of you to do that).
      4. A button named "BackToTitle_btn" that says "Back"

    3. GameScreen_mc

      1. Some text that says: "the game will be played on this screen"
      2. A button named "Quit_btn" that says "Quit" on it.








  15. After you've create all of these screen, you should put them in 4 folders in your library, "fTitleScreen", "fInfroScreen", "fCreditsScreen", "fGameScreen"




TIP: if you make a mistake and put all of your screen's elements on the same layer, you can fix it by clicking on the frame in the timeline (the box with the black dot in it) and then right-clicking on one of the highlighted items on the stage and selecting: "Distribute to Layers". Now each item is on it's own layer... just rename the layers to match what's on them... again, you can use the toggle of the eye to turn layers on and off and make sure you know what's on each layer before you rename it.


Step 03: How to make and hookup a Document class



If we test our game right now, we should get a blank screen. You can test your game by pressing Ctrl+Enter, or going to the menu bar and selecting "Control" > "Test Movie". (PS, if you have a Mac, I'm sure you're used to figuring out what the Mac equivalents of PC shortcut keys are... in fact, I've been saying "right-click" a lot, and I know that's different for you guys as well. I'm just going to continue in PC terms, please keep translating in your mind like you have been already. Thanks, and sorry for the inconvenience.)

So, what we want to do is use ActionScript to create an object of type "movie clip" (all of our screens are movie clips). Then we want to show the movie clip we created the in movie's main scene. Of course the question is, "how?"

We have a couple things to overcome.


  1. We need to get the movie to trigger some ActionScript the moment it starts playing.
  2. Then we need that ActionScript to specifically create one of our movie clip screens.
  3. Finally, we need to get that movie clip to actually display.


This section is going to cover that first issue: get the moive to trigger some ActionScript the moment it starts playing.


  1. First we need an ActionScript file to call when the movies starts, so let's create an ActionScript file.
  2. in the menubar, select: "File" > "New..." and then select "ActionScript File". Don't select "Flash File (ActionScript 3.0)". I know that one looks tempting, but it's going to create another *.fla file.... what we want is a *.as file.
  3. Our main window changes and we no longer have our stage and timeline. Instead we have a blank screen with two tabs at the top "AGreatGame.fla" and "Script-1".
  4. Before we get distracted, let's name the *.as file. Please note, I had a bit of a run around when my *.as file and the class it contained were not named identically. It could have been a fluke, but I just got in the habit of making sure my names were identical. So just give some thought to your file names is all I'm saying.
  5. Let's "save as" on this file and call it, "MainApp.as" and be sure to save it in the same directory as AGreatGame.fla. (don't call it by the name of your game, you'll regret it later in the tutorial when we actually create an AS file by that name)
  6. Now we type in some ActionScript. Notice I said "type". I don't mean to be a pain in the butt or sound all "holier-than-thou", but copy/pasting stuff is not going to get you anywhere. I heard a great quote: "The Learning is in The Doing". Very wise in my opinion. You learn more by "writing script" than "moving script" from one screen to another with copy/paste. (sorry for the lecture).

  7. Save Your MainApp.as file! I don't know why but Flash doesn't automatically save your *.as file when you try to test your movie (as in: ctrl+enter). So just get in the habit of saving often. Also, if you change some script and run your movie only to see that nothing happened, you'll remember my mystical jedi powers of suggestion and recall this paragraph *before* you pull your hair out.
  8. Okay, so what does this script mean? With my one week of AS3 experience I can tell you this:

    1. All *.as files that I've seen start with "package"
    2. All *.as files that I've seen have no class or one class in them, but I haven't seen more than one class and I hadn't had a reason to try it.
    3. import is a lot like C++'s #include or using namespace.
    4. trace( ) is basically our debug printf.

  9. But wait! What's a "class"? what's "public"? what's "extends"? -if you find yourself asking these questions, then you need to take a break from this tutorial and go check out some object oriented programming tutorials. I don't mean to be rude but classes are a basic programming building block these days, and the syntax of ActionScript is very much like Java and C++. So you should read up on them. In all honesty, it broke my heart when I realized just how much programming is involved in ActionScript. I had visions of little kids on Christmas morning, opening their gifts to find that one perfect toy they've been waiting months to play with, only to find out it didn't come with batteries. I really thought Flash with AS3 was going to pretty much be a fun little "game editor" or something... but the reality is, Flash and AS3 are so powerful because they are so much like programming. If you want to make cool games, just bite the bullet and start reading (and doing!) programming tutorials. This is tough love. I'm warning you now because it's only going to get more complex as we move on.
  10. Okay, we have the bare minimum ActionScript to do something, which is just a debug print in our class' constructor. Now we need this class to actually get created when the movie runs. This is why the title of this section is "How to make and hookup a Document class."
  11. If you haven't already, save your MainApp.as file.
  12. click on the tab at the top of the window to go back to your AGreatGame.fla file (you can also use ctrl+tab).
  13. in the location bar, click on "Scene 1" to verify that only the words "Scene 1" appear in the location bar.
  14. Click on the blank stage and then click on the Properties tab.
  15. Remember, this is where we set the movie's size.
  16. Also in this panel, you'll see "Document class". This is where we tell flash the name of the class we want to create when the movie starts running. So type in: MainApp
  17. now hit ctrl+enter to test the movie. The Output window should automatically open and print "MainApp::MainApp()".
  18. tada, this is basically "hello world", only more useful because we've also created an instance of a class.



Step 04: How to Link Movie Clips to ActionScript like classes.



This is really cool but not really that intuitive. I followed a tutorial that did this and didn't even pause to explain why. It came back to bite me (of course), so I'm devoting a whole section to it to say:

"HEY YOU! STOP SKIMMING AND READ THIS!! It's really important and easily overlooked."

Imagine you could treat a Flash movie clip like a class in Actionscript. Imagine you could create buttons in that movie clip and have them be member variable of that class in Actionscript. That's exactly what we're going to do.

Exposing your movie clips to ActionsScript 3.0 as classes.


  1. In your AGreatGame.fla, go to your Library and right-click your IntroScreen_mc and select "Linkage" (which is right under "Properties")
  2. In the pop-up, check "Export for ActionScript". The data should automatically fill in.


  3. Basically, we're about to say we want a class called "IntroScreen_mc" and we want it to extent "flash.display.MovieClip" which makes sense. Our IntroScreen_mc *is* a Movie Clip and we want to add more functionality to it. Also, the "export in first frame" checkbox should be check.
  4. Now here's one of my first "sad kid with no batteries on Christmas" moments. We click OK and nothing happens. I really expected flash to create a new ActionScript file for us and pop in the one class so we would have not change of screwing it up. This is not the case. You need to *already know* what the class is supposed to look like in *their language*. This, I think, is a lot to ask of any user regardless of one's programming experience. I paid money for this "tool", it should be saving me from cases of potential user error. Oops.
  5. create a new ActsionScript file (remember how we made MainApp.as? go review if you have to.), call this new file "IntroScreen_mc.as".
  6. Here's the code for this file:


  7. Code details:

    1. so again we start our file with "package".
    2. We import the MovieClip, which is just like a c++ #include. If we didn't' include the MovieClip, on the next line, Flash would give us a compile error for trying to used an undefined type "MovieClip".
    3. Our class definition is pretty straight forward. You may think it looks a little funny having that "_mc" hanging off the end of the class name. Again, I did this to help ourselves in the future. We're going to make class that are *not* attached to Flash objects with this "Linkage" property. So it's nice to have that "_mc" jump out at you to tell you which things are relying on things in your flash library and which are not. Think about it, if I handed you 100 *.as files and 20 of them ended with "_mc.as", you'd instantly have a much better understanding of what files do what and which are linked to objects in the game's flash library.
    4. Again we put a trace in our constructor because we want to verify that it worked.

  8. go back to MainApp.as and add a few things.


    1. Remember, we have to import the MovieClip so we can use it.
    2. We create a member variable to hold our current screen. Note how AS3 does this. You declare public/private for the variable, then you use "var" to say it's a variable. This is followed by the name of the variable, then the colon and the variable type. Also note that this is a pointer because we just set it to null (a lowercase "null" btw). Why do we have a "var" if it's obviously a MovieClip variable? Later you'll see us replace "var" with things like "const". So it's good to see AS3 allows us to describe our data as "var", "const" and "static".
    3. We created a function CreateIntroScreen() which will do just that.

      1. add/removeChild() are for adding the screen's movieclip to the MainApp, which is, in turn, a child of the stage. These functions control whether or not the screen movieclip will be displayed in our flash movie.
      2. I started with an error check, better safe than sorry.
      3. Note, no 'delete' because we're using a garbage collecting language.
      4. and "new" is just like C++.

    4. Finally, we call CreateIntroScreen(); in our MainApp's conctructor.

  9. Save your *.as files. Then test it with ctrl+enter.














  10. Finally! We have visual! (notd, the button does nothing) I hate not seeing my game onscreen and it's a shame just how much we have to go through to get to this point. Are their other ways? Yes, of course, but I fell victim to many of those ways when I first starting researching AS3 with the goal of making a falling blocks game. Let me repeat: there *are* easier ways to get something on screen, but I found many of those ways quickly limit us as to where we can go next. This way, we have class, we have encapsulations, --we have all the structure in place to actually start programming an application/game. Again, I use the word "programming", I'm sorry my artist friends, but Flash really did go into the realm of programming on this one. If you're an artist and you want to make a Flash game, you might be happier hooking up with a programmer so they can do what they love (type boring text!) and you can do what you love (make things look awesome!)
  11. btw: you're output window should read:

    MainApp::MainApp()

    IntroScreen_mc::IntroScreen_mc()
  12. okay, just a note on how I work. I'm a visual person. From here on out I'm going to add a little bit, and then test the movie, and add a little bit, and then test the movie. I'm not going to dump a couple files worth of ActionScript on you and say "1. type all this. 2. 'tada' we're done." We're going to build on what we have and keep building.
  13. BEFORE YOU RUN AHEAD AND IMPLEMENT THE OTHER SCREENS (ie: CreateCreditsScreen(), CreateGameScreen() and CreateTitleScreen() ), first take this next step.
  14. The plan here is to have MainApp manage our screens. The best way to do that is to give MainApp a common API for dealing with all of our screens. Currently mCurrentScreen is a MovieClip, which is nice. Those add/removeChild() functions will work for all of our screens. However, we're going to plan ahead so our screens' common API can get more complex as we progress.
  15. To do this we're going to insert a class between IntroScreen_mc and MovieClip. We'll call this new class "AppScreen". And in the end, all of our screen movieclips will inherit from AppScreen.
  16. So create a new *.as file and name it AppScreen, then fill it with this:


  17. now update what IntroScreen_mc extents from MovieClip to AppScreen.
  18. Also update MainApp.as so our mCurrentScreen is no longer of type MovieClip and instead, of type AppScreen.
  19. save your files and test your movie. It should look exactly the same, only you should have different output text:

    MainApp::MainApp()

    AppScreen::AppScreen()

    IntroScreen_mc::IntroScreen_mc()
  20. Now go back to the beginning of this section and use your copy/paste skills to:

    1. Link up each screen using the "Linkage" properties.
    2. Create files with classes for: CreditsScreen_mc, GameScreen_mc, and TitleScreen_ms.
    3. Don't forget, your screens are extending AppScreen, not MovieClip.
    4. Create functions in the MainApp class for: CreateCreditsScreen(), CreateGameScreen(), and CreateTitleScreen().
    5. Test those functions by trying each of them in your MainApp::MainApp().



Step 05: How to access Buttons in ActionScript classes.




We're going to do two major things in this section. First we're going to give ActionsScript access to the buttons on each screen. Then we are going to actually listen for when the button gets pressed and give a debug print. We're not actually changing screens just yet, we're just hooking up buttons.


  1. Before we do anything, we need to verify you don't have the "mess everything" checkbox checked in your settings.

    1. Go to File > Publish Settings...
    2. Click the "Flash" tab


    3. Where it says: "ActionScript version: ActionScript 3.0" and then "Settings..."... click that "Settings..." button.


    4. Make sure "Stage: [ ] Automatically declare stage instances" is not checked. We're going to declare our instances in each screen's class, if we don't uncheck this, Flash will complain that we're trying to declare something twice.
    5. Click OK, but don't close the Publish Settings window.
    6. While were here, check the "Protect from import" box and anything else you might find useful.
    7. Click OK to close the Publish Settings window.

  2. now let's hookup a button to our actionscript. We'll start with the IntroScreen_mc, since that's the first screen with the first button we can test with.

    1. Double click the icon next to "IntroScreen_mc" in your Library. (so you can get to the edit mode for IntroScreen_mc.
    2. You may need to center the screen in the stage, remember you can do this by holding down the spacebar while clicking and dragging, or you can just move the scroll bars.
    3. Select the Selection tool from the toolbox. (the black pointer at the top of the toolbox)
    4. Single click on the "skip intro" button on the stage to highlight it.
    5. Now, if it's not already open, click on the "Properties" tab at the bottom of the screen.
    6. There should be some gray'ed-out text that reads: . Change that to be: mInstBtnSkipIntro
    7. Again, we have my extra descriptive prefix. I'm sure your getting tired of them, but let me explain my logic. "m" is about to mean "member variable", "Inst" is "instance", "Btn" is "button". I put all this *before* the SkipIntro because this is going to be a *variable*, while "SkipIntro_btn" is a *type*. This way when you see "mInstSomething" vs "Something_btn" in Actionscript, you'll not right away if it's a variable or if it's something in your flash movie's library that you can edit. Imagine if they were both called "SkipIntro" and "SkipIntro"... it just leads to a runaround if you don't already know what you're looking at.
    8. After naming the instance, open up your IntroScreen_mc.as
    9. Add the following lines:


    10. We have to import SimpleButton and MouseEvent because we're about to make SimpleButton variable and listen for mouse events on that button.
    11. public var mInstBtnSkipIntro:SimpleButton; is that same instance we just named in our IntroScreen_mc. Note: "public" not "private", Flash doesn't like it when these types of vars are "private".
    12. mInstBtnSkipIntro.addEventListener function is Flash's standard way of listening for events. (as in: remember this line, you'll be making lots of these in the future).

      1. MouseEvent.CLICK is the event we're listening for.
      2. OnSkipIntro is the name of the callback function we want flash to call when the MouseEvent.CLICK event is fired.
      3. false, 0, true : this sets out "useCapture", "priority", and "useWeakReference". We want our game to be fast and not use a lot of memory for events. These settings let us do that.
      4. The OnSkipIntro function is the function that will be called when our button is clicked... we could have called it anything, it's the ev:MouseEvent that's the required part.


  3. Save your file and test your movie. You should get a printout every time you click the "skip intro" button.
  4. Now go back the hook up all your buttons in all your movieclip screens.
  5. Be sure to test them all to make sure they are printing out the debug trace correctly before moving on to the next major step. So you should have the following button instance variable and callback functions:

    1. In CreditsScreen_mc:

      1. mInstBtnBack which is hooked up to call an OnBack function.

    2. In TitleScreen_mc:

      1. mInstBtnPlay which is hooked up to call an OnPlay function.
      2. mInstBtnCredits which is hooked up to call an OnCredits function.

    3. In GameScreen_mc:

      1. mInstBtnQuit which is hooked up to call an OnQuit function.





Step 06: How to Sent And Receive our own custom Flash Events.




Okay, so we know our buttons are doing something because they are doing a debug print. Now we just need our buttons to actually change screens. Basically, we need a way for our AppScreens to communicate with our MainApp.

Events are pretty much the standard for objects to communicate with each other these days, and ActionScript 3 is no exception. We've already used one of Flash's standard events to listen for buttons being click. This was when we told each button to "addEventListener" and then specified a function to call when the event was fired.

You can get pretty far using nothing but Flash's built in events. In fact, rather than have each screen be in charge of listening for it's own buttons (like we just did), I saw plenty of sample code that would have our MainApp class access each specific button in each specific screen and attach a listener function there to handle each button press. This works, but it also breaks the simple idea of encapsulation. Each screen should be self-sustaining, and if we change the buttons on a screen, it seems silly that we would have to also fix references to that button *outside* of the screen's class (as in, the bad MainApp usage I just described).

So we're just going to bite the bullet and learn how to setup our AppScreens to send and receive our own custom events. Now, instead of having MainApp setup to say "tell me when someone clicks this exact button in this exact screen", we're going to set it up to tell MainApp, "hey, don't ask why, but someone wants to go to this other screen." That way all the logic of what the buttons do is encapsulated in each screen and MainApp never has to know about what screen has which buttons on it.

So lets get started adding our own events:


  1. First we need to define our events so we can send them later. An example of an event would be that "MouseEvent.CLICK" we used earlier.

    1. Create a new *.as file, and save it as "AppScreenEvents.as"
    2. Here's the code for that file:


    3. Again, package comes first and everything goes inside it.
    4. Our AppScreenEvent class extends Event
    5. These next four static const strings are out events. That are the equivalent of that "MouseEvent.CLICK", however we will be using something that looks like "AppScreenEvent.GOTO_TITLESCREEN"
    6. The constructor is just passing on the data to it's super class (Event). This 'super' keyword is awesome in my opinion (having dealt with the way C++ calls super class functions, which involves hard coding the name of the super class followed by the scope operator.)
    7. We also override the clone function. BTW, this is the first time we a colon after the function's closing paranthisis. "clone():Event". This is how we define a funtion's return type in ActionScript 3. So it's consistent with the way they define variable types, and it's carried out with the "return" keyword as expected.

  2. Save your files and Test your movie, just to make sure all the was typed correctly and didn't cause any problems.
  3. We have our events, now we need to be able to sent these events.

    1. Open IntroScreen_mc.as
    2. Update the OnSkipIntro function as follows:


    3. Pretty simple. The OnSkipIntro function gets called when the "Skip Intro" button is press on the Intro Screen. What do what want to happen when went we press this button? We want to go to the Title Screen. So we create an AppScreenEvent using the GOTO_TITLESCREEN static const we just setup.
    4. Now open each *Screen_mc.as file and add the dispatchEvent call after our button's trace output. Just ask yourself "where do I want this button to take me?" and then changed the "GOTO_xxx" to match.

  4. Save your files and Test your movie, again just so make sure we didn't make an typos or anything. The movie itself is not going to do anything new just yet.
  5. Now, we have custom events that we're sending out when buttons are clicked, we just don't have anyone listening to these events. We do this pretty much the same way we did our "MouseEvent.CLICK". That is, we're going to use the "addEventListener" function again.

    1. In MainApp.as add this function:


    2. So basically when mCurrentScreen fires off one of our "GOTO_xxx" events, we go to one of our Create*Screen functions.
    3. This doesn't compile yet, by the way. Remember, an event callback takes a parameter that is the event it heard. Back in IntroScreen_mc.as, we have the OnSkipIntro function that takes the parameter "ev:MouseEvent", because that's what it's listening to, a MouseEvent. We need to make our Create*Screen functions aware of the event they are catching.
    4. So, in MainApp.as, for each of our Create*Screen functions, change the parameters from "( )" to "( ev:AppScreenEvent )". Also, while you're in there, have each of these functions call AddListenersForAppScreenEvents() on the last line of the function.




      Note, you're changing more than want I got in that screen shot

    5. The very last step is to go back to the MainApp constructor and have CreateIntroScreen pass a null parameter.

  6. Save your files and test your movie. You should be able to click buttons and move around from screen to screen.












The Next Step: What you can do with what we've learned.




This is the end of this tutorial. What have we learned?

In the end, the most important things we're walking away with here is the ability to:


  • Access movie clips in ActionScript 3 as classes via the "Linkage" property.
  • Access instances, like buttons, in ActionScript 3 and have them be member variables in a class we've used "Linkage" on.
  • We can listen and react to standard events, like MouseEvent.CLICK
  • We can create, send, and listen for our own custom events. This is huge. All the other things I just mentioned are more of a "Basics of Flash Actionscript 3", while custom events are a big step up and are more of an "Intermidiate" topic. Knowing how to do this will set you free to create some really great games in the future, even if you don't follow all my, specific, tutorials.


We've used the above building blocks to set up a bunch of Screens, each of which is smart enough to manage it's own content. We've also setup a manager to switch from screen to screen when asked to do so by the objects it's in charge of. From here you could make as many screens as you wanted and link them with buttons how ever you wanted. Notice that the way we put things together, all you have to do is add a button to a screen and you can make it bring us to any other existing screen without having to touch MainApp or AppScreenEvent again.

However, if you want to add more screens, then you'll have to make sure MainApp knows how to create it as well as add a new AppScreenEvent so MainApp can communicate with it's AppScreens about going to this new screen.

If you were inspired, you could use this framework to make 100 screens and link them together to make a graphical "choose your own adventure" style story.


You can also go back and make your screens look cooler. We just did the bare minimum as far as graphics go. Now is your change to go wild. However, one word of caution: make sure your WhateverScreen_mc movieclip has one, and only one, frame. I'm talking about CreditsScreen_mc, GameScreen_mc, etc. Originally, I thought it would be cool have an animating title screen where the words animate into view. You can do this, but instead of adding a bunch of frames to your TitleScreen_mc, make a seperate TitleText_mc that had multiple frames and animates the text the way you want. Then just drag that TitleText_mc into your TitleScreen_mc's single frame. It will animate as you want, and will keep you from having odd problems to deal with later in these tutorials.

The Next Lessons: more tutorials.



The next tutorial will be about drawing a square on the screen and moving it around with the keyboard.

The tutorial after that will be about using our drawing and keyboard capabilities to make the actual game board and game pieces.

The tutorial after that will be about getting the game board and the game pieces functioning together like a game. At the end of this tutorial you'll have a bare-minimum falling blocks game.

The tutorial after that will be about adding sound.

The tutorial after that will be about adding a score and some game over text.


If you read all the way to this line. I hope you got a lot out of this tutorial!

thanks for reading!

~Danny



A Link To: All Lessons' Table Of Contents
A Link To: The Original Flash Game that started all this

3 comments:

Danny said...

I got a rather unhelpful comment about all this not being needed. Let me just re-iterate: The point behind the AppScreen class was to make some simple, object oriented building blocks.

Yes, you can put the contents of each movieclip on a seperate frame and try to bypass the encapsulation of each screen into a single, self contained object.

Yes, you can weave a fine web of GoToAndPlay() calls that may or may not use labeled frames or hardcoded frame numbers.

Yes, you can put together a game that uses lots of action script on frames.

However, the point was, re-usable code. Once you've made a nice clean, self contained object, you can easily move it from one game to another; copy it to another fla and start using it without having to untangle all it's connections in the last fla; or better yet, put it in a swf by itself and load it in dynamically. Then switch out that swf whenever you want (say, for a holiday theme or something).

Yes, we've tackled some big topics in this first tutorial. We're creating classes, sending our own events, linking movie_clips to AS code, and extending classes! *cue dramatic music!* However, we're doing the heavy lifting up front. We're planning on making our own lives easier as the construction of the game progresses rather than letting it become unwieldy and harder to change every time we add something.

My apologies to anyone who wanted a fast, hacked-up solution that would only be useful for the short term and didn't involve learning more advanced approaches.

BTW, I only allow comments that are constructive. I have no issues with someone who disagrees with me, but I'm not going to click "allow comment" when the person doesn't offer any helpful alternatives, links, or suggestions. And I'm definitely not going to stand for comments that are nothing more than rude.

Paulb said...

Mate that is one of the best tutorials I have ever read. Very well done! I love the OO approach, I recently developed a Game in J2ME using the same idea of separate class's for screens. This implemented a switch statement instead of separate methods, but I like your approach. I have now been coding AS3 for 5 hours and most the menu for my game is done ;-) i'll be reading the rest of your tutorials THANKS FOR THE HARD WORK!

p.s. who ever left the unhelpful comment about it not being needed is a moron

Oliver Lecher said...

Great tutorials! I would be more than happy if you finish the tutorial series.you are a fantastic teacher.Thank you very much.