Tutorials

March 2, 2009

AS3 Flash Games for Beginners: Scores, HUDS, and User Interface

More articles by »
Written by: Par
Tags: , , , , , , ,
basics9_tn

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

So what’s the point of having a flash game if there isn’t some way to keep score? Whether it be as simple as an incrementing number or as complex as graphics flying all over the place and icons flashing… your game (if it’s a typical game) has to track score.  Ever since I’ve worked with games (particularly FPS games) we’ve called this our HUD.  HUD stands for Heads Up Display and originated in combat air crafts.  In our case, the HUD will keep track of our score in our game but it could be used to keep up with ammo, health, lives, awards, names…. anything. So let’s get started making a heads up display to display our scores :)

This is the FINAL ARTICLE in the series AS3 Flash Games for Beginners. I hate to finish the series but it’s covered a lot of topics for building a flash game from scratch. A new series will begin soon that will cover packaging and set up of a flash game for public distribution so you can make some money off your game.  Anyway, this is the final article in the series so if you would like to start from the beginning and follow through to here, just use the table of contents above.

You’ll need the source code from the last tutorial so grab it:
Previous Tutorial Final Source Code

Step 1: Drawing our Scores in our HUD

Alright so make a new MovieClip and name it scoreHud. Now draw how you want your HUD to look. Wow, that’s vague. Yep, very vague.  But here’s the important part. Make sure your registration is at the top left of your artwork. This is my personal preference, All graphics and user interface objects I prefer to keep there registration at the top left. This way I can manage their ActionScript positioning the same way.

So you want some guidance on how to design the hud? If so here’s an image of my mockup to go by. But feel free to design your own. Just read the following paragraphs to make sure you know how to set everything up.

basics1_9step1-1

Image of the Game Score HUD in Flash. Used to display our game's score, kills, and times hit.

Okay, the image should be pretty self explanatory but here’s how I made it. I used the Rectangle Tool (R) to create the box (width: 223, height: 32). Then taking the Text Tool (T) I wrote out Kills, Times Hit, and Score then spaced them accordingly. There’s a simple line Tool (N) made divider between each section. Then I created 3 dynamic text fields to hold the values for kills, times hit, and score.

So since we haven’t talked about text yet in the series. Let’s take a second to discuss it. The font I am using is a pixel font. Pixel fonts are intended for small font sizes where normal fonts tend to blur and lose detail.  A search on Google for free pixel fonts should return you plenty of results. If you use a pixel font I recommend changing the anti-alias option to Bitmap Text.

Fonts in Flash also must be embedded in order to insure the user will see the correct font. If you don’t embed your font and the client doesn’t have the font, they’ll likely see Times New Roman (at least on a Windows machine). Certain fonts like Arial are rather universal and should be on a LARGE majority of computers. To prevent users seeing the wrong font, we have two options.

First we can break apart our font, this works great if our text never changes. Like in the case of our HUD, kills will always say kills. So I broke apart the font. To do this, just right click the font (on the scene) and choose Break Apart. Now you should have a separate text field for each letter. Just right click again and select Break Apart once more. Now it should be vectorized, this text is good to go, no embedding is needed.

The Second option is to Embed the font. A dynamic and input text field must be embedded to ensure the user will display the correct font. So for the values of kills, times hit, and score let’s embed (104 in my drawing).  To embed a font it must first be a dynamic or input text field. So to make a text field dynamic just set at the top left of the Properties window. It defaults to Static Text.  Great, now click “Embed…” and select Numerals [0-9]. This will only embed numbers and in our case it’s all we need.

Properties Window for a Textfield in flash. Make sure to set your type to Dynamic in order to enable the Embed Option

Properties Window for a Textfield in flash. Make sure to set your type to Dynamic in order to enable the Embed Option

Alright. Finally, you need to set an instance name for each of your dynamic text fields. I named them kills, hits, and score. I suggest for clarity sake through the rest of the tutorial that you do the same.

Okay our HUD user interface is designed… now let’s use it. Right click on scoreHud in the library and select Linkage…  Export for ActionScript and set the class to com.asgamer.basics1.ScoreHUD and OK.

Step 2: Coding our HUD to update when Score change.

So we’ve got our ScoreHUD designed but we can’t display anything with our ScoreHUD when we haven’t coded it yet. So let’s go ahead and code our ScoreHUD.as class first. It’s a simple class so here’s all the source for it. I’ll explain it afterwards.

