{"id":1373,"date":"2009-02-28T08:01:36","date_gmt":"2009-02-28T12:01:36","guid":{"rendered":"http:\/\/www.mrsunstudios.com\/?p=1373"},"modified":"2022-05-29T08:23:30","modified_gmt":"2022-05-29T12:23:30","slug":"tutorial-create-a-tower-defense-game-in-as3","status":"publish","type":"post","link":"http:\/\/www.mrsunstudios.com\/blog\/flash\/tutorial-create-a-tower-defense-game-in-as3\/","title":{"rendered":"Tutorial: Create a Tower Defense Game in AS3"},"content":{"rendered":"<div class=\"toc\">\n<h3>Table of Contents<\/h3>\n<ol>\n<li class=\"c_chap\"><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><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 1: Setting Up a Level<\/h3>\n<p>The tower defense genre is one that has become extremely popular over the years. Although they can become quite complicated to develop, they are almost always very fun to play. I am here to walk you through the creation of one of these games. Let us begin, shall we?<\/p>\n<p>In this section of the tutorial, we&#8217;re going to set up the roads and stuff onto the stage. However, the first thing we need to do is create a blank flash document with a black background with the frames per second set at 24.<\/p>\n<p>Now, we have to create two classes. In order to do this, simply create two external ActionScript files by selecting <strong>File -> New -> ActionScript File<\/strong>, twice. The first class we&#8217;ll create is one for an empty block that towers can be placed in. Add the following code to it:<\/p>\n<pre lang=\"actionscript\">\r\npackage{\r\n\t\/\/importing required classes for this to work\r\n\timport flash.display.MovieClip;\r\n\timport flash.events.*;\r\n\tpublic class EmptyBlock extends MovieClip{\/\/defining the class as EmptyBlock\r\n\t\tprivate var _root:MovieClip;\/\/creating a _root variable to access root easily\r\n\t\t\r\n\t\tpublic function EmptyBlock(){\/\/this function will always run once EmptyBlock is called\r\n\t\t\tthis.addEventListener(Event.ADDED, beginClass);\/\/create a function that will run once\r\n\t\t\tthis.addEventListener(Event.ENTER_FRAME, eFrameEvents);\/\/create a enterFrame function\r\n\t\t}\r\n\t\tprivate function beginClass(e:Event):void{\r\n\t\t\t_root = MovieClip(root);\/\/setting the _root as the root level\r\n\t\t\t\r\n\t\t\tthis.buttonMode = true;\/\/make this act like a button\r\n\t\t\tthis.addEventListener(MouseEvent.MOUSE_OVER, thisMouseOver);\/\/adding function for mouseOver\r\n\t\t\tthis.addEventListener(MouseEvent.MOUSE_OUT, thisMouseOut);\/\/adding function for mouseOut\r\n\t\t\tthis.addEventListener(MouseEvent.CLICK, thisClick);\/\/adding function for clicking\r\n\t\t}\r\n\t\tprivate function eFrameEvents(e:Event):void{\r\n\t\t\tif(_root.gameOver){\/\/remove this and listeners if game is over\r\n\t\t\t\tthis.removeEventListener(Event.ENTER_FRAME, eFrameEvents);\r\n\t\t\t\tthis.removeEventListener(MouseEvent.MOUSE_OVER, thisMouseOver);\r\n\t\t\t\tthis.removeEventListener(MouseEvent.MOUSE_OUT, thisMouseOut);\r\n\t\t\t\tthis.removeEventListener(MouseEvent.CLICK, thisClick);\r\n\t\t\t\tMovieClip(this.parent).removeChild(this);\r\n\t\t\t}\r\n\t\t}\r\n\t\tprivate function thisMouseOver(e:MouseEvent):void{\r\n\t\t\t\/\/changing the background so the user know's it's clickable\r\n\t\t\tthis.graphics.drawRect(0,0,25,25);\r\n\t\t\tthis.graphics.endFill();\r\n\t\t}\r\n\t\tprivate function thisMouseOut(e:MouseEvent):void{\r\n\t\t\t\/\/changing the background back\r\n\t\t\tthis.graphics.beginFill(0x333333);\r\n\t\t\tthis.graphics.drawRect(0,0,25,25);\r\n\t\t\tthis.graphics.endFill();\r\n\t\t}\r\n\t\tprivate function thisClick(e:MouseEvent):void{\r\n\t\t\t\/\/we'll add code that'll make a turret be made later\r\n\t\t}\r\n\t}\r\n}\r\n<\/pre>\n<p>I&#8217;ve commented the code extensively if you need any explanation. Now, save this file as &#8220;EmptyBlock.as&#8221; in the same folder as your source .fla file. Now, take the second external ActionScript file. We will turn this into a special block which will act as a marker for the road. There are going to be 6 types of this special block, the four different directional notifiers, and the start and finish block. They won&#8217;t look any different than any other block, but they will be very important later. Add this code to that second class:<\/p>\n<pre lang=\"actionscript\">\r\npackage{\r\n\t\/\/imports\r\n\timport flash.display.*;\r\n\timport flash.events.*;\r\n\timport flash.geom.*;\r\n\tpublic class DirectBlock extends MovieClip{\/\/we'll call it a DirectBlock\r\n\t\tprivate var _root:MovieClip;\/\/again, defining a _root\r\n\t\tprivate var directType:String;\/\/what kind of special block is this\r\n\t\t\r\n\t\t\/\/this time, we have to accept some values to make it easier to place, like the type and coordinates\r\n\t\tpublic function DirectBlock(type:String,xVal:int,yVal:int){\r\n\t\t\tdirectType = type;\/\/set the directType so that all other functions can use it\r\n\t\t\t\/\/add the required event listeners\r\n\t\t\tthis.addEventListener(Event.ADDED, beginClass);\r\n\t\t\tthis.addEventListener(Event.ENTER_FRAME, eFrame);\r\n\t\t\t\r\n\t\t\t\/\/setting the coordinates\r\n\t\t\tthis.x = xVal;\r\n\t\t\tthis.y = yVal;\r\n\t\t}\r\n\t\tprivate function beginClass(e:Event):void{\r\n\t\t\t_root = MovieClip(root);\/\/setting the _root again\r\n\t\t\t\r\n\t\t\t\/\/making this into a 25x25 square\r\n\t\t\tthis.graphics.beginFill(0x111111);\r\n\t\t\tthis.graphics.drawRect(0,0,25,25);\r\n\t\t\tthis.graphics.endFill();\r\n\t\t}\r\n\t\tprivate function eFrame(e:Event):void{\r\n\t\t\tif(_root.gameOver == true){\/\/destroy this if the game's over\r\n\t\t\t\tthis.removeEventListener(Event.ENTER_FRAME, eFrame);\r\n\t\t\t\tMovieClip(this.parent).removeChild(this);\r\n\t\t\t}\r\n\t\t\t\/\/we'll add more code to this later\r\n\t\t}\r\n\t}\r\n}\r\n<\/pre>\n<p>This will just set up the blocks. Now, we must return back to the main .fla file. Create a new layer to place actions in, and add the following code:<\/p>\n<pre lang=\"actionscript\">\r\nstop();\r\n\r\n\/\/setting vars to step in for turns and special blocks\r\nvar S:String = 'START';\r\nvar F:String = 'FINISH';\r\nvar U:String = 'UP';\r\nvar R:String = 'RIGHT';\r\nvar D:String = 'DOWN';\r\nvar L:String = 'LEFT';\r\n\r\nvar startDir:String;\/\/the direction the enemies go when they enter\r\nvar finDir:String;\/\/the direction the enemies go when they exit\r\nvar startCoord:int;\/\/the coordinates of the beginning of the road\r\nvar lvlArray:Array = new Array();\/\/this array will hold the formatting of the roads\r\n\r\nlvlArray = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\r\n\t\t\t0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\r\n\t\t\t0,0,0,0,R,1,1,D,0,0,R,1,1,D,0,0,R,1,1,D,0,0,\r\n\t\t\t0,0,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,\r\n\t\t\t0,0,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,\r\n\t\t\tS,D,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,R,1,F,\r\n\t\t\t0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,0,0,0,\r\n\t\t\t0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,0,0,0,\r\n\t\t\t0,R,1,1,U,0,0,R,1,1,U,0,0,R,1,1,U,0,0,0,0,0,\r\n\t\t\t0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\r\n\t\t\t0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\r\n\t\t\t0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\r\n\t\t\t];\r\n\r\n\/\/the names of these variables explain what they do\r\nvar currentLvl:int = 1;\r\nvar gameOver:Boolean = false;\r\n\r\nfunction startGame():void{\/\/we'll run this function every time a new level begins\r\n\t\/\/right now we don't have any code\r\n}\r\n\r\nvar roadHolder:Sprite = new Sprite();\/\/create an object that will hold all parts of the road\r\naddChild(roadHolder);\/\/add it to the stage\r\nfunction makeRoad():void{\r\n\tvar row:int = 0;\/\/the current row we're working on\r\n\tvar block;\/\/this will act as the block that we're placing down\r\n\tfor(var i:int=0;i<lvlArray.length;i++){\/\/creating a loop that'll go through the level array\r\n\t\tif(lvlArray[i] == 0){\/\/if the current index is set to 0\r\n\t\t\tblock = new EmptyBlock();\/\/create a gray empty block\r\n\t\t\tblock.graphics.beginFill(0x333333);\r\n\t\t\tblock.graphics.drawRect(0,0,25,25);\r\n\t\t\tblock.graphics.endFill();\r\n\t\t\taddChild(block);\r\n\t\t\t\/\/and set the coordinates to be relative to the place in the array\r\n\t\t\tblock.x= (i-row*22)*25;\r\n\t\t\tblock.y = row*25;\r\n\t\t} else if(lvlArray[i] == 1){\/\/if there is supposed to be a row\r\n\t\t\t\/\/just add a box that will be a darker color and won't have any actions\r\n\t\t\tblock = new Shape();\r\n\t\t\tblock.graphics.beginFill(0x111111);\r\n\t\t\tblock.graphics.drawRect(0,0,25,25);\r\n\t\t\tblock.graphics.endFill();\t\t\r\n\t\t\tblock.x= (i-row*22)*25;\r\n\t\t\tblock.y = row*25;\t\r\n\t\t\troadHolder.addChild(block);\/\/add it to the roadHolder\r\n\t\t} else if(lvlArray[i] is String){\/\/if it's a string, meaning a special block\r\n\t\t\t\/\/then create a special block\r\n\t\t\tblock = new DirectBlock(lvlArray[i],(i-row*22)*25,row*25);\r\n\t\t\taddChild(block);\r\n\t\t}\r\n\t\tfor(var c:int = 1;c<=16;c++){\r\n\t\t\tif(i == c*22-1){\r\n\t\t\t\t\/\/if 22 columns have gone by, then we move onto the next row\r\n\t\t\t\trow++;\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n}\r\n\/\/run these functions at the start\r\nmakeRoad();\r\nstartGame();\r\n<\/pre>\n<p>Now, if you test out your game, you'll see nice little road set up for you. However, we need to keep that empty space in the bottom so we can add stats and other cool stuff.<\/p>\n<p>Well, that concludes this first part of the tutorial. Next time we'll make it so you can add turrets!<\/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\/pt1\/source.swf\" \/><embed type=\"application\/x-shockwave-flash\" width=\"550\" height=\"400\" src=\"http:\/\/www.mrsunstudios.com\/obj\/tuts\/tower-defense-as3\/pt1\/source.swf\"><\/embed><\/object><\/p>\n<p><a href=\"http:\/\/www.mrsunstudios.com\/obj\/tuts\/tower-defense-as3\/pt1\/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 1: Setting Up a Level The tower defense genre is one that has become extremely popular over the years. Although they can become quite complicated to develop, they are almost always [&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\/1373"}],"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=1373"}],"version-history":[{"count":14,"href":"http:\/\/www.mrsunstudios.com\/blog\/wp-json\/wp\/v2\/posts\/1373\/revisions"}],"predecessor-version":[{"id":1484,"href":"http:\/\/www.mrsunstudios.com\/blog\/wp-json\/wp\/v2\/posts\/1373\/revisions\/1484"}],"wp:attachment":[{"href":"http:\/\/www.mrsunstudios.com\/blog\/wp-json\/wp\/v2\/media?parent=1373"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.mrsunstudios.com\/blog\/wp-json\/wp\/v2\/categories?post=1373"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.mrsunstudios.com\/blog\/wp-json\/wp\/v2\/tags?post=1373"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}