It is currently Sat Nov 22, 2008 1:55 am


Post a new topicPost a reply Page 1 of 13   [ 121 posts ]
Go to page 1, 2, 3, 4, 5 ... 13  Next
Author Message
 Post subject: Tower Defense Game Part 2: The Towers
PostPosted: Tue Aug 12, 2008 10:58 pm 
Commander in Chief
Commander in Chief
User avatar

Joined: Sat Apr 21, 2007 6:43 pm
Posts: 964
Location: Salem, Oregon
Tower Defense Game Part 2: The Towers

Difficulty: Intermediate-Expert
Part 1

Whats being added:
  • A Menu
  • Building Towers
  • Enemy's Health
  • Tower Projectile

What it looks like when done:
Attachment:

TD Part 2.swf [ 88.58 KiB | Viewed 2465 times ]


Section 1: New Images
There 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]
Image

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


Image

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.
Image
The final path.png[640px X 480px]
Image

Fourth, create a new image 20px by 20px and fill it with black. Save as coll.png[20px X 20px]
Image

Section 2: Setting Up The Stuff
Import 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:
Image
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:
Image
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:
Image
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".
Image
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.
Image
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
Image

Movie Clip: arrowTower
Image

Movie Clip: menu
Image

Movie Clip: rangeCircle
Image

Bitmap: path.png
Image

Bitmap: coll.png
Image

Section 3: The Code
Add the official geom classes:
Find:
Code:

import flash
.display.*;
 

Add on a new line after:
Code:

import flash
.geom.*; //Imports all of the classes that are part of 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"); //Load the bitmap information from path.png into the path variable.
var towerColl = BitmapData.loadBitmap("coll"); //Load the bitmap information from coll.png into the towerColl variable.
 


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()); //Add the menu movie clip from the library with a name 
//of menu and a depth of the next highest available.
menu._x=0; //Set the value of the menus x coordinate to 0.
menu._y=416; //Set the value of the menus y coordinate to 416.
 


Create some new variables:
Add on a new line after the previous code:
Code:

