Creating a Asteroids Flash Game Part 8: Lives, Scores, Restarting, Pausing, Creating Levels, and a Basic GUI

Chris Moeller Web Asteroids Flash Game Part 8 - lives levels and menu

In the last section, we created a way to detect collisions, created particle explosions, and broke the asteroids up into smaller pieces when hit.

In this section, we’ll keep track of the lives, score, make levels, and create a GUI for starting, restarting, and pausing the game.

Creating the GUI System For the Game

We’re going to setup a basic GUI system that allows us to have as many menu screens, buttons, and other GUI eelments that we want, for this project and for future ones.

The First thing We’ll need to do, is create a new folder under ‘src’ called ‘UI’.

Next, create a new class in this folder called ‘UI_element.as’ and enter in the following code:

UI_element.as

package UI
{
	import flash.display.BitmapData;
	import flash.geom.Point;
	import flash.geom.Rectangle;

	public class UI_element
	{
		public var x:Number;
		public var y:Number;
		public var width:int;
		public var height:int;

		public var background:Boolean = false;
		public var bg_color:uint;

		public var visible:Boolean;

		public var image:BitmapData;

		public function UI_element(x:Number=0, y:Number=0, width:int=10, height:int=10, background:Boolean=true, bg_color:uint=0x888888)
		{
			this.x = x;
			this.y = y;
			this.width = width;
			this.height = height;
			this.background = background;
			this.bg_color = bg_color;
			this.visible = true;
			if(background)
				image = new BitmapData(width, height, false, bg_color);
			else
				image = new BitmapData(width, height, true, bg_color);

		}
		public function Render(Renderer:BitmapData):void
		{
			if (!visible)
				return;

			if (background)
				image.fillRect(new Rectangle(0, 0, width, height), bg_color);

			Renderer.copyPixels(image, new Rectangle(0, 0, width, height), new Point(x, y));

		}
		public function Update():void
		{

		}
	}
}

Next, we will want to create a new class for creating buttons.

TextButton.as

package UI
{
	import flash.display.BitmapData;
	import flash.geom.Matrix;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.text.TextField;
	import flash.text.TextFormat;

	public class TextButton extends UI_element
	{
		public var bg_color2:uint;
		public var text:TextField;

		public var hovered:Boolean;
		public var clicked:Boolean;
		public var func:Function;

		public function TextButton(x:Number = 0, y:Number = 0, width:int = 10, height:int = 10, text_str:String="Button", format:TextFormat=null, background:Boolean = true, bg_color:uint = 0x333333, bg_color2:uint=0x666666, func:Function=null)
		{
			super(x, y, width, height, background, bg_color);
			this.bg_color2 = bg_color2;

			text = new TextField();
			if (format == null)
			{
				format = new TextFormat("Arial", 20, 0x000000, true);
				format.align = "center";
			}

			text.width = width;
			text.height = height;
			text.defaultTextFormat = format;
			text.x = x;
			text.y = y;
			text.text = text_str

			hovered = false;
			clicked = false;
			this.func = func;
		}
		override public function Render(Renderer:BitmapData):void
		{
			if (!visible)
				return;

			if (background)
			{
				if(!hovered)
					image.fillRect(new Rectangle(0, 0, width, height), bg_color);
				else
					image.fillRect(new Rectangle(0, 0, width, height), bg_color2);
			}
			image.draw(text, new Matrix(1, 0, 0, 1, 0 , 0 ));
			Renderer.copyPixels(image, new Rectangle(0, 0, width, height), new Point(x, y));
		}
		override public function Update():void
		{
			if (clicked)
			{
				trace("button Clicked!");
				if (func != null)
					func();
				clicked = false;
			}
			hovered = false;
		}
	}
}

And Finally We’ll want to create a “Screen” class that will contain each of our screens that we could want for the game, including the menu screen, pause screen overlay, and the high scores screen.

Screen.as