package com.asgamer.basics1
{
 
	import flash.display.MovieClip;
	import flash.display.Stage;
	import flash.text.TextField;
	import flash.events.Event;
 
	public class ScoreHUD extends MovieClip
	{
 
		private var stageRef:Stage;
		public var s_score:Number = 0;
		public var s_hits:Number = 0;
		public var s_kills:Number = 0;
 
		public function ScoreHUD(stageRef:Stage)
		{
 
			this.stageRef = stageRef;
 
			kills.text = "0";
			hits.text = "0";
			score.text = "0";
 
			x = 10;
			y = stageRef.stageHeight - height - 10;
 
		}
 
		public function updateKills(value:Number) : void
		{
			s_kills += value;
			kills.text = String(s_kills);
		}
 
		public function updateHits(value:Number) : void
		{
			s_hits += value;
			hits.text = String(s_hits);
		}
 
		public function updateScore(value:Number) : void
		{
			s_score += value;
			score.text = String(s_score);
		}
 
	}
 
}

Alright the breakdown:

  • First we import everything we need. The only new import here is flash.text.TextField. We need this so we can edit the text in our dynamic text fields.
  • We have our stageRef as a class variable with three number variables all prefixed with s_. The s_ just tells me it’s a stat variable.  It’s not required and just a preference. Also it is because we cannot use kills, hits, and score as the variables since that is the name of our text field instances in the scoreHud MovieClip.
  • In our constructor we set our stageRef reference to the class variable and then we default all our text fields to “0″. To change the text in a text field you just change the text property of the text field.
  • Lastly in our constructor we put our ScoreHUD object in the bottom left of the screen with a 10 pixel padding from the edge.
  • Now  we have 3 functions: updateKills, updateHits, and updateScore. They are all pretty much identical, update the class variable and change what is being displayed in the HUD. We wrap String() around each of the variables because they need to be converted from Numbers to Strings before they can be set as the text property of a text field.

That’s pretty simple, and it’s all we need our ScoreHUD class to do. Just keep variables to store the numbers and with each update change what is being displayed to the user.

Step 3: Dispatching Events so they can be caught by addEventListener.

Okay so before we can use our HUD we’re going to have to track our stats. We’ll do this by setting up some new events that fire when and enemy gets killed and when our character ship gets hit.

Okay open Stinger.as we’ll add one simple thing… and fix a small bug.

package com.asgamer.basics1
{
 
	import flash.display.MovieClip;
	import flash.display.Stage;
	import flash.events.Event;
 
	public class Stinger extends MovieClip
	{
 
		private var stageRef:Stage;
		private var vy:Number = 4;
		private var ay:Number = .2;
		private var target:Ship;
 
		public var points:int = 1020; //the points for killing this enemy
 
		public function Stinger(stageRef:Stage, target:Ship) : void
		{
			stop();
			this.stageRef = stageRef;
			this.target = target;
 
			x = Math.random() * stageRef.stageWidth;
			y = -5;
 
			addEventListener(Event.ENTER_FRAME, loop, false, 0, true);
		}
 
		private function loop(e:Event) : void
		{
			if (currentLabel != "destroyed")
			{
				vy += ay;
				y += vy;
 
				if (y > stageRef.stageHeight)
					removeSelf();
 
				if (y - 15 < target.y && y + 15 > target.y)
					fireWeapon();
			}
 
			if (currentLabel == "destroyedComplete")
				removeSelf();
		}
 
		private function fireWeapon() : void
		{
			stageRef.addChild(new StingerBullet(stageRef, target, x, y, -8));
			stageRef.addChild(new StingerBullet(stageRef, target, x, y, 8));
		}
 
		private function removeSelf() : void {
 
			removeEventListener(Event.ENTER_FRAME, loop);
 
			if (stageRef.contains(this))
				stageRef.removeChild(this);
 
		}
 
		public function takeHit() : void
		{
			if (currentLabel != "destroyed") //insure we can't keep killing the enemy ship... over and over
			{
				dispatchEvent(new Event("killed")); //our new ship killed event
				rotation = Math.random() * 360;
				gotoAndPlay("destroyed");
			}
		}
 
	}
 
}

