Tutorials

April 27, 2009

Making a Complete Flash Game: Menus, UI, Screens, or Windows

More articles by »
Written by: Par
Tags: , , , , , ,
cg-tn-4

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

Whatever you want to call it, a complete Flash game is going to need an user interface that kicks off the game. A place where the user can get more information about the game, see the credits, save the game, load the game, whatever needs to be done. The Menu the starts the game provides this functionality. So how are we going to do it? Well, you’re probably thinking this is a simple task, and it is. We’re going to make it a step simpler by creating a base menu class that we will extend in all our other menu classes. This base class will keep some of our core functionality so we don’t have to write transitions for each class uniquely.

You are reading Making a Complete Flash Game Read more from this series of articles.

Now, you are going to need to download a new zip file to start this project.  If you have been keeping up with the last two tutorials in this series, you will still need to download this zip archive.  The code in this zip is the same as we left it at the end of the last project. However, the fla contains a new folder called Menus with a few graphic files and MovieClips setup to be used in this tutorial. The reason I am doing this is because, I really don’t want to keep explaining the same things over and over, if you are having problems understanding then you need to go back and read AS3 Flash Games for Beginners.  Anyway make sure you grab the zip file from the links above so you can get started.

Step 1: Explaining the new FLA File

Okay here’s the deal. The FLA file you downloaded in the zip has a new folder called Menus in the Library. Under Menus we have Credits and MainMenu folders.  Each have some graphic files in them and buttons for our Menu pages. The main file in each is titled Credits and MainMenu. These two MovieClips have linkage set to com.asgamer.snipergame.CreditsMenu and com.asgamer.snipergame.MainMenu respectively. They are both set to Export on Frame 1 and are not in our AssetHolder MovieClip.  So you will need to turn export on frame 1 off and drop them in the AssetHolder MovieClip.  I could have done this for you but this is good practice because you’ll need to do it with any asset your create in your game. (At least with the preloader method we are using)

Step 2: Our Menu Design Goals

Okay, so you have already seen our menus. But what is my user interface goal? Well, in the few games I have made, I’ve learned a thing or two to be consistent. One of those things is that pretty much every user interface menu you design will need to appear and disappear as the user jumps between them. And of course we’d like our menu to transition gracefully so we need a way to animate it in and out.  Since this is always consistent in our UI, let’s make a base class for our menus that does the animate in and out.

Whoa, base class you say?

I may have talked about this before and maybe you know what it is but if not I’ll explain.  Let me explain it in a simple manner.  A Base Class is a class that when extended we can use all the public or internal functions and parameters of that class.  So we can write our animate in function once in our menu base class then have all our other classes extend it.  It’s like when I talked about MovieClips and DisplayObjects in AS3 Flash Games for Beginners

Step 3: Let’s Make It (Our Base Class) Happen.

Alright so here’s the deal. In our com/asgamer/snipergame directory let’s create our base class with a new AS file called BaseMenu.as. I want this base class to do two things:  Load (add to stage and animate in) and Unload (animate out and remove from stage).  Add while we are at it, let’s just have some fun with it. Let’s make it so that if we send it our next Menu to unload, it will go ahead and load it when our current Menu unloads. That’s a lot of load/unload talk. Let’s make it work.  So here’s our BaseMenu.as code.

package com.asgamer.snipergame
{
	import flash.display.MovieClip;
	import caurina.transitions.Tweener;
	import flash.display.Stage;
	import flash.events.Event;
 
	public class BaseMenu extends MovieClip
	{
 
		public var stageRef:Stage; //the stage
		public var loadNext:BaseMenu; //instance of next Menu to load
 
		public function BaseMenu()
		{
			alpha = 0;
			y = 400;
		}
 
		public function unload(loadMe:BaseMenu = null) : void
		{
			if (loadMe != null)
				loadNext = loadMe;
 
			Tweener.addTween(this, { alpha: 0, y:-400, time: 0.7, onComplete:remove } );
		}
 
		public function remove() : void
		{
			dispatchEvent(new Event("menuRemoved"));
			if (stageRef.contains(this))
				stageRef.removeChild(this);
 
			if (loadNext != null)
				loadNext.load();
		}
 
		public function load() : void
		{
			stageRef.addChild(this);
			Tweener.addTween(this, { alpha: 1, y:0, time: 0.7} );
		}
 
	}
 
}