package UI
{
	import flash.display.BitmapData;
	import flash.geom.Matrix;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.text.TextField;
	import flash.text.TextFormat;
	/**
	 * ...
	 * @author Chris
	 */
	public class Screen extends UI_element
	{
		public var texts:Array;
		public var buttons:Array;

		public function Screen(x:Number = 0, y:Number = 0, width:int = 10, height:int = 10, background:Boolean = true, bg_color:uint = 0x888888)
		{
			super(x, y, width, height, background, bg_color);
			texts = new Array();
			buttons = new Array();
		}
		public function AddText(x:Number, y:Number, width:int, height:int, text_str:String, format:TextFormat=null, color:uint=0xFFFFFF, font:String="Arial", size:int=20, background:Boolean=false, bg_color:uint=0x888888):void
		{
			var text:TextField = new TextField();
			if (format == null)
				format = new TextFormat(font, size, color);

			text.width = width;
			text.height = height;
			text.defaultTextFormat = format;
			text.x = x;
			text.y = y;
			text.text = text_str
			texts.push(text);
		}
		public function AddTextButton(x:Number, y:Number, width:int, height:int, text:String, format:TextFormat = null, color:uint = 0xFFFFFF, font:String = "Arial", size:int = 20, background:Boolean = false, bg_color:uint = 0x888888, bg_color2:uint = 0x333333, func:Function=null):void
		{
			buttons.push(new TextButton(x, y, width, height, text, format, background, bg_color, bg_color2, func));
		}
		override public function Render(Renderer:BitmapData):void
		{
			if (!visible)
				return;

			if (background)
				image.fillRect(new Rectangle(0, 0, width, height), bg_color);

			//next we'll render the texts and buttons
			for (var i:int = 0; i < texts.length; i++)
			{
				image.draw(texts[i], new Matrix(1, 0, 0, 1, texts[i].x , texts[i].y ));
			}

			for (var j:int = 0; j < buttons.length; j++)
				buttons[j].Render(image);

			Renderer.copyPixels(image, new Rectangle(0, 0, width, height), new Point(x, y));
		}
		override public function Update():void
		{
			for (var i:int = 0; i < buttons.length; i++)
			{
				buttons[i].Update();
				if (Game.mouse_pos.x >= x + buttons[i].x && Game.mouse_pos.x <= x + buttons[i].x + buttons[i].width)
					if (Game.mouse_pos.y >= y + buttons[i].y && Game.mouse_pos.y <= y + buttons[i].y + buttons[i].height)
					{
						buttons[i].hovered = true;
						if (Game.mouse_click)
							buttons[i].clicked = true;
					}
			}
		}
	}
}

We'll now need to update "Game.as" to create our screens, and to update and render them when they are selected.

Game.as

package
{
	import Entities.Asteroid;
	import Entities.Bullet;
	import Entities.Explosion;
	import Entities.Ship;
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Sprite;
	import flash.events.KeyboardEvent;
	import flash.events.MouseEvent;
	import flash.geom.Matrix;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.text.TextField;
	import flash.text.TextFormat;
	import flash.utils.getTimer;
	import UI.Screen;

	public class Game
	{
		public var bitmap:Bitmap;
		public static var Renderer:BitmapData;

		private var ship:Ship

		private var keys_down:Array;
		private var keys_up:Array;

		private const LEFT:int = 37;
		private const UP:int = 38;
		private const RIGHT:int = 39;
		private const DOWN:int = 40;
		private const SPACE:int = 32;	

		private const P:int = 80;
		private const R:int = 82;

		private const ESC:int = 27;

		public static var current_time:Number;
		private var bullets:Array;
		private var firing_delay:Number;
		private var last_fired:Number;
		private var bullets_max_life:Number;

		private var asteroids:Array;

		private var explosions:Array;

		private var score_txt:TextField;
		private var score:int;

		private var level_txt:TextField;
		private var level:int;

		private var game_over_txt:TextField;
		private var game_over:Boolean;

		private var lives:int;
		private var starting_lives:int;
		private var death_delay:Number;

		private var level_change_timer:Number;
		private var level_change_delay:Number;

		public var ship_start:Point;

		public var state:int;

		public const MAIN_MENU:int = 0;
		public const VIEW_HIGH_SCORES:int = 1;
		public const ENTER_HIGH_SCORE:int = 2;
		public const PLAYING:int = 3;
		public const PAUSED:int = 4;

		private var main_menu_screen:Screen;
		private var view_high_score_screen:Screen;
		private var enter_high_score_screen:Screen;
		private var paused_screen:Screen;

		public static var mouse_down:Boolean;
		public static var mouse_click:Boolean;
		public static var mouse_pos:Point;		

		public function Game(stageWidth:int, stageHeight:int)
		{
			trace("Game created");
			current_time = getTimer();
			Renderer = new BitmapData(stageWidth, stageHeight, false, 0x000000);
			bitmap = new Bitmap(Renderer);

			ship_start = new Point(Renderer.width / 2 - 6, Renderer.height / 2 - 10);
			ship = new Ship(ship_start.x, ship_start.y, 10, 18);

			keys_down = new Array();
			keys_up = new Array();
			bullets = new Array();
			firing_delay = 200;
			last_fired = 0;
			bullets_max_life = 1000;

			asteroids = new Array();
			explosions = new Array();

			score_txt = new TextField();
			score_txt.width = 700;
			var format:TextFormat = new TextFormat("Courier", 40, 0xFFFFFF, true);
			score_txt.x = 20;
			score_txt.y = 10;
			score_txt.defaultTextFormat = format;
			score = 0;
			score_txt.text = String(score);

			game_over_txt = new TextField();
			game_over_txt.width = Renderer.width;
			var format2:TextFormat = new TextFormat("Courier", 40, 0xFFFFFF, true);
			format2.align = "center";
			game_over_txt.x = 0;
			game_over_txt.y = Renderer.height / 2 - 20;
			game_over_txt.defaultTextFormat = format2;
			game_over_txt.text = "Game Over Man!\nPress 'R' to start a new game";
			game_over = false;

			starting_lives = 4;
			lives = starting_lives;
			death_delay = 2000;

			level_change_delay = 500;
			level_change_timer = 0;

			level_txt = new TextField();
			level_txt.width = 700;
			level_txt.defaultTextFormat = format;
			level_txt.x = 20;
			level_txt.y = 55;
			level_txt.text = "Lvl " + level;

			level = 1;

			main_menu_screen = new Screen(0, 0, Renderer.width, Renderer.height,true, 0x000000);
			var format3:TextFormat = new TextFormat("Courier", 20, 0xFFFFFF, true);
			format3.align = "center";
			main_menu_screen.AddText(0, 50, Renderer.width, 100, "Welcome to Program", format3);
			main_menu_screen.AddTextButton(
			Renderer.width / 2 - 75, 100,
			150, 30,
			"Start!", null,
			0x000000, "Courier",
			10, true,
			0x666666, 0x999999,
			StartGame);

			main_menu_screen.AddTextButton(
			Renderer.width / 2 - 75, 150,
			150, 30,
			"View Scores",	null,
			0x000000, "Courier",
			10, true,
			0x666666, 0x999999,
			ShowScores);

			paused_screen = new Screen(0, 0, Renderer.width, Renderer.height, false);
			paused_screen.AddText(0, 100, Renderer.width, 40, "Paused: Press 'P' To Resume", format3);

			view_high_score_screen = new Screen(0, 0, Renderer.width, Renderer.height, true, 0x000000);

			view_high_score_screen.AddText(0, 50, Renderer.width, 20, "High Scores", format3);

			var format4:TextFormat = new TextFormat("Courier", 16, 0xFFFFFF);
			format4.align = "left";

			view_high_score_screen.AddText(
			200, 100,
			200, Renderer.height - 100,
			"1. Chrismweb\n2. Chrismweb\n3. Chrismweb\n4. Chrismweb\n5. Chrismweb\n6. Chrismweb\n7. Chrismweb\n8. Chrismweb\n9. Chrismweb\n10. Chrismweb", format4);

			view_high_score_screen.AddText(
			400, 100,
			200, Renderer.height - 100,
			"100\n100\n100\n100\n100\n100\n100\n100\n100\n100 ", format4);

			view_high_score_screen.AddTextButton(
			Renderer.width / 2 - 150, Renderer.height-100,
			300, 30,
			"Return to Main Menu", null,
			0x000000, "Courier",
			10, true,
			0x666666, 0x999999,
			ShowMainMenu);

			enter_high_score_screen = new Screen(0, 0, Renderer.width, Renderer.height, true, 0x000000);

			enter_high_score_screen.AddText(0, 50, Renderer.width, 100, "You made the high score list! \nEnter Your name:", format3);

			//button to submit score
			enter_high_score_screen.AddTextButton(
			Renderer.width / 2 - 100, Renderer.height-300,
			200, 30,
			"Submit Score", null,
			0x000000, "Courier",
			10, true,
			0x666666, 0x999999);

			//button to return to main menu
			enter_high_score_screen.AddTextButton(
			Renderer.width / 2 - 150, Renderer.height-100,
			300, 30,
			"Return to Main Menu", null,
			0x000000, "Courier",
			10, true,
			0x666666, 0x999999,
			ShowMainMenu);

			mouse_down = false;
			mouse_click = false;
			mouse_pos = new Point(0, 0);

			state = MAIN_MENU;

		}
		public function ShowMainMenu():void
		{
			state = MAIN_MENU;
		}
		public function ShowScores():void
		{
			state = VIEW_HIGH_SCORES;
		}
		public function StartGame():void
		{
			state = PLAYING;
			LoadLevel(1);
		}
		public function LoadLevel(num:int):void
		{
			if(level==1)
				ResetGame();
			ResetShip();
			asteroids = new Array();
			bullets = new Array();
			explosions = new Array();
			level = num;
			level_txt.text = "Lvl " + level;
			//every level the number of asteroids increase until 12 on screen at once, after that the levels just keep resetting

			//setup four first asteroids
			asteroids.push(new Asteroid(Renderer.width / 5, 2 * Renderer.height / 3, 0, 0, 1));
			asteroids.push(new Asteroid(Renderer.width / 5, Renderer.height / 4, 0, 1, 0));

			asteroids.push(new Asteroid(2*Renderer.width / 3, 1 * Renderer.height / 3, 0, 2, 1));
			asteroids.push(new Asteroid(2*Renderer.width / 3, Renderer.height, 0, 3, 0));

			if (num > 1)//5
				asteroids.push(new Asteroid(Renderer.width / 5, 1 * Renderer.height / 3, 0, 0, 1));
			if (num > 2)//6
				asteroids.push(new Asteroid(Renderer.width ,  Renderer.height / 5, 0, 0, 1));
			if (num > 3)//7
				asteroids.push(new Asteroid(Renderer.width / 2, Renderer.height, 0, 1, 1));
			if (num > 4)//8
				asteroids.push(new Asteroid(2*Renderer.width / 3, 2 * Renderer.height / 3, 0, 1, 1));
			if (num > 5)//9
				asteroids.push(new Asteroid(Renderer.width / 7, 3*Renderer.height / 4, 0, 2, 1));
			if (num > 6)//10
				asteroids.push(new Asteroid(Renderer.width / 2, 2 * Renderer.height / 8, 0, 2, 1));
			if (num > 7)//11
				asteroids.push(new Asteroid(4*Renderer.width / 5, Renderer.height, 0, 3, 1));
			if (num > 8)//12
				asteroids.push(new Asteroid(2*Renderer.width / 3, 2 * Renderer.height / 3, 0, 3, 1));
		}
		public function Render():void
		{

			Renderer.lock();
			Renderer.fillRect(new Rectangle(0, 0, Renderer.width, Renderer.height), 0x000000);

			if (state == PLAYING || state == PAUSED)
			{

				if(state!=PAUSED)
					ship.Render();

				for (var i:int = 0; i < bullets.length; i++)
					bullets[i].Render();

				for (var j:int = 0; j < asteroids.length; j++)
					asteroids[j].Render();

				for (var k:int = 0; k < explosions.length; k++)
					explosions[k].Render();

				//Renderer.draw(score_txt);
				Renderer.draw(score_txt, new Matrix(1, 0, 0, 1, score_txt.x , score_txt.y ));
				Renderer.draw(level_txt, new Matrix(1, 0, 0, 1, level_txt.x , level_txt.y ));

				for (var p:int = 0; p < lives; p++)
					Game.Renderer.draw(ship.image_sprite, new Matrix(1,0,0,1,score_txt.x+(ship.width+2)*p, 35));
				if (game_over)
					Renderer.draw(game_over_txt, new Matrix(1, 0, 0, 1, game_over_txt.x , game_over_txt.y ));

				if (state == PAUSED)
					paused_screen.Render(Renderer);
			}
			else if (state == MAIN_MENU)
				main_menu_screen.Render(Renderer);
			else if (state == ENTER_HIGH_SCORE)
				enter_high_score_screen.Render(Renderer);
			else if (state == VIEW_HIGH_SCORES)
				view_high_score_screen.Render(Renderer);	

			Renderer.unlock();
		}

		public function Update():void
		{
			current_time = getTimer();

			if (state == PLAYING)
			{
				if (CheckKeyUp(ESC))
					state = MAIN_MENU;
				if (CheckKeyUp(P))
					state = PAUSED;
				if (CheckKeyUp(R))
				{
					LoadLevel(1);
					keys_up = new Array();
					return;
				}

				if (ship.visible)
				{
					if (CheckKeyDown(LEFT))
						ship.RotateLeft();

					if (CheckKeyDown(RIGHT))
						ship.RotateRight();

					if (CheckKeyDown(UP))
						ship.Thrust(1);
					if (CheckKeyDown(DOWN))
						ship.Thrust( -1);				

					if (CheckKeyDown(SPACE) && current_time-last_fired > firing_delay)
					{
						var x:int = 0 * Math.cos(ship.angle) + ship.rotate_offset.y * Math.sin(ship.angle)+ship.x+ship.rotate_offset.x;
						var y:int = 0 * Math.sin(ship.angle) - ship.rotate_offset.y * Math.cos(ship.angle)+ship.y+ship.rotate_offset.y;

						bullets.push(new Bullet(x, y, current_time, ship.angle));
						last_fired = current_time;
					}
					ship.Update();
				}
				else if (CheckKeyDown(R))
				{
					game_over = false;
					score_txt.text = String(score);
					asteroids = new Array();
					bullets = new Array();
					LoadLevel(1);
				}

				var bullets_to_delete:Array = new Array();
				for (var i:int = 0; i < bullets.length; i++)
				{
					bullets[i].Update();
					if (current_time-bullets[i].life > bullets_max_life)
					{
						bullets_to_delete.push(i);
						continue;
					}

					var asteroid_hit:int = -1;
					for (var i2:int = 0; i2 < asteroids.length;i2++)
						if (bullets[i].CheckIfInNonRotatedRect(asteroids[i2]))
						{
							asteroid_hit = i2;
							break;
						}
					if (asteroid_hit != -1)
					{
						DestroyAsteroid(asteroid_hit);
						bullets_to_delete.push(i);
					}
				}
				for (var j:int = 0; j < bullets_to_delete.length;j++ )
				{
					bullets.splice(bullets_to_delete[j], 1);
				}
				var asteroid_ship_hit:int = -1;
				for (var k:int = 0; k < asteroids.length; k++ )
				{
					asteroids[k].Update();
					if (ship.CheckIfInNonRotatedRect(asteroids[k]))
					{
						asteroid_ship_hit = k;
						break;
					}
				}
				if (asteroid_ship_hit != -1)
				{
					lives--;
					ship.visible = false;
					explosions.push(new Explosion(ship.x, ship.y, 1500,2));
					explosions.push(new Explosion(ship.x, ship.y, 500));
					DestroyAsteroid(asteroid_ship_hit);
					if (lives > 0)
						ship.ship_death_time = current_time;
					else
						game_over = true;
				}

				var explosions_to_delete:Array = new Array();
				for (var m:int = 0; m < explosions.length;m++ )
					if (current_time-explosions[m].life > explosions[m].max_life)
						explosions_to_delete.push(m);
				for (var n:int = 0; n < explosions_to_delete.length; n++)
					explosions.splice(explosions_to_delete[n], 1);

				if (ship.ship_death_time != 0)
					if (current_time-ship.ship_death_time > death_delay)
					{
						ResetShip();
					}
				if (asteroids.length == 0 && !game_over&&level_change_timer==0)
					level_change_timer = current_time;

				if(level_change_timer!=0)
					if (current_time-level_change_timer > level_change_delay)
					{

						level++;
						LoadLevel(level);
						level_change_timer = 0;
						trace("loading level " + level);
					}
			}//end of "playing state
			else if (state == MAIN_MENU)
				main_menu_screen.Update();

			else if (state == PAUSED)
			{
				if (CheckKeyUp(P))
					state = PLAYING;
			}
			else if (state == ENTER_HIGH_SCORE)
				enter_high_score_screen.Update();
			else if (state == VIEW_HIGH_SCORES)
				view_high_score_screen.Update()

			mouse_click = false;
			//clear out the "keys_up" array for next update
			keys_up = new Array();
		}
		public function ResetShip():void
		{
			ship.visible = true;
			ship.angle = 0;
			ship.x = ship_start.x;
			ship.y = ship_start.y;
			ship.speed.x = 0;
			ship.speed.y = 0;
			ship.ship_death_time = 0;
		}
		public function ResetGame():void
		{
			lives = starting_lives;
			score = 0;
			score_txt.text = "0";
		}
		public function DestroyAsteroid(asteroid_hit:int):void
		{
			score += Asteroid.Scores[asteroids[asteroid_hit].size];
			score_txt.text = String(score);
			//trace("score is now =" + score);
			explosions.push(new Explosion(
			asteroids[asteroid_hit].x + asteroids[asteroid_hit].width / 2,
			asteroids[asteroid_hit].y + asteroids[asteroid_hit].height / 2, 1000, asteroids[asteroid_hit].width/4));	

			//now delete the old asteroid, and add 2 new ones in it's place if there are any more sizes left
			var old_asteroid:Asteroid = asteroids[asteroid_hit];
			//if there are more sizes to chose from
			if (old_asteroid.size != Asteroid.Sizes.length - 1)
			{

				var rand_dir:int = Math.floor(Math.random() * (1 + Asteroid.Directions.length - 1 ));

				var rand_dir2:int = rand_dir - 2;
				if (rand_dir - 2 < 0)
					rand_dir2 = rand_dir + 2;

				var rand_type:int = Math.floor(Math.random() * (1 + Asteroid.Types.length - 1 ));
				var rand_type2:int = Math.floor(Math.random() * (1 + Asteroid.Types.length - 1 ));

				//add 2 new asteroids at half the size
				asteroids.push(new Asteroid(
				old_asteroid.x,
				old_asteroid.y,
				old_asteroid.size + 1,
				rand_dir,
				rand_type));

				asteroids.push(new Asteroid(
				old_asteroid.x,
				old_asteroid.y,
				old_asteroid.size + 1,
				rand_dir2,
				rand_type2));
			}
			asteroids.splice(asteroid_hit, 1);
		}
		public function KeyUp(e:KeyboardEvent):void
		{
			trace(e.keyCode);
			//position of key in the array
			var key_pos:int = -1;
			for (var i:int = 0; i < keys_down.length; i++)
				if (e.keyCode == keys_down[i])
				{
					//the key is found/was pressed before, so store the position
					key_pos = i;
					break;
				}
			//remove the keycode from keys_down if found
			if(key_pos!=-1)
				keys_down.splice(key_pos, 1);		

			keys_up.push(e.keyCode);
		}

		public function KeyDown(e:KeyboardEvent):void
		{
			//check to see if the key that is being pressed is already in the array of pressed keys
			var key_down:Boolean = false;
			for (var i:int = 0; i < keys_down.length; i++)
				if (keys_down[i] == e.keyCode)
					key_down = true;

			//add the key to the array of pressed keys if it wasn't already in there
			if (!key_down)
				keys_down.push(e.keyCode);
		}

		public function CheckKeyDown(keycode:int):Boolean
		{
			var answer:Boolean = false;
			for (var i:int = 0; i < keys_down.length; i++)
				if (keys_down[i] == keycode)
				{
					answer = true;
					break;
				}
			return answer;
		}
		public function CheckKeyUp(keycode:int):Boolean
		{
			var answer:Boolean = false;
			for (var i:int = 0; i < keys_up.length; i++)
				if (keys_up[i] == keycode)
				{
					answer = true;
					break;
				}
			return answer;
		}
		public function MoveMouse(e:MouseEvent):void
		{
			mouse_pos.x = e.stageX;
			mouse_pos.y = e.stageY;
		}
		public function MouseDown(e:MouseEvent):void
		{
			mouse_down = true;
		}
		public function MouseUp(e:MouseEvent):void
		{
			mouse_down = false;
			mouse_click = true;
		}
	}
}

