{"id":1439,"date":"2009-02-28T08:04:23","date_gmt":"2009-02-28T12:04:23","guid":{"rendered":"http:\/\/www.mrsunstudios.com\/?p=1439"},"modified":"2022-05-29T08:23:29","modified_gmt":"2022-05-29T12:23:29","slug":"tutorial-create-a-tower-defense-game-in-as3-part-4","status":"publish","type":"post","link":"http:\/\/www.mrsunstudios.com\/blog\/flash\/tutorial-create-a-tower-defense-game-in-as3-part-4\/","title":{"rendered":"Tutorial: Create a Tower Defense Game in AS3 &#8211; Part 4"},"content":{"rendered":"<div class=\"toc\">\n<h3>Table of Contents<\/h3>\n<ol>\n<li><a href=\"http:\/\/mrsunstudios.com\/2009\/02\/tutorial-create-a-tower-defense-game-in-as3\/\">Setting up Level<\/a><\/li>\n<li><a href=\"http:\/\/mrsunstudios.com\/2009\/02\/tutorial-create-a-tower-defense-game-in-as3-part-2\/\">Adding Turrets<\/a><\/li>\n<li><a href=\"http:\/\/mrsunstudios.com\/2009\/02\/tutorial-create-a-tower-defense-game-in-as3-part-3\/\">Adding Enemies<\/a><\/li>\n<li class=\"c_chap\"><a href=\"http:\/\/mrsunstudios.com\/2009\/02\/tutorial-create-a-tower-defense-game-in-as3-part-4\/\">Making Turrets Attack Enemies<\/a><\/li>\n<li><a href=\"http:\/\/mrsunstudios.com\/2009\/02\/tutorial-create-a-tower-defense-game-in-as3-part-5\/\">Winning\/Losing the Game<\/a><\/li>\n<li><a href=\"http:\/\/mrsunstudios.com\/2009\/02\/tutorial-create-a-tower-defense-game-in-as3-part-6\/\">Expanding on the Game<\/a><\/li>\n<li><a href=\"http:\/\/mrsunstudios.com\/2009\/02\/tutorial-create-a-tower-defense-game-in-as3-part-7\/\">Finishing Touches<\/a><\/li>\n<\/ol>\n<\/div>\n<h3>Step 4:  Making Turrets Attack Enemies<\/h3>\n<p>Well, it&#8217;s now time to let the enemies we just created be destroyed. Let&#8217;s dig in, shall we?<\/p>\n<p>First, we&#8217;ll define a single <tt>health<\/tt> variable for the Enemy. Just add this code to &#8220;Enemy.as&#8221; where we define all of the variables:<\/p>\n<pre lang=\"actionscript\">\r\npublic var health:int = 5;\r\n<\/pre>\n<p>Next, we&#8217;re going to have to create a new class. We&#8217;ve done this many times before, so hopefully I don&#8217;t need to remind you how to do it. Just create a new ActionScript file and save it as &#8220;Bullet.as&#8221;. Now, we&#8217;re just going to have to place a bit of code into it:<\/p>\n<pre lang=\"actionscript\">\r\npackage {\r\n\timport flash.display.MovieClip;\r\n\timport flash.events.*;\r\n\tpublic class Bullet extends MovieClip {\r\n\t\tprivate var _root:*;\r\n\t\t\/\/these two variables below must be set to public so that we can edit them outside the class\r\n\t\tpublic var target;\/\/the target that this guy is moving towards\r\n\t\tpublic var damage:int;\/\/how much damage this guy inflicts on the enemy\r\n\t\t\r\n\t\tprivate var xSpeed:Number;\/\/how fast it's moving horizontally\r\n\t\tprivate var ySpeed:Number;\/\/how fast it's moving vertically\r\n\t\tprivate var maxSpeed:Number = 5;\/\/how fast it can go\r\n\t\tpublic function Bullet() {\r\n\t\t\taddEventListener(Event.ADDED,beginClass);\/\/this will run every time this guy is made\r\n\t\t\taddEventListener(Event.ENTER_FRAME,eFrame);\/\/this will run every frame\r\n\t\t}\r\n\t\tprivate function beginClass(e:Event):void {\r\n\t\t\t_root = MovieClip(root);\/\/setting the root\r\n\t\t\t\r\n\t\t\t\/\/drawing this guy (it'll be a small white circle)\r\n\t\t\tthis.graphics.beginFill(0xFFFFFF);\r\n\t\t\tthis.graphics.drawCircle(0,0,2);\r\n\t\t\tthis.graphics.endFill();\r\n\t\t}\r\n\t\tprivate function eFrame(e:Event):void {\r\n\t\t\tvar yDist:Number=target.y+12.5 - this.y;\/\/how far this guy is from the enemy (x)\r\n\t\t\tvar xDist:Number=target.x+12.5 - this.x;\/\/how far it is from the enemy (y)\r\n\t\t\tvar angle:Number=Math.atan2(yDist,xDist);\/\/the angle that it must move\r\n\t\t\tySpeed=Math.sin(angle) * maxSpeed;\/\/calculate how much it should move the enemy vertically\r\n\t\t\txSpeed=Math.cos(angle) * maxSpeed;\/\/calculate how much it should move the enemy horizontally\r\n\t\t\t\/\/move the bullet towards the enemy\r\n\t\t\tthis.x+= xSpeed;\r\n\t\t\tthis.y+= ySpeed;\r\n\t\t\t\r\n\t\t\tif(this.hitTestObject(target)){\/\/if it touches the enemy\r\n\t\t\t\ttarget.health -= damage;\/\/make it lose some health\r\n\t\t\t\tdestroyThis();\/\/and destroy this guy\r\n\t\t\t}\r\n\t\t\tif(target == null || _root.gameOver == true){\/\/destroy it if game is over\r\n\t\t\t\tdestroyThis();\r\n\t\t\t}\r\n\t\t}\r\n\t\tpublic function destroyThis():void{\r\n\t\t\t\/\/this function will just remove this guy from the stage\r\n\t\t\tthis.removeEventListener(Event.ENTER_FRAME, eFrame);\r\n\t\t\tMovieClip(this.parent).removeChild(this);\r\n\t\t}\r\n\t}\r\n}\r\n<\/pre>\n<p>The next thing we need to do is define some variables for the Turret. Open up &#8220;Turret.as&#8221; and add in the following code where we define the variables:<\/p>\n<pre lang=\"actionscript\">\r\nprivate var angle:Number; \/\/the angle that the turret is currently rotated at\r\nprivate var radiansToDegrees:Number = 180\/Math.PI;\/\/this is needed for the rotation\r\nprivate var damage:int = 3;\/\/how much damage this little baby can inflict\r\nprivate var range:int = 100;\/\/how far away (in pixels) it can hit a target\r\nprivate var enTarget;\/\/the current target that it's rotating towards\r\nprivate var cTime:int = 0;\/\/how much time since a shot was fired by this turret\r\nprivate var reloadTime:int = 12;\/\/how long it takes to fire another shot\r\nprivate var loaded:Boolean = true;\/\/whether or not this turret can shoot\r\n<\/pre>\n<p>Those are a lot of variables, aren&#8217;t they? Well, this is a pretty complex task, so we&#8217;re going to need all of them. So, brace yourself, for we are now going to jump into some code. Add this code to the <tt>eFrameEvents<\/tt> function in &#8220;Turret.as&#8221;:<\/p>\n<pre lang=\"actionscript\">\r\n\/\/FINDING THE NEAREST ENEMY WITHIN RANGE\r\nvar distance:Number = range;\/\/let's define a variable which will be how far the nearest enemy is\r\nenTarget = null;\/\/right now, we don't have a target to shoot at\r\nfor(var i:int=_root.enemyHolder.numChildren-1;i>=0;i--){\/\/loop through the children in enemyHolder\r\n\tvar cEnemy = _root.enemyHolder.getChildAt(i);\/\/define a movieclip that will hold the current child\r\n\t\/\/this simple formula with get us the distance of the current enemy\r\n\tif(Math.sqrt(Math.pow(cEnemy.y - y, 2) + Math.pow(cEnemy.x - x, 2)) < distance){\r\n\t\t\/\/if the selected enemy is close enough, then set it as the target\r\n\t\tenTarget = cEnemy;\r\n\t}\r\n}\r\n\/\/ROTATING TOWARDS TARGET\r\nif(enTarget != null){\/\/if we have a defined target\r\n\t\/\/turn this baby towards it\r\n\tthis.rotation = Math.atan2((enTarget.y-y), enTarget.x-x)\/Math.PI*180 - 90;\r\n\tif(loaded){\/\/if the turret is able to shoot\r\n\t\tloaded = false;\/\/then make in unable to do it for a bit\r\n\t\tvar newBullet:Bullet = new Bullet();\/\/create a bullet\r\n\t\t\/\/set the bullet's coordinates\r\n\t\tnewBullet.x = this.x;\r\n\t\tnewBullet.y = this.y;\r\n\t\t\/\/set the bullet's target and damage\r\n\t\tnewBullet.target = enTarget;\r\n\t\tnewBullet.damage = damage;\r\n\t\t_root.addChild(newBullet);\/\/add it to the stage\r\n\t}\r\n}\r\n\/\/LOADING THE TURRET\r\nif(!loaded){\/\/if it isn't loaded\r\n\tcTime ++;\/\/then continue the time\r\n\tif(cTime == reloadTime){\/\/if time has elapsed for long enough\r\n\t\tloaded = true;\/\/load the turret\r\n\t\tcTime = 0;\/\/and reset the time\r\n\t}\r\n}\r\n<\/pre>\n<p>Now, if you test the movie out, the turrets should be shooting at those darn red dots. Now, we have to make those dots die! In the <tt>eFrameEvents()<\/tt> function in \"Enemy.as\", add the following code:<\/p>\n<pre lang=\"actionscript\">\r\n\/\/remove this from stage when game is over\r\nif(_root.gameOver){\r\n\tdestroyThis();\r\n}\r\n<\/pre>\n<p>Pretty hot stuff, ain't it? Well, this concludes the fourth installment of this tutorial. Join us next time when we make levels and have winning and losing scenarios!<\/p>\n<h4>Final Product<\/h4>\n<p><center><object classid=\"clsid:d27cdb6e-ae6d-11cf-96b8-444553540000\" width=\"550\" height=\"400\" codebase=\"http:\/\/download.macromedia.com\/pub\/shockwave\/cabs\/flash\/swflash.cab#version=6,0,40,0\"><param name=\"src\" value=\"http:\/\/www.mrsunstudios.com\/obj\/tuts\/tower-defense-as3\/pt4\/source.swf\" \/><embed type=\"application\/x-shockwave-flash\" width=\"550\" height=\"400\" src=\"http:\/\/www.mrsunstudios.com\/obj\/tuts\/tower-defense-as3\/pt4\/source.swf\"><\/embed><\/object><\/p>\n<p><a href=\"http:\/\/www.mrsunstudios.com\/obj\/tuts\/tower-defense-as3\/pt4\/tower-defense-as3-source.zip\">Source Files (Zipped)<\/a><\/center><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Table of Contents Setting up Level Adding Turrets Adding Enemies Making Turrets Attack Enemies Winning\/Losing the Game Expanding on the Game Finishing Touches Step 4: Making Turrets Attack Enemies Well, it&#8217;s now time to let the enemies we just created be destroyed. Let&#8217;s dig in, shall we? First, we&#8217;ll define a single health variable for [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[160,5,8,4,6],"tags":[25,8,246,19,18,245,247,11],"_links":{"self":[{"href":"http:\/\/www.mrsunstudios.com\/blog\/wp-json\/wp\/v2\/posts\/1439"}],"collection":[{"href":"http:\/\/www.mrsunstudios.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.mrsunstudios.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.mrsunstudios.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.mrsunstudios.com\/blog\/wp-json\/wp\/v2\/comments?post=1439"}],"version-history":[{"count":6,"href":"http:\/\/www.mrsunstudios.com\/blog\/wp-json\/wp\/v2\/posts\/1439\/revisions"}],"predecessor-version":[{"id":1470,"href":"http:\/\/www.mrsunstudios.com\/blog\/wp-json\/wp\/v2\/posts\/1439\/revisions\/1470"}],"wp:attachment":[{"href":"http:\/\/www.mrsunstudios.com\/blog\/wp-json\/wp\/v2\/media?parent=1439"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.mrsunstudios.com\/blog\/wp-json\/wp\/v2\/categories?post=1439"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.mrsunstudios.com\/blog\/wp-json\/wp\/v2\/tags?post=1439"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}