Welcome to the 2nd part of this tutorial. I recommend you to check part 1.

In this tutorial, we will place our first base, and it will start to fire.

Let’s have a look at the objects:

**base**: it’s the base

**bullet**: it’s the bullet the base will shoot

**cant_build**: it’s the area where you can’t build a base

**minion**: already explained in part 1.

**path**: already explained in part 1.

**range**: it’s the firing range of the base

Now, a little actionscript all in the first frame:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
base_range = 300; can_be_placed = false; placed = false; attachMovie("path", "path", _root.getNextHighestDepth()); attachMovie("cant_build", "cant_build", _root.getNextHighestDepth()); attachMovie("range", "range", _root.getNextHighestDepth(), {_width:base_range, _height:base_range}); attachMovie("base", "base", _root.getNextHighestDepth()); waypoint_x = new Array(40, 140, 140, 220, 220, 80, 80, 340, 340, 420, 420); waypoint_y = new Array(140, 140, 60, 60, 240, 240, 320, 320, 100, 100, -20); delay = 25; new_monster = 0; monsters_placed = 0; onEnterFrame = function () { if (monsters_placed<25) { new_monster++; } if (new_monster == delay) { monsters_placed++; new_monster = 0; min = attachMovie("minion", "minion"+_root.getNextHighestDepth(), _root.getNextHighestDepth(), {_x:40, _y:-20}); min.point_to_reach = 0; min.speed = 1; min.onEnterFrame = function() { dist_x = waypoint_x[this.point_to_reach]-this._x; dist_y = waypoint_y[this.point_to_reach]-this._y; if ((Math.abs(dist_x)+Math.abs(dist_y))<1) { this.point_to_reach++; } angle = Math.atan2(dist_y, dist_x); this._x = this._x+this.speed*Math.cos(angle); this._y = this._y+this.speed*Math.sin(angle); this._rotation = angle/Math.PI*180-90; }; } }; base.onEnterFrame = function() { if (!placed) { this._x = _root._xmouse; this._y = _root._ymouse; _root.range._alpha = 100; can_be_placed = true; if (_root.cant_build.hitTest(this._x-this._width/2, this._y-this._height/2, true) or _root.cant_build.hitTest(this._x+this._width/2, this._y+this._height/2, true) or _root.cant_build.hitTest(this._x+this._width/2, this._y-this._height/2, true) or _root.cant_build.hitTest(this._x-this._width/2, this._y+this._height/2, true)) { _root.range._alpha = 0; can_be_placed = false; } } }; range.onEnterFrame = function() { if (!placed) { this._x = _root._xmouse; this._y = _root._ymouse; } }; onMouseDown = function () { if (can_be_placed) { placed = true; } }; |

**Line 1**: Defining the base range

**Line 2**: Defining if the base can be placed

**Line 3**: Defining if the base has been placed

**Line 5**: Attaching the `cant_build`

movieclip

**Line 6**: Attaching the `range`

movieclip and setting its width and height to match `base_range`

**Line 7**: Attaching the base movieclip

**Line 36**: Function to be executed for the base at every frame

**Line 37**: If the base is not already placed…

**Lines 38-39**: Move the base to the mouse pointer

**Line 40**: Set the transparency of the range to 100 (fully opaque)

**Line 41**: Updating `can_be_placed`

to `true`

**Line 42**: If a corner of the base is over the cant_build area…

**Line 43**: Setting the transparency of the range to 0 (fully transparent)

Line 44: Setting `can_be_placed`

to false

**What I’ve done**: I let the player move the base with the mouse. If the base can’t be placed, because it’s over the walking path, I hide the range to make the player know he is on an area where he can’t build.

**Line 48**: Function to be executed for the range at every frame

**Lines 49-52**: Same thing of **lines 37-39**… if the base has not been placed, then move the range with the mouse

**Line 54**: Function to be executed when the player clicks the mouse

**Line 55**: If the base can be placed…

**Line 56**: Then set `placed`

to `true`

. Now the base is placed

Look: you can now place your base, but only outside the walking path.