And the breakdown:

  • First of all, imports and our BaseMenu extends MovieClip.  We have two class variables: stageRef (Stage Reference) and loadNext(an instance of the next Menu to load, if we have one)
  • In the constructor we set the alpha to 0 and the y to 400. This is so we can animate it fading in and moving up into position when we call load.
  • public function unload(loadMe:BaseMenu = null) : void. Our unload function. It excepts a parameter called loadMe which is an instance of a BaseMenu (meaning it’s one of our menus we will create that extends BaseMenu).  The loadMe parameter is the new menu that we are going to load when we unload our current Menu.  Now if we don’t pass a new Menu into unload then loadMe will store as null.
  • if (loadMe != null) loadNext = loadMe; So if loadMe gets something passed into it, then we will store it in loadNext (our class variable).
  • Tweener.addTween(this, { alpha: 0, y:-400, time: 0.7, onComplete:remove } ); A simple animate out and move up tween using Tweener. If you need to know how to use Tweener or what it is then you should read Using Tweener in AS3 to Move Objects.
  • public function remove() : void. When our tween completes this function is called. This function does three simple things. First it dispatches the event “menuRemoved” which we may need to use at sometime in the future, currently we have no need for it. Then if our menu is on the stage we remove it from the stage. And last if loadNext is not null then we go ahead and call load on the loadNext menu instance.
  • public function load() : void. Simple function that adds our BaseMenu to the stage and Tweens it up into position while fading it in.

Alright that covers the BaseMenu. Let’s make our MainMenu and our CreditsMenu pages.

Step 4: Making the Main Menu and the Credits Menu Work

Oh this is simple. We already have everything setup in our FLA so we just have to code it.  And coding these two is so simple I’m just going to drop off the code for both of them then explain it real quickly.

MainMenu.as

package com.asgamer.snipergame
{
	import flash.display.MovieClip;
	import flash.display.SimpleButton;
	import flash.display.Stage;
	import flash.events.MouseEvent;
 
	public class MainMenu extends BaseMenu
	{
 
		public function MainMenu(stageRef:Stage = null )
		{
			this.stageRef = stageRef;
			btnPlay.addEventListener(MouseEvent.MOUSE_DOWN, playGame, false, 0, true);
			btnCredits.addEventListener(MouseEvent.MOUSE_DOWN, credits,  false, 0, true);
		}
 
		private function playGame(e:MouseEvent) : void
		{
 
		}
 
		private function credits(e:MouseEvent) : void
		{
			unload(new CreditsMenu(stageRef));
		}
 
	}
 
}

CreditsMenu.as

package com.asgamer.snipergame
{
	import flash.display.MovieClip;
	import flash.display.SimpleButton;
	import flash.display.Stage;
	import flash.events.MouseEvent;
 
	public class CreditsMenu extends BaseMenu
	{
 
		public function CreditsMenu(stageRef:Stage = null )
		{
			this.stageRef = stageRef;
			btnReturn.addEventListener(MouseEvent.MOUSE_DOWN, returnMainMenu,  false, 0, true);
		}
 
		private function returnMainMenu(e:MouseEvent) : void
		{
			unload(new MainMenu(stageRef));
		}
 
	}
 
}

Okay Breakdown Time:

  • First thing you notice is that both have imports and extend BaseMenu. So they both have all the functionality of our BaseMenu class.
  • Both constructors except the stage reference. We add = null so during preloading when the menus try to load from inside our AssetHolder they won’t complain about not getting a parameter sent in to them.
  • Then also in the constructor we set event listeners on our buttons that our inside our Menu Movieclips.
  • the playGame function is currently empty. We will use it in the next tutorial.
  • unload(new MainMenu(stageRef)); This unloads our menu(by calling unload from our BaseMenu class) and loads the instance of MainMenu that we are passing into it.

See I told you it was simple! This tutorial is finished. Here’s the final SWF & source:

Menus, UI, Screens, or Windows Complete Source Zip Archive

Similar Posts:


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


About the Author