We added a new class variable points. Everything else new is in takeHit. Here’s the Breakdown:

  • public var points:int  = 1020; I’m adding this in so we can give a special number of points for killing this enemy. If all our enemies have a points variable then we can take the points variable when the enemy dies and call it to get different points for killing different enemies. That was a mouth full. Simply put, each enemy can have a different points value that is awarded when they are killed, we’ll do this by giving each enemy a points variable.
  • if (currentLabel != “destroyed”) This should have been added the last tutorial.  Without it we can keep shooting the enemy ship over and over and it will keep exploding. Mistake on my part. Sorry… Don’t worry though, unless you’re flawless you’ll find little bugs like this are a part of programming.
  • dispatchEvent(new Event(“killed”)); You know when we write addEventListener? Well it’s looking for these. Our addEventListener’s are looking for dispatched Events. So if we dispatch a new Event called “killed” we can use an addEventListener(“killed”, function) to listen for it. Simple, yet very effect.

Now we need our Ship to dispatch when it takes a hit. Just one problem… Currently our ship has no idea when it get’s hit.  Yes yes, we do get a small yellow explosion when it happens. But our Ship class has no idea that ever occured… only the enemy bullet class knows it happened. So we’re going to need to classes updated here. Let’s open Ship.as and StingerBullet.as. We will make StingerBullet call the function takeHit in Ship when a hit occurs. So here’s the new source code for StingerBullet.

package com.asgamer.basics1
{
 
	import flash.display.MovieClip;
	import flash.display.Stage;
	import flash.events.Event;
 
	public class StingerBullet extends MovieClip
	{
 
		private var stageRef:Stage;
		private var target:Ship;
 
		private var vx:Number;
 
		public function StingerBullet(stageRef:Stage, target:Ship, x:Number, y:Number, vx:Number) : void
		{
			this.stageRef = stageRef;
			this.target = target;
			this.x = x;
			this.y = y;
			this.vx = vx;
 
			addEventListener(Event.ENTER_FRAME, loop, false, 0, true);
		}
 
		private function loop(e:Event) : void
		{
			x += vx;
 
			if (x > stageRef.stageWidth || x < 0)
				removeSelf();
 
			if (hitTestObject(target.hit))
			{
				target.takeHit();
				stageRef.addChild(new SmallImplosion(stageRef, x, y));
				removeSelf();
			}
		}
 
		private function removeSelf() : void
		{
			removeEventListener(Event.ENTER_FRAME, loop);
			if (stageRef.contains(this))
				stageRef.removeChild(this);
		}
 
	}
 
}

One line added. That’s all.

  • target.takeHit(); Well, you know exactly what this is. We’re calling takeHit function in the target. The target being the Ship class object… But we don’t have a takeHit function in Ship. Let’s make it.

Just add this function somewhere in your ship class.

		public function takeHit() : void
		{
			dispatchEvent(new Event("hit"));
		}

Well… does this need a breakdown? Not really it’s the same as before. We’re just dispatching an event when our ship takes a hit. We’re calling it hit this time.

Step 4: Catching Events with addEventListener

So we’ve got our ship and our enemy ship dispatching events when they are killed or hit. Now we need to do something with them.  Since our ship and the enemy ships are both created in the Engine class let’s catch our event dispatches there. And we need to create an object from our ScoreHUD class so let’s do it in the Engine class as well.  Here’s the new source code for Engine.as:

package com.asgamer.basics1
{
	import flash.display.MovieClip;
	import flash.display.Stage;
	import flash.events.Event;
 
	public class Engine extends MovieClip
	{
 
		private var numStars:int = 80;
		public static var enemyList:Array = new Array();
		private var ourShip:Ship;
 
		private var scoreHUD:ScoreHUD; //our HUD
 
		public function Engine() : void
		{
			ourShip = new Ship(stage);
			ourShip.x = stage.stageWidth / 2;
			ourShip.y = stage.stageHeight / 2;
			ourShip.addEventListener("hit", shipHit, false, 0, true); //if hit is dispatched call shipHit function
			stage.addChild(ourShip);
 
			scoreHUD = new ScoreHUD(stage); //create our HUD
			stage.addChild(scoreHUD); //and display it.
 
			for (var i:int = 0; i < numStars; i++)
			{
				stage.addChildAt(new Star(stage), stage.getChildIndex(ourShip));
			}
 
			addEventListener(Event.ENTER_FRAME, loop, false, 0, true);
 
		}
 
		private function loop(e:Event) : void
		{
			if (Math.floor(Math.random() * 90) == 5)
			{
				var enemy:Stinger = new Stinger(stage, ourShip);
 
				enemy.addEventListener(Event.REMOVED_FROM_STAGE, removeEnemy, false, 0, true);
				enemy.addEventListener("killed", enemyKilled, false, 0, true); //catch when the enemy is killed
				enemyList.push(enemy);
				stage.addChild(enemy);
			}
		}
 
		private function enemyKilled(e:Event) : void
		{
			scoreHUD.updateKills(1); //add 1 to enemy kills
			scoreHUD.updateScore(e.currentTarget.points); //add that points variable we created earlier
		}
 
		private function removeEnemy(e:Event) : void
		{
			enemyList.splice(enemyList.indexOf(e.currentTarget), 1);
		}
 
		private function shipHit(e:Event) : void
		{
			scoreHUD.updateHits(1); //add 1 to number of hits
		}
 
	}
 
}