Now, we will make the base fire at the foes

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
base_range = 300; can_be_placed = false; placed = false; firing = false; attachMovie("path", "path", _root.getNextHighestDepth()); attachMovie("cant_build", "cant_build", _root.getNextHighestDepth()); attachMovie("range", "range", _root.getNextHighestDepth(), {_width:base_range, _height:base_range}); attachMovie("base", "base", _root.getNextHighestDepth()); waypoint_x = new Array(40, 140, 140, 220, 220, 80, 80, 340, 340, 420, 420); waypoint_y = new Array(140, 140, 60, 60, 240, 240, 320, 320, 100, 100, -20); delay = 25; new_monster = 0; monsters_placed = 0; onEnterFrame = function () { if (monsters_placed<25) { new_monster++; } if (new_monster == delay) { monsters_placed++; new_monster = 0; min = attachMovie("minion", "minion"+_root.getNextHighestDepth(), _root.getNextHighestDepth(), {_x:40, _y:-20}); min.point_to_reach = 0; min.speed = 1; min.onEnterFrame = function() { dist_x = waypoint_x[this.point_to_reach]-this._x; dist_y = waypoint_y[this.point_to_reach]-this._y; if ((Math.abs(dist_x)+Math.abs(dist_y))<1) { this.point_to_reach++; } angle = Math.atan2(dist_y, dist_x); this._x = this._x+this.speed*Math.cos(angle); this._y = this._y+this.speed*Math.sin(angle); this._rotation = angle/Math.PI*180-90; if (bullet.hitTest(this._x, this._y, true)) { firing = false; bullet.removeMovieClip(); this.removeMovieClip(); } if (placed) { distance_from_turret_x = base._x-this._x; distance_from_turret_y = base._y-this._y; if ((Math.sqrt(distance_from_turret_x*distance_from_turret_x+distance_from_turret_y*distance_from_turret_y)<base_range/2) and (!firing)) { firing = true; bullet = attachMovie("bullet", "bullet"+_root.getNextHighestDepth(), _root.getNextHighestDepth(), {_x:base._x, _y:base._y}); bullet.dir = Math.atan2(distance_from_turret_y, distance_from_turret_x); bullet.onEnterFrame = function() { this._x -= 3*Math.cos(bullet.dir); this._y -= 3*Math.sin(bullet.dir); if ((this._x<0) or (this._y<0) or (this._y>400) or (this._x>500)) { firing = false; this.removeMovieClip(); } }; } } }; } }; base.onEnterFrame = function() { if (!placed) { this._x = _root._xmouse; this._y = _root._ymouse; _root.range._alpha = 100; can_be_placed = true; if (_root.cant_build.hitTest(this._x-this._width/2, this._y-this._height/2, true) or _root.cant_build.hitTest(this._x+this._width/2, this._y+this._height/2, true) or _root.cant_build.hitTest(this._x+this._width/2, this._y-this._height/2, true) or _root.cant_build.hitTest(this._x-this._width/2, this._y+this._height/2, true)) { _root.range._alpha = 0; can_be_placed = false; } } }; range.onEnterFrame = function() { if (!placed) { this._x = _root._xmouse; this._y = _root._ymouse; } }; onMouseDown = function () { if (can_be_placed) { placed = true; } }; |

**Line 4**: Setting the firing variable to false. Now the base is not firing

**Line 34**: Performing an hit test between the minion and the bullet. At this time in the script we haven’t already met the bullet, but anyway at this time I am performing this test

**Line 35-37**: If the test is positive, then remove the bullet and the minion that was hit (at this time minions do not have energy, so my turret is one shot one kill), then set firing to false.

**Lines 40-41**: Calculating x and y distance between the bullet and the minion

**Line 42**: If the distance between the bullet and the minion is less than half the range (in our case the range is the diameter of the circle, so half the range is the radius)

**Line 43**: Boom! The turret fires!

**Line 44**: Placing the bullet on stage, in the same position of the turret

**Line 45**: Setting bullet direction, accordind to its x and y distances from the minion

**Line 46**: Function to be executed for the bullet at every frame

**Lines 47-48**: Moving the bullet using trigonometry. If you don’t know what is trigonometry, then head to this tutorial

**Line 49**: Checking if the bullet is flying out of the stage

**Lines 50-51**: In this case, remove the bullet and set `firing`

to `false`

again to let the turret fire once more

And here it is our firing turret. You may need to reload the page to have the minion walking while you will place the turret and start killing them.

The fire rate sucks a lot, and the same thing does turret’s AI. But I got all those features in only 81 lines, I am sure I will create the complete game in less than 500 lines.

Not today, anyway. Today, download the source and if you have suggestion… just leave a comment.

Pingback: Make a Flash game like Flash Element Tower Defense - Part 1 : Emanuele Feronato - italian geek and PROgrammer()

Pingback: Hoi! Koffie? » Tower “Addiction” Defense()

Pingback: L’ultima linea di difesa /4 - Faccio Cose Vedo Gente()

Pingback: digitalt skapande » Tower Defence()

Pingback: Adobe Flash CS3- AS3 and AS2 game tutorials roundup | Lemlinh.com()

Pingback: Flash Tower Defence Prototype v 0.9 | Its Not Another Gaming Site()

Pingback: marciorosa.org » Make a Flash game like Flash Element Tower Defense – Part 1 - Complete listing Tools and resorces for the ultimate web developer()

Pingback: marciorosa.org » Make a Flash game like Flash Element Tower Defense – Part 2 - Complete listing Tools and resorces for the ultimate web developer()