Par
Hey! Don't be surprised, I'm a flash developer. While Flash is definitely one of my favorite languages to develop in, most of all I just like making games. If you want to see the games I've developed so far head over to my website, DigitallyBold, in the link below. If you want to know more about what I'm working on now and in the future be sure to follow me on twitter.




44 Comments


  1. I think this tutorial would be the perfect situation to introduce interfaces. Btw:

    if (loadNext != null)

    can just be

    if (loadNext)

    Great tutorial!


  2. Par

    thanks and yep :D . I’m still trying not to confuse people though :D


  3. Jacobs

    Haven’t read it yet, but it seems nice, i’ll review it later, thanks.


  4. Really Nice Tutorial, thankx a lot guys !

    And Btw, the Base Class you have mentioned is also called “Abstract Class”


  5. miyijura

    Excellent tut Par.
    I will try it now!


  6. cyberninja

    Nice tutorial Par :)

    Can’t wait for the next one …

    I’m wondering how you would setup the game since the base class of the game usually extends MovieClip .. How would you make it work if it extends the BaseMenu ???


  7. good job, continue !


  8. BugSlayer

    Awsome tutorial.
    Moar! Moar!

    (Has anyone seen the tutorial with jumping targets here on asgamer?
    I thought there was one.)


  9. Vathian

    Has asgamer.com died? I visit this site daily in hopes of more content and it’s been a rather long time since an update…

    Anyone have any idea what’s going on?


  10. Par

    Not dead. Just a hiatus.


  11. Marie

    Perhaps I don’t have a very strong sense of AS3 yet, but I’ve been following this tutorial to then end, and now want to try and insert my gamecode into it.

    This is from the MainMenu.as file:

    public function playGame(e:MouseEvent) : void
    {
    PlayGame();
    }

    PlayGame() is comes from PlayGame.as, it doesn’t seem to want to play any code from there. But it works fine (not as pretty) when I just drop all the game code into the actual function. I was just wondering if there was a way to maintain separation.


  12. Steve

    I was trying to continue and start a place where I can add code for the game. So I made a new folder and called it Start
    the from MainMenu.as like so:

    private function playGame(e:MouseEvent) : void
    {
    //load the start page for the game
    unload(new Start(stageRef));
    }

    My question is should I have my game code here (on Start) or should it be in the Engine.as? Seems like it should go Engine.as Not sure how to proceed :(

    great tutorial…….can’t wait to see how to tie it all together!


  13. No new posts in this series since april 27th :( You sure you’re just on hiatus?


  14. Par

    very long hiatus


  15. james

    Hi. i have been following you tutorials and i have always been wondering about menu’s. HOW THE HECK DO YOU ADD A MENU TO AN ALREADY COMPLETED FLASH GAME?


  16. misterbluedot

    Hey Par, good to see some new stuff back on the site. Thought I might point something out tho:

    In the Engine’s loadAsset() function, if you simply change “this.play;” to “gotoAndStop(3);” you don’t have to nullify your functions parameters. You’re still passing frame 2 so everything gets loaded for the engine to use, but you never display frame 2, so linked MCs in the asset holder won’t cause the #1009 error.


  17. Siddin

    First of all I’d like to thank you for these excellent tutorials, Par.

    But I have a question. I’m trying to start my game from the MainMenu class, as you’ll probably explain in your next tutorial. I have no idea how to do this.
    Can you help?


  18. aks

    hi there , nice tutorial

    but i didnt get only one thing. what will be the code inside the
    playGame function ??????

    plz can any one help me with this.

    by the way thanks a lot man greate tutorial i followed the complete tutorial. love u man….


  19. iqbal

    hai all,

    i get an error:1120: Access of undefined property btnPlay.


  20. If you are having problems with merging this tutorial to the shooter game tutorial visit the forums. http://asgamer.com/forum/viewtopic.php?f=3&t=79


  21. Here is how to put the code to start the game based on this model:

    in the play game function:
    private function playGame(e:MouseEvent) : void
    {
    this.stageRef.dispatchEvent(new Event(“gameSTART”));

    }
    and in the Engine.as, under the preLoader.addEventListener…stuff, add the following:
    stage.addEventListener(“gameSTART”, fGameStart);

    then in the Engine.as, create the following function:

    private function fGameStart(evt:Event):void {

    //code to start your game goes here…

    }

    It works great for me…..in fact I added four different game start buttons (various difficulty) and just process which one was clicked.

    Great set of tutorials by the way!


  22. I don’t see the point in the stageRef variables you seem to use quite a bit. To avoid those, you should just add the ADDED_TO_STAGE listener in your constructor and perform methods that need the stage inside that method. Then if you want to use the stage after its been added, you can just call “stage”, because it has been added to it.

    For example, if a sprite is added to the stage, just call stage.removeChild(sp); instead of stageRef.removeChild(sp); and having to pass a stage ref in for each constructor.


  23. Par

    Entirely preference. Not always everything that will need a reference of the stage will need to be added to the stage. For that reason I just pass it through to the classes I know will need it. However, if you want to do it your way, that’s absolutely fine. Both work.


  24. didi

    Par, everything works great! Only one problem.

    How the heck do I remove the MainMenu screen when I click the play button?

    The game works, but its hard to play when the mainmenu screen is on the game field ;)


  25. sharad

    Hi,

    There one bug …. any directly accessed class and its dependencies from document class will be loaded in frame one.

    So if you access menu that way …. or other stages of games …. it will all get loaded in frame one making the preloader useless.

    A work around is to access it indirectly as

    var menu:Class = getDefinitionByName(“MainMenu”) as Class;

    But you wont be able to compile this as compiler wont include MainMenu (cause its not directly referenced anywhere).

    So here is main hack … create a movieclip symbol named AllClasses. Add AllClasses.as as its corresponding link class. Refer to dangling classes in this AllClasses class as

    “var dummyVar:MainMenu”

    And you are done.


  26. Lord_Damascus

    I was wondering about the follow up tutorial to this one that has the actual game and gravity and such implimented… it was Up before the Hacking, but disappeared after… where you ever going to repost this…?


  27. Madsen

    Pete, I have tried to start my game the way you described, but i get error:

    at line: this.stageRef.dispatchEvent(new Event(“gameSTART”));

    error: Call to a possibly undefined method Event.

    Any other ideas how to implement game?


  28. You have forgotten to provide a link between the completion of the pre-roll, and the loading of the menus.

    In the last section funtion showMenus() was left with a simple traces(“show menus”). You have overlooked providing the code to begin loading the menus from assetHolder

    private function showMenu(e:Event) : void{

    new MainMenu(stage).load();
    }


  29. Thanks for a fantastic tutorial series, they have been really instructive, and I have learned much from them.

    It would be great to see a tutorial that ties the lessons from the basic ship shooter game together with this series on preloading and menus etc…..to clarify switching from the preload/menu state to actual gameplay.

    Would I be correct in assuming that the class GameEngine here must assume the same functions and instances as class Engine in Ship Shooter, or is it possible to have two “engines” as it were?

    I guess “try it and see” will have to suffice for now -and experimentation is the master teacher after all!

    Thanks again anyway


  30. Although sometimes I get errors when following your tutorials I come to realise it’s due to my typos or misreading something ^^

    Thankyou very much for these fantastic tutorials, they are so clear and explain (almost) all that is needed :P

    I wish you would make some more tutorials :D They are all AWESOME!


  31. Reapering

    I followed everything you done but when i run it, it only simulates the preloader and then nothing.Just a blank screen. Why is the main menu not loading?

    I also downloaded your final SWF and source and the same thing happens.


  32. RamenNoodles

    I got it work fine, make sure you have this

    private function showMenu(e:Event):void
    {
    new MainMenu(stage).load();
    }

    in the Engine or whatever you named your main script. That was the problem I had when the screen would just be blank after the sponsers frame.

    The problem I’m having now is what to do next lol. I tried loading the game scene link a menu but I keep getting an object null reference error, and all the game objects would load right away during the preroll. I even set the all new scripts and movie clips I to NOT export on frame 1.

    Does this mean I would have to insert a new keyframe and have the game in there and just have the “Play Game” button have

    gotoAndPlay(3);

    Or is there a better way?

    With the way the tutorials are going I would assume just making a new keyframe with the game is not good flash practice.

    I hope the next tutorial comes up soon :D


  33. Daniel

    I have implemented your solution into my game and it worked absolutely fine except even though I un-ticked all the “Export to frame 1″ I still get all my assets loading on the first frame thus making the preloader taking a while to appear. I tried creating a new game from scratch following your tuts but get the same error. Really confusing, read your tut over and over but still don’t get why??


  34. dash

    hello there i just wondering can this games or the codes be used for flash lite…and i stupid NOOB(me) question where do u put these codes is it on the first frame ..or on actions layer or on the items

    im a new beginner for flash need ur help pls email me ur answer
    to
    devildash47@yahoo.com

    ur tutorial is the best!!!!


  35. Ian

    Please finish this tutorial. What a monster cliffhanger you have left us. I need to know what goes in the Play button.


  36. BamLib

    I’m really enjoying your tutorials so far and I’m extremely grateful that they’re here.
    Just a quick question though, when about’s is the next part of the series of tutorials coming?
    Also my friend has few good tutorials of his own, would it be alright if he gave them to you to put up here?


  37. Mike

    Yup, same problem as Daniel. I put all this work into the game and now I can’t even get a preloader working. Also, I’m getting errors with the Tweener in your downloaded final files before I even touch them.


  38. rob

    hi, does any one have a finished game with a menu linked to the game, in the method describe in these tutorials. cause i cant figure out what code starts my game and how to remove the menu ect.


  39. JRF

    Same question as rob-If any one got this to work with their game please post your code. So we have some idea of how it is done-please!


  40. JRF

    I got it!
    Just follow this tutorial just as if your game didn’t exist yet.
    Make sure you get each of the 3 parts working and your game loading before you get to the next part.
    Also I used the Stage document background color set to black,instead of using the rectangle in the very beginning.Since I could not change my games document without breaking it.
    Then I just set it up using Pete says:
    February 7, 2010 at 9:56 am-
    in the play game function:
    private function playGame(e:MouseEvent) : void
    {
    this.stageRef.dispatchEvent(new Event(”gameSTART”));

    }
    and in the Engine.as, under the preLoader.addEventListener…stuff, add the following:
    stage.addEventListener(”gameSTART”, fGameStart);

    then in the Engine.as, create the following function:

    private function fGameStart(evt:Event):void {

    //code to start your game goes here…
    myPerson = new Person(stage);
    myPerson.x = stage.stageWidth / 2;
    myPerson.y = stage.stageHeight / 2;
    stage.addChild(myPerson);

    scoreHUD = new ScoreHUD(stage); //create our HUD
    stage.addChild(scoreHUD); //and display it.

    myGerm = new Germ(stage, myPerson);
    stage.addChild(myGerm);

    trace(GermRemoved );
    if (GermRemoved == 0)
    {
    addEventListener(Event.ENTER_FRAME, loop, false, 0, true);
    trace(“Yesloop”);
    //GermRemoved = 1;
    trace(GermRemoved );
    }
    else
    {
    trace(“Noloop”);
    }

    }
    Basically I waited to add anything to stage form my game until I was ready to press the play button.
    Finally to get rid of the Main Menu I just added:
    unload();
    to
    private function playGame(e:MouseEvent) : void
    {
    unload();
    this.stageRef.dispatchEvent(new Event(“gameSTART”));
    }
    And now to continue with my game development!
    Hope this helps someone.


  41. Great tutorial!, this save me a lot of time thinking on how to separate some component in my game and screens clases for less coupling between presentation and logic of the game code. :D


  42. Nekyo

    In some case that you get 2025 error in remove function of base class , change
    if (stageRef.contains(this))
    stageRef.removeChild(this);

    to

    if (this.parent.contains(this))
    this.parent.removeChild(this);


  43. @JRF yes, thank you so much for that little nudge, if this is just the beginning I wonder how much harder it gets… should’ve studied this in college instead of marketing :)


  44. Ann

    Thanks JRF!!! Your solution for starting the game play works great. If anyone gets a 1093 Syntax error after pasting the code, just retype it. It’s probably the parentheses “”.

    Par your tutorials are fantastic! Much thanks for taking the time to share. :)



Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="" highlight="">


Advertisement