And the breakdown:

  • private var scoreHUD:ScoreHUD; simply adding it as a class variable.
  • ourShip.addEventListener(“hit”, shipHit, false, 0, true); so if hit gets dispatched from our ship object we call the shipHit function
  • scoreHUD = new ScoreHUD(stage); Just creating our scoreHUD, next line we add it to the stage. Nothing new really.
  • enemy.addEventListener(“killed”, enemyKilled, false, 0, true); Our enemy is created now we need to make sure when he is killed we know it. So we add a listener to catch when “killed” is dispatched. When it is we call enemyKilled.
  • private function enemyKilled(e:Event). In this function we simply use our ScoreHUD class functions to add a kill and add to our score. The points variable we added to enemy earlier is added to our total score. e.currentTarget allows us to grab the object that dispatched the event. We’ve used it before so you should have no problem understanding it.
  • private function shipHit(e:Event). Here we simply add 1 to the number of times our ship has been hit.

Alright that’s everything. Compile your flash and you should have a working HUD!

Okay, in closing this series I want to remind everyone that this is a basics series. My goal was to take you through what you would need to know to begin developing a flash game. By now I think you have the gist of how flash works with game development. Where you go from here depends on your programming knowledge and willingness to experiment with the code. Please feel free to have fun with what we have already created and make something different. If you went your own way with this tutorial and created your own enemies, ships, bullets, and lasers I would love to see your games.  Even feel free to write an article about how you used this tutorial to create a game and what you did differently.  If I find your game or article interesting I’ll gladly add them to the site so you can get some publicity to start off your flash game development career :)

I also want to let you know that more series of articles will be appearing on the website in the nearby future that will take you through packaging and making a complete flash game for portal distribution. So stick around and keep an eye out for this new series.

Here’s the final final source code:

AS3 Flash Games for Beginners: Scores, HUDS, and User Interface Source Code 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.




