Tower Defense Game Part 2: The Towers Difficulty: Intermediate-ExpertPart 1Whats being added:- A Menu
- Building Towers
- Enemy's Health
- Tower Projectile
What it looks like when done:Attachment:
Section 1: New ImagesThere are 4 new images that we need to create; A tower, A projectile, A no build area, and A Collision image.
First, draw out an image of a tower that will be used for an arrow tower. Save as arrowTower.png[32px X 32px]

Second, draw an arrow to use as the projectile for the arrow tower. Save as arrow.png[32px X 16px]
Make sure the arrow is facing right

Third, draw a path in a solid color to represent the no build area. Save as path.png[640px X 480px]
The image below is show with the actual background image the image saved should just be the red portion without the background.

The final path.png[640px X 480px]

Fourth, create a new image 20px by 20px and fill it with black. Save as coll.png[20px X 20px]
Section 2: Setting Up The StuffImport the four images we created into flash by clicking File -> Import -> Import to stage.
Select arrowTower.png, arrow.png, path.png, and coll.png. Then click import.
Creating the arrow tower, drag arrowTower.png from the library to the stage.
Right click the image on the stage and select convert to symbol. Use the following settings:

Delete the movie clip on the stage.
To create the arrow projectile, drag arrow.png from the library to the stage.
Right click the image on the stage and select convert to symbol. Use the following settings:

Delete the movie clip on the stage.
The next thing we need to create is the menu that will hold all the buttons. Draw a rectangle on the stage 640px by 64px.
Highlight the whole rectangle and select convert to symbol, and use the following settings:

Delete the menu from the stage.
Right click the menu in the library and select edit.
Drag a arrowTower movie clip onto the menu from the library, and give it a linkage name of "tower1".

Go back to the main stage by clicking Scene 1 above the timeline.
The last thing we need to create is a circle to represent the range of a tower.
Draw a circle on the stage and make it 100px by 100px. I made it transparent.

Delete the movie clip on the stage.
To access these in actionscript we need to give them linkage names.
For each you will need to right click on the name in the library and select Linkage.
Movie Clip: arrow

Movie Clip: arrowTower

Movie Clip: menu

Movie Clip: rangeCircle

Bitmap: path.png