We'll also need to update "Main.as" to send the mouse up and down states to the game.

Main.as

package
{
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.KeyboardEvent;
	import flash.events.MouseEvent;

	public class Main extends Sprite
	{
		private var game:Game;
		public function Main():void
		{
			if (stage) init();
			else addEventListener(Event.ADDED_TO_STAGE, init);
		}

		private function init(e:Event = null):void
		{
			removeEventListener(Event.ADDED_TO_STAGE, init);
			// entry point

			//create the game object passing in the swf width and height
			game = new Game(stage.stageWidth, stage.stageHeight);

			//add the game bitmap to the screen/ Main.as Sprite to make it visible
			addChild(game.bitmap);

			//Create the main game loop
			addEventListener(Event.ENTER_FRAME, Run);

			//add keylisteners
			stage.addEventListener(KeyboardEvent.KEY_DOWN, game.KeyDown);
			stage.addEventListener(KeyboardEvent.KEY_UP, game.KeyUp);

			stage.addEventListener(MouseEvent.MOUSE_DOWN, game.MouseDown);
			stage.addEventListener(MouseEvent.MOUSE_UP, game.MouseUp);
			stage.addEventListener(MouseEvent.MOUSE_MOVE, game.MoveMouse);
		}

		private function Run(e:Event):void
		{
		   game.Update();
		   game.Render();
		}
	}
}