71 Comments


 
 

  1. Reapering

    This tutorial is so Awesome! All other tutorials were not as detailed like you did, Thank you! I mean it and very grateful.

    I always get excited when you said “Here’s the Breakdown”,
    Thumbs Up to that phrase ^^ I love to know something instead of not knowing whats going on.


  2. bobby

    This guy deserves a medal, very clear tutorial, helped me a lot!


  3. Marc Karsai

    The tutorial is great, and I love it and get it so far, but the class I’m in is having some trouble with a few things, and our regular teacher isn’t here, and even when he is, he has troubles, but the HUD is a little confusing at the moment. We are working with CS5 and some of the instructions aren’t clear to us. It would greatly appreciated if you could help out our class by instruct us on how to make the HUD with CS5 instead of CS3. Most of the other codes and instructions are clear, but this one is a little harder. The code is the same, but embedding some of the objects is a little harder. Embedding the text for “kills” and the “104″ is confusing to us. The instructions are not as clear for us with CS5. If you could help out, it would be great.

    Sincerely,
    Marc Karsai

    Email: marckarsai@gmail.com

    P.S. We are high school students.


  4. Ladman

    this tutorial is awesom! i have everything working in my game but the hud is not woring. i did everything same as you in this tutorial even named everything the same and when i went to play it i got these errors:

    1120: Access of undefined property kills.
    1120: Access of undefined property hits.
    1120: Access of undefined property score.
    1120: Access of undefined property kills.
    1120: Access of undefined property hits.
    1120: Access of undefined property score.

    so i thought they might not be declaired, so i then made kills, hits, and score public var’s, when i did tha i got this error:

    1004: Namespace was not found or is not a compile-time constant.

    I dont understand what im doing wrong.

    i created the hud box, gave the text dynamic, then embed the numbers with [0-9]. then deleted it from the stage like all the other MC’s that were made. what am i doing worong?


  5. Ladman

    ok, now the game works, but i hot no background or enemies all ican see is my ship and it moves and shots. i got this error when it compiled and ran

    TypeError: Error #1010: A term is undefined and has no properties.
    at ScoreHUD()
    at Engine()


  6. Ladman

    figured it all out, it would help if i made my HUD a MC!!!!


  7. Joe

    Glad to see you can no longer infinitely kill a given enemy, even if the functionality *was* added in a bit late.


  8. Naushad

    How to add more interface(new game,pause,stop)


  9. I also wanted to thank you for this wonderful ‘basics series’ tutorial Jonathan. I can only reverberate the praises you’ve received from the other comments. Mainly, that your tutorial is well written, clear, and fun.

    If I don’t get too sidetracked by another project, I should have a cool example soon.


  10. Oh! I forgot to mention. The code portions on this article converts some of the characters to html code. For example: if (y – 15 < target.y && y + 15 > target.y)


  11. Dennis

    I am having a 1120 compile error saying
    public var s_hits
    public var s_kills

    kills.text = “0″;
    hits.text = “0″;
    score.text = “0″;

    are not defined, is s_ a cs3 thing? i am using cs5.5


  12. klutchego

    Dude your tutorial is great!. What about making a tutorial like chess game. I really need to know how it looks like the code in flash as3..Help please!:D


  13. Sean Longmire

    Hi there, great tutorial! Any idea how i would alter the code to set a limit to the score, so for example when he got hit 20 times it would be “Game Over”?


  14. Thomas

    I added a new function called die() to my ourShip class… as shown,

    public function die():void {
    if(stageRef.contains(this)) {
    //
    removeEventListener(Event.ENTER_FRAME, loop);
    //
    var explosion:Explosion=new Explosion(stageRef,1,x,y);
    stageRef.addChild(explosion);
    stageRef.removeChild(this);
    }
    }


  15. Thomas

    I added a new function called die() to my Ship class so that my ship can be removed when it dies. I made it just like all of the objects when they are removed from the stage…

    public function die():void {
    if(stageRef.contains(this)) {
    removeEventListener(Event.ENTER_FRAME, loop);
    //
    stageRef.removeChild(this);
    }
    }

    ….

    and I added to the Engine class…

    var lose:Boolean=false;

    and I have an if statement in my Engine loop function…

    if (hud.s_hits>10 && !lose) {
    ourShip.die();
    lose=true;
    }
    ————————————————————–
    this removes the ourShip object from the screen, but…
    *the enemy ships can still find the ourShip object and fire a stinger bullet
    *all of the hitTests still work as if the ship is just standing still at the place that it died…

    ___________________________________________
    can anyone explain why this is happening?

    basically…
    even though I remove the ship… everything acts as if the ship were still there…

    Thanks


  16. Hi everyone,

    I have an intro to my game (where instructions are displayed, etc) – from this intro.swf, I thought I could just load my game.swf into it.

    So ideally my progression would go:
    intro.swf -> game.swf

    But unfortunately when I click ‘launch game’ in intro.swf, I get thrown a #1009 error for Engine.as.

    Has anybody figured out how to do this, or point me towards a solution.

    Thanks everyone.
    Also this was a very spectacular tutorial series, 5 stars!!!

    -a


  17. TheGreenhorn

    Thank you for the tutorial! The “Here’s the breakdown” parts really helped me in understanding the code. You tutorials are particularly intuitive for beginners like me.

    I hope to see more tutorials done by you!

    Can you make another great tutorial series, this time, tackling the creation of a Platformer?

    Cheers!


  18. Nice work! Thanks! :)


  19. Hi,

    I just finished the entire tutorial and it was great for a noob like me.

    The only problem I have run into is the fact that the kills, hits and score numbers tend to appear upsidown on my screen. Is there a way to prevent this from happening? It would be great to get some help.

    Thanks!


  20. boy wonder

    can somebody help me with this?

    kills.text = “0″;
    kills.text = String(s_kills);


  21. vienna

    great tutorial! i wanna ask, how to make game over to this game?


 
 



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