placeTower
=false; //Variable used to tell if the user is playing a tower.
numTowers=0; //The number of towers created.
towers=new Array(); //Array to hold the list of the towers created.
enemys=new Array(); //Array to hold the list of the enemys created.
//Range | Reload | Damage | Speed
towerStats=[[150,30,20,12]]; //A 2 dimensional array to hold the stats of the towers.
 


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) //If a tower is not all ready being placed
    {
        _root.placeTower=true; //We are now placing a tower
        _root.selectedTower="arrowTower"; //The tower being placed is an arrowTower, same as the linkage name.
        _root.towerNum=0; //The number of the tower to use when getting the tower stats.
               //It will be using the first row from the tower stats array.
        _root.attachMovie("rangeCircle","rangeCircle",_root.getNextHighestDepth()); //Add a range circle from the library 
//to the stage with the next highest depth.
        _root.rangeCircle._xscale=_root.rangeCircle._yscale=_root.towerStats[_root.towerNum][0]*2; //Set the size of the range circle to the range of the tower.
        _root.attachMovie(selectedTower,"towerHold",_root.getNextHighestDepth()); //Add the tower being placed to the 
//stage with a name of towerHold with the next highest depth.
        towerHold._x=(Math.floor(_xmouse/32)*32)+16; //Place the towerHold movie at the mouse snapping it at every 32 pixels starting with 16.
        towerHold._y=(Math.floor(_ymouse/32)*32)+16; //Same thing for y
        rangeCircle._x=towerHold._x; //move the range circle to the toewrHold.
        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) //If a tower is being place
    {
        towerHold._x=(Math.floor(_xmouse/32)*32)+16; //Move the towerHold x position to the mouse snapping 
//every 32 pixels starting at 16.
        towerHold._y=(Math.floor(_ymouse/32)*32)+16;// Same for y
        rangeCircle._x=towerHold._x;//Move the range circle to the towerHold.
        rangeCircle._y=towerHold._y;
        if (towerColl.hitTest(new Point(towerHold._x, towerHold._y), 255, path, new Point(0, 0), 255))
                //Huh? this does not look like a normal hitTest. It NOT its a bitmap hitTest. It checks if two bitmaps are colliding 
//with each other.
                //The first part: towerColl.hitTest means we are using the towerColl bitmap (coll.png) and we are checking at the 
//towerHold x and y with 255 alpha threshold. 
                //The second part: path, means we are checking with the path bitmap at the point 0,0 on the bitmap with 255
//alpha threshold.
        {
            towerHold._alpha=40;//If there is a collision set the alpha of towerHold to 40.
        }else{
            towerHold._alpha=100;//If there is not a collision it is ok to build and set the alpha of towerHold to 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))
//If we are placing a tower and there is not a collision.
    {
        numTowers++; //Increase the number of towers by 1.
        name=selectedTower+numTowers; //Create a new string variable called name with the selectedTower name and 
//the number of active towers.
        this.attachMovie(selectedTower,name,this.getNextHighestDepth()); //Attach the selected tower giving it an 
//instance name of the value of the name variable.
        this[name]._x=towerHold._x; //Set the new tower to the towerHold position.
        this[name]._y=towerHold._y;     
        this
[name].num=numTowers; //Give the tower a new variable called num with the value of numTowers. 
        this[name].range=towerStats[towerNum][0]; //Set a new variable called range to the value of the first index in the 
//array from the row of towerNum.
        this[name].reload=towerStats[towerNum][1];//Same for reload.
        this[name].damage=towerStats[towerNum][2]; //Same for damage.
        this[name].speed=towerStats[towerNum][3]; //Same for speed.
        this[name].reloadHold=this[name].reload; Set the reloadHold variable to the reload value.
        this[name].canFire=false; //Set the variable canFire to false.
        towers.push(this[name]); //Push the new tower into the towers array.
        placeTower=false; //set placeTower to false because we are no longer placing a tower.
        towerHold.removeMovieClip(); //Remove towerHold.
        rangeCircle.removeMovieClip();//Remove rangeCircle.
        var mat:Matrix = new Matrix(); //Create a new Matrix which is a rectangular array or a table of data.
        mat.tx = this[name]._x; //Set the tx value of the matrix to the new towers x position.
        mat.ty = this[name]._y; //Same for ty
        path.draw(this[name], mat); //Draw the tower onto the path bitmap so the player cannot place a tower on top 
//another.
    }
}
 


The main loop of the game:
Add on a new line after the previous code:
Code:

this
.onEnterFrame=function() //Every time a frame is displayed the event is called. 
{
    for(i=0;i<towers.length;i++) //A for loop to loop through the towers array.
    {
        tower=towers[i]; //Set the tower variable equal to towers[i].
        towerCheck(tower); //run the towerCheck function on the current tower being worked with to check if it can fire.
        if(tower.ableFire) //If the tower's ableFire variable is true
        {
            towerFire(tower); //Fire the arrow!! Run the towerFire function on the current tower.
        }
    }
}
 


Lets make the towerCheck function:
Add on a new line after the previous code:
Code:

function towerCheck
(tower) //Create a new function with the name of towerCheck with one variable
{    
    if
(tower.reloadHold<=0) //If the towers reloadHold is less than 0 the tower has reloaded.
    {
        for(j=0;j<enemys.length;j++) //A for loop to run through the enemys array.
        {
            if(distance(tower,enemys[j])<tower.range) 
//Call the distance function and if it returns a value less than the towers range the enemy is in firing distance.
            {
                tower.target=enemys[j]; //Set the towers target to the enemy in range.
                tower.ableFire=true; //Set ableFire to true because the tower can fire.
                break;//Break out of the for loop because we dont need to keep checking.
            }
        }
    }else{ //If the tower has not reloaded 
        tower.reloadHold--; //Subtract 1 from the tower's 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; //Set the reload hold to the towers reload value because it needs to reload again before 
//firing.
    tower.ableFire=false; //The tower is no longer able to fire so set ableFire to false.
    name="a"+tower.num; //A name value to give to the arrow being created.
    this.attachMovie("arrow",name,this.getNextHighestDepth()); //Attach an arrow with an instance name of the value of 
//the name variable and give it the next highest depth.
    this[name]._x=tower._x; //Set the arrows x position to the towers x.
    this[name]._y=tower._y;//Same for y.
    this[name].target=tower.target; //Set the target of the arrow to the towers target.
    this[name].speed=tower.speed; //Set the speed of the arrow to the towers speed.
    this[name].damage=tower.damage; //And the same for the damage.
    this[name].onEnterFrame=function() //Give the arrow an on enter frame function.
    {
        dx=this.target._x-this._x; //The difference between the arrow and the target's X
        dy=this.target._y-this._y; //The difference between the arrow and the target's Y
        angle=Math.atan2(dy,dx); //Get the angle in radians from the arrow to the target.
        this._rotation=(angle*180)/Math.PI; //Convert the radians to degrees and apply it to the arrows rotation.
        this._x+=Math.cos(angle)*this.speed; //Move the towers x by the cosine value of the angle multiplied by the 
//arrows speed.
        this._y+=Math.sin(angle)*this.speed; //Same for y with sine.
        if(this.target._x==undefined)//If the target's x value is undefined then the target does not exist and we should 
//remove the arrow.
        {
            this.removeMovieClip();//Remove the arrow.
        }
        if(this.target.hitTest(this._x,this._y,true)) //If there is collision (using normal hitTest) between the target 
//and the arrow.
        {
            this.target.health-=this.damage; //Subtract the arrows damage from the targets health.
            if(this.target.health<=0) //If the targets health is less than 0 the target is dead!
            {
                removeEnemy(this.target); //Remove the target from the enemys array by calling the removeEnemy 
//function.
                this.target.removeMovieClip(); //Remove the target from the stage.
            }
            this.removeMovieClip();//Remove the arrow.
        }
    }
}
 


Two functions to go, the removeEnemy function:
Add on a new line after the previous code:
Code:

function removeEnemy
(enemy) //A new function with a name of removeEnemy with one variable
{
    for(var i=0; i<enemys.length; i++) {//A for loop to loop through the enemys array.
        if(enemys[i]==enemy) { //Check the enemys array value at i to see if it is equal to the value of enemy.
            enemys.splice(i,1); //call the splice function of the enemys array at the value of i and remove 1 element.
        }
    }
}
 


Last function, the distance:
Add on a new line after the previous code:
Code:

function distance
(ob1,ob2) //A new function with the name of distance with two variables.
{
    dx=ob2._x-ob1._x; //Get the difference between ob2's x value and ob1's.
    dy=ob2._y-ob1._y; //Same for y
    dist=Math.sqrt(dx*dx+dy*dy); //Take the square root of the dx squared plus the dy squared to get the distance.
    return dist; //Return the value of 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;//Give the enemy a variable called health with a value of 100.
    enemys.push(_root[name]); //Push the enemy into the enemys array.
 


The last line of code to add!
Find:
Code:

                _root
.lifeBox.life.text=lives;
 

Add on a new line after:
Code:

                removeEnemy
(this); //Remove the enemy from the enemys array when it passes through the exit.
 


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:


Attachments:
Tower Defense Part 2.zip [103.02 KiB]
Downloaded 582 times

_________________
Image
Top
 Profile  
 
 Post subject: Re: Tower Defense Game Part 2: The Towers
PostPosted: Wed Aug 13, 2008 4:04 am 
First Lieutenant
First Lieutenant
User avatar

Joined: Thu Aug 23, 2007 2:45 pm
Posts: 1556
Location: South Park, PA
yey =D>
Nice tutorial.

_________________
Image

Hippo Attack Force


Top
 Profile  
 
 Post subject: Re: Tower Defense Game Part 2: The Towers
PostPosted: Wed Aug 13, 2008 5:25 am 
First Lieutenant
First Lieutenant
User avatar

Joined: Tue Aug 28, 2007 8:16 am
Posts: 1521
Location: Earth
Sweet! The wait is gone. :)

_________________
Image ImageImage


Top
 Profile  
 
 Post subject: Re: Tower Defense Game Part 2: The Towers
PostPosted: Wed Aug 13, 2008 5:41 am 
First Lieutenant
First Lieutenant
User avatar

Joined: Sat Jul 28, 2007 10:47 am
Posts: 1568
Location: Mars
Not quite, there should be Part 3 :D
Upgrading towers, lives, and the rest :D

_________________
Image


Top
 Profile  
 
 Post subject: Re: Tower Defense Game Part 2: The Towers
PostPosted: Wed Aug 13, 2008 2:11 pm 
First Lieutenant
First Lieutenant
User avatar

Joined: Tue Aug 28, 2007 8:16 am
Posts: 1521
Location: Earth
I haven't seen any other TD tutorials, ever.
Advertisement:

_________________
Image ImageImage


Top
 Profile  
 
 Post subject: Re: Tower Defense Game Part 2: The Towers
PostPosted: Wed Aug 13, 2008 8:24 pm 
Commander in Chief
Commander in Chief
User avatar

Joined: Sat Apr 21, 2007 6:43 pm
Posts: 964
Location: Salem, Oregon
Has anyone finish because i would like to know if everything worked ok.

_________________
Image


Top
 Profile  
 
 Post subject: Re: Tower Defense Game Part 2: The Towers
PostPosted: Wed Aug 13, 2008 11:39 pm 
Warrant Officer Three
Warrant Officer Three
User avatar

Joined: Tue Jan 01, 2008 6:04 pm
Posts: 682
Location: I forget, Austria, Maby I Don't rember
Finally, thanks so much jason.... :)


Top
 Profile  
 
 Post subject: Re: Tower Defense Game Part 2: The Towers
PostPosted: Thu Aug 14, 2008 7:29 pm 
Warrant Officer Three
Warrant Officer Three
User avatar

Joined: Tue Jan 01, 2008 6:04 pm
Posts: 682
Location: I forget, Austria, Maby I Don't rember
Sorry, for double.
But, Jason. How can I have more then one type of tower????


Top
 Profile  
 
 Post subject: Re: Tower Defense Game Part 2: The Towers
PostPosted: Thu Aug 14, 2008 10:36 pm 
Warrant Officer Three
Warrant Officer Three
User avatar

Joined: Tue Jan 01, 2008 6:04 pm
Posts: 682
Location: I forget, Austria, Maby I Don't rember
Sorry for triple.
But, when I try to add another tower with different stats. Everything goes haywire. HELP.


Top
 Profile  
 
 Post subject: Re: Tower Defense Game Part 2: The Towers
PostPosted: Thu Aug 14, 2008 11:49 pm 
First Lieutenant
First Lieutenant
User avatar

Joined: Sat Jul 28, 2007 10:47 am
Posts: 1568
Location: Mars
You can use the EDIT button, btw.

Post your fla or code.

_________________
Image


Top
 Profile  
 
Display posts from previous:  Sort by  
Post a new topicPost a reply Page 1 of 13   [ 121 posts ]
Go to page 1, 2, 3, 4, 5 ... 13  Next


Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
610nm Style by Daniel St. Jules of Gamexe.net