Creating an Asteroids Flash Game Using the Display List Part 3: Creating Asteroids

Creating an Asteroids Flash game part3 - Creating The Asteroids

In the last section, we created bullets, and a method of wrapping the ship and bullets to the other side of the screen when they reach an edge of the screen.

In this section, we’ll create an asteroids class that allows us to make a variety of asteroids quickly and easily. We’ll also move them around, and wrap them on the screen.

Creating the Asteroid class

Create a new class called “Asteroid.as” in your ‘src->Entities’ folder, that extends/uses the base class’MovieClip’ class.

Asteroid.as

package Entities 
{
	import flash.display.MovieClip;
	import flash.geom.Point;
	
	/**
	 * ...
	 * @author Chris Moeller
	 */
	
	public class Asteroid extends MovieClip 
	{
		public static const Directions:Array = [Math.PI / 4, 3 * Math.PI / 4, 5 * Math.PI / 4, 7 * Math.PI / 4];
		public static const Sizes:Array = [40, 20, 10];
		public static const Speeds:Array = [1, 3, 5];
		
		public var size:int;
		public  var type:int;
		private var direction:Number;
		private var speed:Point;
		
		public function Asteroid(x:int, y:int, size:Number, direction:Number, type:int)
		{
			this.x = x;
			this.y = y;
			
			this.size = size;
			this.type = type;
			this.direction = direction = Directions[direction];
			this.speed = new Point( -Speeds[size] * Math.cos(direction), -Speeds[size] * Math.sin(direction));
			
			graphics.lineStyle(1, 0xFFFFFF);
			this.type = type;
			
			var ast_width:Number = Sizes[size];
			var ast_height:Number = Sizes[size];
			
			if (type == 0)
			{
				//first lets draw the asteroid
				//they are basically circles with some craggly looking edges
				graphics.moveTo(0, 1 / 3 * ast_height); 
				graphics.lineTo(1 / 3 * ast_width, 0);//top line
				graphics.lineTo(2 / 3 * ast_width, 0);//top line
				graphics.lineTo(ast_width, 1 / 3 * ast_height); //right slanted line
				graphics.lineTo(ast_width, 2 / 3 * ast_height); //right  line
				graphics.lineTo(2 / 3 * ast_width,  ast_height); //bottom right slanted line
				graphics.lineTo(ast_width / 2,  ast_height); //bottom line
				graphics.lineTo(ast_width / 2,  2 / 3 * ast_height); //vertical bottom line
				graphics.lineTo(1 / 3 * ast_width, ast_height); //slanted bottom left line
				graphics.lineTo(0, 2 / 3 * ast_height); //slanted bottom left line 2
				graphics.lineTo(1 / 3 * ast_width,  ast_height / 2); //slanted center left line 1
				graphics.lineTo(0, 1 / 3 * ast_height);//back to start
			}
			else
			{
				graphics.moveTo(0, 1 / 3 * ast_height);
				graphics.lineTo(1 / 3 * ast_width, 0);//to top left line
				graphics.lineTo(ast_width / 2, 1 / 3 * ast_height);//to center top
				graphics.lineTo(2 / 3 * ast_width, 0);//to top right line
				graphics.lineTo(ast_width, 1 / 3 * ast_height);//to right top line
				graphics.lineTo(4 / 5 * ast_width, ast_height / 2);//inward right center line
				graphics.lineTo( ast_width, 2 / 3 * ast_height);//to right bottom line
				graphics.lineTo( 2 / 3 * ast_width,  ast_height);//to bottom right line
				graphics.lineTo( 1 / 3 * ast_width,  ast_height);//to bottom left line
				graphics.lineTo( 0,  2 / 3 * ast_height);//to left bottom line
				graphics.lineTo(0, 1 / 3 * ast_height);//back tot he start
			}
			//super();
		}
		public function Update():void 
		{
			x += speed.x;
			y += speed.y;	
			
			if (x + width <= 0)
				x = Game.stageWidth - width;
			else if(x >= Game.stageWidth)
				x = 0;
				
			if (y + height <= 0)
				y = Game.stageHeight - height;
			else if(y >= Game.stageHeight)
				y = 0;				
		}
		
	}
}

Line 13: These are the different directions/ angles that are asteroids will travel in radians. I had picked 4 different dirrection – 45 degrees in every quadrant- so all four diaganols.

Line 14: These are the different possible sizes in pixel width/ height for all of our asteroids.

Line 15: These are the different speeds for our asteroids. It is setup so the smaller asteroid sizes correspond to the faster speeds.

Line 22: Is the constructor – in it we pass all the variables to allow us to create a variety of asteroids.

Line 38: If we pass in type 0, we will draw this pattern on the asteroids image sprite.

