Shooting Target Game In this Premium Tutorial, we ll learn how to combine several ActionScript 3 classes and skills to create a fantastic shooting gallery game. Step 1: Brief Overview Using the Flash Tools we ll create good looking graphics that will be powered by several ActionScript 3 classes like MouseCursor, Tween Nano, Sprite, Timers and other Events. The user will be able to input a player s name and destroy a predefined number of dartboards before the game ends. Step 2: Document Settings Open Flash and create a 720 pixels wide, 480 pixels tall document. Set the Frame rate to 24fps.
Step 3: Interface A colorful nice looking interface will power our code, this involves multiple shapes, buttons, custom cursors and more. Continue to the next steps to learn how to create this GUI.
Step 4: Sky A blue radial gradient will be the sky. Select the Rectangle Tool (R) and create a 720 335 px rectangle, use the Color Panel to apply a #EFFDFE, #7FD7FF radial background.
Step 5: Clouds Three main shapes will be used for the clouds, the rest will be duplicated MovieClips. Use the Oval Tool (O) to create circles and ovals of different sizes, after you got the cloud shape you like, color them using this gradient fill #F1FBFF, #C3ECFF. Use the Gradient Transform Tool (F) to rotate the gradient.
Step 6: Mountains Let s add some mountains to the scene. Use the Rectangle Tool to create two rectangles across the scene, use this gradient on them #8DB400, #CFF500. With the Selection Tool (V), grab the corners of the rectangle and give them a less squared form.
Use the same technique only this time dragging from the sides of the rectangles, (you ll se a curve in the mouse cursor), use the Gradient Transform tool to rotate the gradient.
Step 7: Grass This is the grass graphic we ll be creating. It is made from three or four different shapes in different colors.
Use the Rectangle Tool to create a rectangle, and use the mountains technique to start modifiying the shape. You can see how the grass was created looking at the next image: Once you have the first grass shape you just now have to modify the colors and sizes, then put them together and you re done.
Step 8: Ground The ground graphic is pretty simple, a #5F4123 colored background, with some #3A2814 rocks.
Your background should look like this now:
Step 9: Info Panel The Info Panel will show the player s name as well as the current score. Let s start by creating the background. Use the Rectangle Primitive Tool to create a 230 40 px, #CCCCCC, alpha 60% rectangle and place it as seen in the image. Duplicate the shape and change it to 225x30px, #000000, alpha 70%. Center the new shape in the gray background.
Convert the new shape to MovieClip and name it infobg. Use the Text Tool (T) to create two dynamic textfields and place them in the background.
This is the format used for the player name: Walway Rounded, 28pt, #6CA8E6, instance name: playername. The textfield on the side is: Walkway rounded, 32pt, #FFFFFF, instance name: score.
Step 10: Cursor The custom cursor is composed by a series of rounded rectangles and a circle. A look at the next image will give you a better understandig of how it was made. Step 11: Dartboard The Dartboard is one of the main elements in the game, it is the target to destroy. Use the Oval tool to create a 80 80 px circle with this linear gradient #697368, #060604.
Duplicate the shape, resize it to 64 64 px, and change the gradient to #F6F6F6, #DDDDDD. Use the Oval Primitive Tool to create a 46 46 px circle and modify the inner radius to 75.00. Use again the black gradient. Duplicate the white circle, resize it to 18 18 px, and fill it with #AF4F50.
Convert the Shapes to MovieClip and name it Dartboard, be sure to check the Export for ActionScript box. Step 12: Hits A hit counter will be on the top-left corner of the stage. Use the same format of the playername Textfield, just change the color to #FEE75C. The dynamic textfield is called hits.
Step 13: Name Panel This is the name panel, nothing difficult about it. This will be first thing shown to the player. It contains an Input TextField named namefield and dartboard used as a button named beginbutton. Step 14: Sound We ll play a sound when a dartboard is hit. There are many sites where you can download sound effects and music online, you can get the effect used in the tutorial here.
Step 15: Export Sound for ActionScript To use the sound we first need to import it to the library. Press Cmd+R, browse to the sound you downloaded and click Open. Open the library and right click the sound icon, select Properties and mark the Export for ActionScript box. This ends the graphic phase, let the ActionScripting begin!
Step 16: New ActionScript Class Create a new (Cmd + N) ActionScript 3.0 Class and save it as Main.as in your class folder. Step 17: Tween Nano We ll use a different tween engine from the default included in flash, this will increase performance (it s also easier to use). You can download Tween Nano from its official website. Step 18: Package The package keyword allows you to organize your code into groups that can be imported by other scripts. It s recommended to name them starting with a lowercase letter and use intercaps for subsequent words for example: myclasses. It s also common to name them using your company s website: com.mycompany.classestype.myclass. In this example, we re using a single class, so there isn t really a need to create a classes folder.
1package 2{ Step 19: Import Directive These are the classes we ll need to import for our class to work, the import directive makes externally defined classes and packages available to your code. 1import flash.display.sprite; 2import flash.ui.mouse; 3import com.greensock.tweennano; 4import flash.events.mouseevent; 5import flash.events.event; 6import flash.utils.timer; 7import flash.events.timerevent; Step 20: Declaring and Extending Here we declare the class using the class definition keyword followed by the name that we want for the class, remember that you have to save the file using this name. The extends keyword defines a class that is a subclass of another class. The subclass inherits all the methods, properties and functions, that way we can use them in our class. 1public class Main extends Sprite 2{ Step 21: Variables These are the variables we ll use, read the comments in the code to find out more about each one. 01 private var gridy:array = new Array(); //Stores the y coordinate in which a 02 dartboard can be positioned
03 private var gridx:array = new Array();//Stores the x coordinate in which a 04 dartboard can be positioned 05 private var xpos:int = 0; //The latest x position used by a dartboard 06 private var ypos:int = 0;//The latest y position used by a dartboard 07 private var dartboards:array = new Array(); //Stores the dartboards sprites 08 private var smack:smacksound = new SmackSound(); //The sound that will play 09 when a dartboard is destroyed 10 private var timer:timer = new Timer(3000); //The amount of time to wait before change the dartboards in screen private var currentdartboards:int = 0; //The dartboards already shown in stage, checks for level completion private var levelcomplete:int = 30; //The dartboards to show to complete the level private var scorepanel:scorepanel = new ScorePanel(); //A score panel instance Step 22: Constructor The constructor is a function that runs when an object is created from a class, this code is the first to execute when you make an instance of an object or runs using the Document Class. It calls the necessary functions to start the game. Check those functions in the next steps. 1public function Main():void 2{ 3 startcustomcursor(); 4 namepanelhandler(); 5 updatescore(); 6 bg.addeventlistener(mouseevent.mouse_down, addhits); 7} Step 23: Name Panel Handler This function animates the Name Panel to stage and adds a listener to the button to set the name in the Textfield when activated. 1private function namepanelhandler():void
2{ 3 namepanel.beginbutton.stop(); 4 namepanel.beginbutton.addeventlistener(mouseevent.mouse_up, 5setPlayerName); 6 TweenNano.from(namePanel, 0.5, {y: -namepanel.height/2}); } Step 24: Set Player Name Sets the name written in the Name Panel textfield to the playername field in the Info panel. private function setplayername(e:mouseevent):void 1 { 2 smack.play(); 3 namepanel.beginbutton.gotoandplay(3); 4 playername.text = namepanel.namefield.text; 5 TweenNano.to(namePanel, 0.5, {y: stage.stageheight + namepanel.height/2, 6 oncomplete: begingame}); 7 } Step 25: Add Custom Cursor The following function makes the custom cursor draggable, it also hides the default mouse cursor. 1private function startcustomcursor():void 2{ 3 Mouse.hide(); 4 cursor.startdrag(true); 5} Step 26: Dartboards Grid
This is an important function, it calculates the stage area and creates a grid based on the size of the Dartboard (80px). We ll use the resulting arrays later to prevent the dartboards from appearing in front of each other. private function calculategrid():void 01 { 02 gridx = []; 03 gridy = []; 04 05 for (var h:int = 1; h <= (stage.stageheight - 160) / 80; h++) //The - 06 reduces invisible/used area 07 { 08 gridy.push(80 * h); 09 } 10 11 for (var v:int = 1; v <= (stage.stagewidth - 160) / 80; v++) 12 { 13 gridx.push(80 * v); 14 } 15 } Step 27: Add Random Dartboards The next function will create and add the dartboards established by the amount parameter. It follows this logic: Calculate the grid (it only does this one time) Create a new Dartboard instance and prevent to play it Use a random position from the positions arrays Remove the last position used to avoid adding dartboards in the same place Add the destroy listener to the dartboard Add dartboard to stage and animate it Add dartboard to the dartboards array Get next highest depth (frequently asked in AS3, take note) for the custom cursor Add one to the dartboards shown list 01 private function addrandomdartboards(amount:int):void 02 {
03 04 05 06 07 08 09 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 } calculategrid(); for (var i:int = 0; i < amount; i++) { var dartboard:dartboard = new Dartboard(); dartboard.stop(); xpos = gridx[math.floor(math.random() * gridx.length)]; ypos = gridy[math.floor(math.random() * gridy.length)]; dartboard.x = xpos + 40; dartboard.y = ypos + 40; gridx.splice(gridx.indexof(xpos), 1); gridy.splice(gridy.indexof(ypos), 1); dartboard.addeventlistener(mouseevent.mouse_down, destroydartboard); addchild(dartboard); TweenNano.from(dartboard, 0.6, {rotationy: 180}); TweenNano.from(dartboard, 0.6, {scalex: 0.4}); TweenNano.from(dartboard, 0.6, {scaley: 0.4}); dartboards.push(dartboard); setchildindex(cursor, (numchildren - 1)); currentdartboards++; } Step 28: Destroy Dartboard This function handles the animation for a darboard that has been hit, it also removes the dartboard from the dartboards array and adds new ones if there are no more clips in stage. Scores and scores animations are handled here too.
private function destroydartboard(e:mouseevent):void 01 { 02 smack.play(); //The hit sound 03 e.target.removeeventlistener(mouseevent.mouse_down, destroydartboard); 04 e.target.gotoandplay(3); 05 e.target.addeventlistener(event.enter_frame, removedartboard); 06 07 dartboards.splice(dartboards.indexof(e.target), 1); //Remove from array 08 09 if (dartboards.length == 0) //Add new darboards if all have been 10 destroyed 11 { 12 timer.stop(); 13 addrandomdartboards(5); 14 timer.start(); 15 } 16 17 /*Update scores, hits and play hit animation*/ 18 19 updatescore(1); 20 updatehits(1); 21 22 var plusone:scoreplus = new ScorePlus(); 23 24 plusone.x = e.target.x; 25 plusone.y = e.target.y + plusone.height; 26 27 addchild(plusone); 28 29 TweenNano.from(plusOne, 0.5, {scalex: 0.5}); 30 TweenNano.from(plusOne, 0.5, {scaley: 0.5, oncomplete:removescoregfx, 31 oncompleteparams: [plusone]}); } Step 29: Remove Score Graphics Removes the Score +1 movieclip. 1private function removescoregfx(target:sprite):void
2{ 3 4} removechild(target); Step 30: Remove Dartboard Checks if the darboard animation has ended and removes it if true. private function removedartboard(e:event):void 1 { 2 if (e.target.currentframe == <IMG class=wp-smiley alt=8) 3 src="http://tutsplus.com/wp-includes/images/smilies/icon_cool.gif"> 4 { 5 e.target.removeeventlistener(event.enter_frame, removedartboard); 6 removechild(e.target as Sprite); 7 } 8 } Step 31: Update Score Adds the indicated score to the score TextField. 1private function updatescore(addtoscore:int = 0):void 2{ 3 score.text = String(int(score.text) + addtoscore); 4} Step 32: Update Hits Adds 1 to the hits score, this is called when a dartboard is destroyed. 1private function updatehits(addtohits:int = 0):void 2{
3 4 5} hits.text = String(int(hits.text) + addtohits); TweenNano.from(hits, 0.3, {y: -5}); Step 33: Add Hits Adds the total hit score to the score TextField. 1private function addhits(e:mouseevent):void 2{ 3 score.text = String(int(score.text) + int(hits.text)); 4 hits.text = "0"; 5} Step 34: Begin Game Initiates the game. Creates the dartboards, removes the players name panel and starts the timer. 01 private function begingame(restarting:boolean = false):void 02 { 03 if (! restarting) 04 { 05 removechild(namepanel); 06 } 07 08 addrandomdartboards(5); 09 timer.addeventlistener(timerevent.timer, removeremaininglisteners); 10 timer.start(); 11 } Step 35: Remove Remaining
Removes the dartboards that weren t hit and adds new ones if the level isn t complete. private function removeremaining():void 01 { 02 for (var i:int = dartboards.length-1; i >= 0; i--) 03 { 04 removechild(dartboards[i]); 05 dartboards.length = i; 06 07 if (dartboards.length == 0 && currentdartboards < levelcomplete) 08 { 09 addrandomdartboards(5); 10 timer.start(); 11 } 12 else if (dartboards.length == 0 && currentdartboards >= levelcomplete) 13 //If level complete 14 { 15 levelcompleted(); 16 } 17 } 18 } Step 36: Level Complete If all the allowed dartboards have been displayed in stage, this function will execute. It calculates the final score, hides the info panel, and shows the ScorePanel. 01 private function levelcompleted():void 02 { 03 score.text = String(int(score.text) + int(hits.text)); 04 hits.text = "0"; 05 06 score.visible = false; 07 playername.visible = false; 08 09 TweenNano.to(infoBg, 0.5, {x: -infobg.width/2}); 10 11 scorepanel.x = stage.stagewidth + scorepanel.width / 2; 12 scorepanel.y = stage.stageheight / 2;
13 14 15 16 17 18 19 20 21 22 } scorepanel.myscore.text = score.text; scorepanel.playagain.addeventlistener(mouseevent.mouse_up, restart); addchild(scorepanel); setchildindex(cursor, (numchildren - 1)); TweenNano.to(scorePanel, 0.5, {x: stage.stagewidth/2}); Step 37: Restart The next lines make the restart possible. You ll find everything explained in the comments. private function restart(e:mouseevent):void { 01 score.visible = true; //hides the score 02 score.text = "0"; //Sets the score to 0 03 playername.visible = true; //Shows again the player name 04 05 scorepanel.playagain.removeeventlistener(mouseevent.mouse_up, restart); 06 //Removes the listener from the button in the score panel 07 08 TweenNano.to(infoBg, 0.5, {x: infobg.width/2}); //Animates the info 09 panel and the score panel 10 TweenNano.to(scorePanel, 0.5, {x: stage.stagewidth + scorepanel.width/2, 11 oncomplete: removescorepanel}); 12 13 currentdartboards = 0; //Resets the current dartboards list 14 begingame(true); //starts the game } Step 38: Remove Score Panel Removes the score panel from the stage when the animation is complete.
1private function removescorepanel():void 2{ 3 removechild(scorepanel); 4} Step 39: Document Class We ll make use of the Document Class in this tutorial, if you don t know how to use it or are a bit confused please read this QuickTip.
Step 40: Test Movie You re now ready to test your game!, go to Flash and press Cmd+Return, check that everything works as expected and have fun!