Tutorial Demo

In the next section we’ll add the Kongregate API to the game, and create a way to submit the high scores to their servers when the game is live.

Download the source Code and please leave me any comments or feedback you have.

Other Articles in this Series

Bookmark the permalink.

6 Comments

  1. Sorry to repeat the comment, but I don´t know if the facebook ones give you a notification, and i’m sure this one does 🙂 Feel free to erase either one!

    The high score system is not implemented… any plans on including it?
    otherwise, excellent tutorial!

    cheers!

  2. Whoops, yeah I didn’t realize the facebook comments didn’t notify-

    Yeah, I’ll write another deviation with storing high scores- In the ‘Part 9: Kongregate API’ part- I added high scores using their API (which only works on Kongregate), but I know you can also store them using mochimedia, or flash’s version of cookies (or on your own server using php + mysql).

    Which version would you most want to see?

    Thanks!

  3. I you´re asking me (I´m honored :D) I’d prefer the php+mysql version, as that would allow for a facebook type game 😀
    Cheers again on a great tutorial!

    PS: is there a way to subscribe to comments?? i didn´t know you answered this until I came back here 🙂

  4. when I ran the program for a test, there were 64 errors in the text, what should I do

    • Did you run the downloaded program code, or copy and pasting in the text from the code blocks?

      If copied code, download the code and see if it compiles, then see if you can see any differences.

      Hope that helps!

    • Great tutorial so far!

      I’d like to point out that there are a few lines of code that need to be added to the Ship.as, GameSprite.as, and Asteroid.as classes that aren’t explained in this section of the tutorial and could be the cause of some of your errors. The solution can be found in the source code.

Leave a Reply

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