Bitmap: coll.png
Section 3: The CodeAdd the official geom classes:
Find:
Code:
import flash.display.*;
Add on a new line after:
Code:
import flash.geom.*;
Load the path.png and coll.png images into variables:
Find:
Code:
var background = BitmapData.loadBitmap("background");
Add on a new line after:
Code:
var path = BitmapData.loadBitmap("path"); var towerColl = BitmapData.loadBitmap("coll");
Add the menu to the stage:
Find:
Code:
this.bg.attachBitmap(background, this.bg.getNextHighestDepth());
Add on a new line after:
Code:
this.attachMovie("menu","menu",this.getNextHighestDepth()); menu._x=0; menu._y=416;
Create some new variables:
Add on a new line after the previous code:
Code:
placeTower=false; numTowers=0; towers=new Array(); enemys=new Array(); towerStats=[[150,30,20,12]];
Make the menu button do something:
Find
Code:
spawn = setInterval(newCreep,1500);
Add on a new line after:
Code:
menu.tower1.onPress=function()
{
if(!_root.placeTower) {
_root.placeTower=true; _root.selectedTower="arrowTower"; _root.towerNum=0; _root.attachMovie("rangeCircle","rangeCircle",_root.getNextHighestDepth()); _root.rangeCircle._xscale=_root.rangeCircle._yscale=_root.towerStats[_root.towerNum][0]*2; _root.attachMovie(selectedTower,"towerHold",_root.getNextHighestDepth()); towerHold._x=(Math.floor(_xmouse/32)*32)+16; towerHold._y=(Math.floor(_ymouse/32)*32)+16; rangeCircle._x=towerHold._x; rangeCircle._y=towerHold._y;
}
}
Now we need to update the positions when the mouse is moved:
Add on a new line after the previous code:
Code:
onMouseMove=function()
{
if(placeTower) {
towerHold._x=(Math.floor(_xmouse/32)*32)+16; towerHold._y=(Math.floor(_ymouse/32)*32)+16; rangeCircle._x=towerHold._x; rangeCircle._y=towerHold._y;
if (towerColl.hitTest(new Point(towerHold._x, towerHold._y), 255, path, new Point(0, 0), 255))
{
towerHold._alpha=40; }else{
towerHold._alpha=100; }
}
}
Then we need to actually add the tower when the users presses the button:
Add on a new line after the previous code:
Code:
onMouseDown=function()
{
if(placeTower && _ymouse<416 && !towerColl.hitTest(new Point(towerHold._x, towerHold._y), 255, path, new Point(0, 0), 255))
{
numTowers++; name=selectedTower+numTowers; this.attachMovie(selectedTower,name,this.getNextHighestDepth()); this[name]._x=towerHold._x; this[name]._y=towerHold._y;
this[name].num=numTowers; this[name].range=towerStats[towerNum][0]; this[name].reload=towerStats[towerNum][1]; this[name].damage=towerStats[towerNum][2]; this[name].speed=towerStats[towerNum][3]; this[name].reloadHold=this[name].reload; Set the reloadHold variable to the reload value.
this[name].canFire=false; towers.push(this[name]); placeTower=false; towerHold.removeMovieClip(); rangeCircle.removeMovieClip(); var mat:Matrix = new Matrix(); mat.tx = this[name]._x; mat.ty = this[name]._y; path.draw(this[name], mat); }
}
The main loop of the game:
Add on a new line after the previous code:
Code:
this.onEnterFrame=function() {
for(i=0;i<towers.length;i++) {
tower=towers[i]; towerCheck(tower); if(tower.ableFire) {
towerFire(tower); }
}
}
Lets make the towerCheck function:
Add on a new line after the previous code:
Code:
function towerCheck(tower) {
if(tower.reloadHold<=0) {
for(j=0;j<enemys.length;j++) {
if(distance(tower,enemys[j])<tower.range)
{
tower.target=enemys[j]; tower.ableFire=true; break; }
}
}else{ tower.reloadHold--; }
}
Three functions and a little more code to go, lets make the towers fire:
Add on a new line after the previous code:
Code:
function towerFire(tower)
{
tower.reloadHold=tower.reload; tower.ableFire=false; name="a"+tower.num; this.attachMovie("arrow",name,this.getNextHighestDepth()); this[name]._x=tower._x; this[name]._y=tower._y; this[name].target=tower.target; this[name].speed=tower.speed; this[name].damage=tower.damage; this[name].onEnterFrame=function() {
dx=this.target._x-this._x; dy=this.target._y-this._y; angle=Math.atan2(dy,dx); this._rotation=(angle*180)/Math.PI; this._x+=Math.cos(angle)*this.speed; this._y+=Math.sin(angle)*this.speed; if(this.target._x==undefined) {
this.removeMovieClip(); }
if(this.target.hitTest(this._x,this._y,true)) {
this.target.health-=this.damage; if(this.target.health<=0) {
removeEnemy(this.target); this.target.removeMovieClip(); }
this.removeMovieClip(); }
}
}
Two functions to go, the removeEnemy function:
Add on a new line after the previous code:
Code:
function removeEnemy(enemy) {
for(var i=0; i<enemys.length; i++) { if(enemys[i]==enemy) { enemys.splice(i,1); }
}
}
Last function, the distance:
Add on a new line after the previous code:
Code:
function distance(ob1,ob2) {
dx=ob2._x-ob1._x; dy=ob2._y-ob1._y; dist=Math.sqrt(dx*dx+dy*dy); return dist; }
Set the enemys health to 100 when they are created and add the enemy to the enemys array:
Find:
Code:
_root[name].tr=1;
Add on a new line after:
Code:
_root[name].health=100; enemys.push(_root[name]);
The last line of code to add!
Find:
Code:
_root.lifeBox.life.text=lives;
Add on a new line after:
Code:
removeEnemy(this);
If everything goes well the game should now be working!
If it is not, recheck your code and linkage names.
Still not? Download the attached zip to look at the source.
If it is still not working post on this forum and you will receive help.
Advertisement: