Flash AS2 OOP game development
[ January 18, 2004 ] by Steve Happ
This long article documents the development process (from requirements definition to release) of a Flash game written in ActionScript2 using entirely OOP (Object Oriented Programming). The game is a standard space shoot'em-up with 3 enemy ships and the player firing lasers.


(continues from page 2)

In this third part of our development process we will need to check our lives left and deal with it accordingly.


CHECK LIVES

In your .fla, make two new frames and put the code that was on frame 1 onto frame 2. Add a stop() action at the top of the code. Add stop() on frames 1 and 3. On frame 1, add a title, some instructions and a button. On the button, add this code:

on(release){
	_root.gotoAndStop(2);
}

On frame 3 add a dynamic textbox to display the results of the game and call the instance "result_txt" .
Add a restart button and put this code on it to take it back to frame 2:

on(release){
	_root.gotoAndStop(2);
}

Go to our Game class code and add this method that will check how many lives left and deal with the consequences:

// in Game class
//	============	CHECK LIVES	===============	//
	function checkLives() {
		if (lives <= 0) {
			// clean up the stage
			// remove all the mc's
			ship.removeMovieClip();
			for(var i = 0; i < enemyArray.length; i++){
				enemyArray[i].removeMovieClip();
			}
			// make the text box autosize
			_root.result_txt.autoSize = "left";
			// display score
			_root.result_txt.text = 
			"You have scored "+score+" . Congratulations.";
			// go to results page..
			_root.gotoAndStop(3);
		}
	}


SCROLLING BACKGROUND

We have two choices here. We can just make a scrolling background inside our Flash API or make a Background class and put the machinery for scrolling inside that... Well I decided to make a Background class and put all the code inside that.
Firstly make 4 mc's twice the width of your Stage and the same height as the stage. Mine turned out at 1400x400. I am going to use parallax with my background. The closest grounds will be moving faster than the grounds that are further back. I named my instances of these mc's sky, far, mid, and fore.
And here is the Background class:

class Background {
	// -----	INITIALISE BACK	--- //
	function initBack() {
		_root.attachMovie("sky", "sky", 1);
		_root.attachMovie("far", "far", 2);
		_root.attachMovie("mid", "mid", 3);
		_root.attachMovie("fore", "fore", 4);
	}
	//	==========	MOVE BACK	====	//
	function moveBack(){
		// sky move
		if(_root.sky._x <= -Stage.width){
			_root.sky._x = 0;
		}
		_root.sky._x -= 2;
		// far ground move
		if(_root.far._x <= -Stage.width){
			_root.far._x = 0;
		}
		_root.far._x -= 4;
		// mid ground move
		if(_root.mid._x <= -Stage.width){
			_root.mid._x = 0;
		}
		_root.mid._x -= 6;
		// fore ground move
		if(_root.fore._x <= -Stage.width){
			_root.fore._x = 0;
		}
		_root.fore._x -= 8;
	}	
	//
	//	===CLEAN UP BACK	===		//
	function cleanBack(){
		_root.sky.removeMovieClip();
		_root.far.removeMovieClip();
		_root.mid.removeMovieClip();
		_root.fore.removeMovieClip();
	}
}

Notice that I have 3 methods:

  • initBack() - in which I attach the background clips to the timeline
  • moveBack() - which moves the clips at different speeds
  • cleanBack() - removes all the clips when all lives are gone

In the Game class add the variable back, and change the constructor to pass a Background instance:

// in Game class
// declare variables
var back:Background;
//... constructor
function Game(_ship:Spaceship, _enArray:Array, 
		_bullArray:Array,_back:Background) {
		ship = _ship;
		enemyArray = _enArray;
		laserArray = _bullArray;
		back = _back;
		score = 0;
		lives = 10;
	}

Now we need to initialise our background. In the game class, inside the "initGame" method, initialise the background:

// in Game class
//	---	Initialise -----------	//
	function initGame(){
		back.initBack();
		
	}

Then move it; but first here is a a very basic interaction diagram (see picture 5).

Pic. 5: Interaction diagram

// in Game class
// == MOVE BACK	=====	//
	function moveBackground(){
		back.moveBack();
	}

// in our fla
//  game loop
_root.onEnterFrame = function(){
	myGame.checkKey();
	myGame.moveShip(dir);
	myGame.moveLaser();
	myGame.moveBaddies();
	myGame.collision();
	myGame.checkLives();
	myGame.moveBackground();
}


FIXING SCORE AND LIVES DISPLAY

All that is well and good but now we can't see our display for the score and lives. That is because our textboxes are at root level and the backgrounds are at depths 1-4, and cover them. So what we need to do is add the test dynamically, and put them at a higher depth.
Add this line in Game class where we have declared our variables:

var myformat:TextFormat;

This will allow us to format our text later. And in the "initGame" method add the dynamic text fields:

// in Game class
//	---	Initialise -----------	//
	function initGame(){
		back.initBack();
		// create a textfield and set format
		_root.createTextField("score_txt",501,20,10,100,50);
		myformat = new TextFormat();
		myformat.color = 0xff0000;
		myformat.size =20;
		_root.score_txt.text = "Score : " + score;
		_root.score_txt.setTextFormat(myformat);
		// init lives text field
		_root.createTextField("lives_txt", 502, 600,10, 100, 30);
		_root.lives_txt.text = "Lives : " + lives;
		_root.lives_txt.setTextFormat(myformat);
	}

Delete the text fields that we put on the stage and check our collison detection for the bullets hitting the baddies, and baddies hitting spaceship:

// in Game class
// function collision() ...
// bullets hit baddies
	score += 10;
	_root.score_txt.text = " Score: " + score;
	_root.score_txt.setTextFormat(myformat);
// ...
// baddies hit spaceship
	lives -= 1;
	_root.lives_txt.text = " Lives : "+lives;
	_root.lives_txt.setTextFormat(myformat);
// ...


CLEAN UP

We still need to remove the background from the stage when the game ends. So I made a new method to do this:

//  in Background class
//	===CLEAN UP BACK	===		//
	function cleanBack(){
		_root.sky.removeMovieClip();
		_root.far.removeMovieClip();
		_root.mid.removeMovieClip();
		_root.fore.removeMovieClip();
	}

Now in the Game class i add this line to the "checkLives()" method:

// in Game class
// in CheckLives method
if(lives<=0){
	// ...
	back.cleanBack();
	// ...
}


TO DO YET

This game is far from finished. For me it was an exercise in programming and I have ignored a lot of gameplay issues, visual design aesthetics, and a few other things.
Here is what can be added:

  • Sound - laser firing, collisions
  • More Levels, bigger, badder baddies
  • Treasures to find and add to your score
  • A High Score sheet
  • Add the buttons code to the Game class
  • Can't think of anything else... your imagination

Download the files as they are up to here. I have only added the code for the actionscript panel on frame 2 (actionscriptPanel.txt). The whole .fla was just too big.


        
 
 
Name: Steve Happ
Location: Newcastle, Australia
Age: 51
Flash experience: 2-3 years
Job: Computer trainer
Website: http://www.video-animation.com/
 
 
| Homepage | News | Games | Articles | Multiplayer Central | Reviews | Spotlight | Forums | Info | Links | Contact us | Advertise | Credits |

| www.smartfoxserver.com | www.gotoandplay.biz | www.openspace-engine.com |

gotoAndPlay() v 3.0.0 -- (c)2003-2008 gotoAndPlay() Team -- P.IVA 03121770048