Line 55: If we pass in type 1, this alternative asteroid pattern onto the sprite.

Line 71: Update function used to check if an asteroid is off screen, and wrap it around to the other side.

Next, we need to update the Game class to spawn the asteroids.

Game.as

package
{
	import Entities.Asteroid;
	import Entities.Bullet;
	import Entities.Ship;
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.MovieClip;
	import flash.display.Stage;
	import flash.events.Event;
	import flash.events.KeyboardEvent;
	
	import flash.utils.getTimer;

	public class Game
	{
		public var stage:Stage;
		public var ship:Ship;
		
		private const LEFT:int = 37;
		private const UP:int = 38;
		private const RIGHT:int = 39;
		private const SPACE:int = 32;	
		private const DOWN:int = 40;
		
		public static var stageWidth:int;
		public static var stageHeight:int;
		
		public static var current_time:Number; //used to track the time of the current frame
		private var bullets:Array; //used to hold all the bullets
		private var firing_delay:Number; //the delay before creating a new bullet when the space bar is held down
		private var last_fired:Number; //the time the last bullet was created
		private var bullets_max_life:Number; //the max life of the bullets
		private var space_down:Boolean; //Either set to true if the spacebar is being held down, or false if released
		
		private var asteroids:Array;
		
		public function Game(stage:Stage)
		{
			this.stage = stage;
			stageHeight = stage.stageHeight;
			stageWidth = stage.stageWidth;
			trace("Game created");
			
			//create the ship
			ship = new Ship(stage.stageWidth / 2 - 5, stage.stageHeight / 2 - 10);
			stage.addChild(ship);
			
			//now for input
			stage.addEventListener(KeyboardEvent.KEY_DOWN, KeyDown);
			stage.addEventListener(KeyboardEvent.KEY_UP, KeyUp);	
			
			bullets = new Array();
			firing_delay = 200;
			last_fired = 0;
			bullets_max_life = 1000;
			space_down = false;
			
			asteroids = new Array();
			//setup four first asteroids
			asteroids.push(new Asteroid(stageWidth / 5, 2 * stageHeight / 3, 0, 0, 0));
			asteroids.push(new Asteroid(stageWidth / 5, stageHeight / 4, 0, 1, 0));
			
			asteroids.push(new Asteroid(2*stageWidth / 3, 1 * stageHeight / 3, 0, 2, 0));
			asteroids.push(new Asteroid(2*stageWidth / 3, 5 * stageHeight / 5, 0, 3, 0));
			
			for (var i:int = 0; i < asteroids.length; i++ )
				stage.addChild(asteroids[i]);
			
		}
		public function Update(e:Event):void
		{
			current_time = getTimer();
			
			ship.Update();
			
			if (space_down && current_time-last_fired > firing_delay)
			{
				var angle_rad:Number = ship.rotation * Math.PI / 180;
				bullets.push(new Bullet(ship.x, ship.y, current_time, angle_rad));
				last_fired = current_time;
				stage.addChild(bullets[bullets.length - 1]);
			}
			
			var bullets_length:int = bullets.length - 1;
			for (var i:int = bullets_length; i > -1;i-- )
			{
				bullets[i].Update();
				if (current_time-bullets[i].life > bullets_max_life)
				{
					stage.removeChild(bullets[i]);
					bullets.splice(i, 1);
				}
			}
			for (var k:int = 0; k < asteroids.length;k++ )
				asteroids[k].Update();
		}
		public function KeyDown(e:KeyboardEvent):void
		{
			if(e.keyCode==RIGHT)
				ship.rotation_amount = 15;				
			if(e.keyCode==LEFT)
				ship.rotation_amount = -15;
			if(e.keyCode==UP)
				ship.thrust = 1;
			if(e.keyCode==DOWN)
				ship.thrust = -1;
			if(e.keyCode==SPACE)
				space_down = true;	
		}
		public function KeyUp(e:KeyboardEvent):void
		{
			if(e.keyCode==RIGHT||e.keyCode==LEFT)
				ship.rotation_amount = 0;				
				
			if(e.keyCode==UP||e.keyCode==DOWN)
				ship.thrust = 0;	
			if(e.keyCode==SPACE)
				space_down = false;
		}
	}
}

Line 36: We create an array to hold our asteroid objects.

Line 59-68: We initialize the asteroids array, add 4 asteroid objects to it, then add them to the stage so that they are visible

Line 95-96: We loop through the array, calling the "Update" function for the asteroid, which lets them wrap around the screen when they come to an edge.

So overall, you'll see that creating an asteroid is very simmilar to creating a bullet, we just change the way we update and create them.

Tutorial Demo

In the next section we’ll create a way to detect collisions, and create explosions!

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

Other Articles in this Series

Bookmark the permalink.

Leave a Reply

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