Monday, November 5, 2012

How to make simple shooting game like Balloon Hunt

For this tutorial I'll use only FlashDevelop as its easier this way. You can easily adapt it later to build with the Flash Ide.

So lets describe our game first. We will have flying targets all over the screen and we will click on them with the mouse in order to shoot them. You can play the original game here Balloon Hunt 2. First we will add the targets.

Now lets start with new AS3 project with size 640x480 and 50fps. Here is the stub code:

package  
{
 import flash.display.*;
 import flash.utils.*;
 import flash.events.*;
 
 public class Game extends MovieClip
 {  
  public function Game() 
  {   
  }  
 }
}
Now I'll add an array for our targets:
private var targets:Array = new Array();
And a separate class for our targets. Its a very simple class that extends MovieClip and we will use its graphics object to draw a circle in it.
 import flash.display.*;
 
 public class Target extends MovieClip
 {

  public var hit:Boolean = false;

  public function Target() 
  {
   graphics.beginFill(0xff0000);
   graphics.drawCircle(0, 0, 30);
  }
  
 }
And a function to our game class to start the game:
 
 import flash.display.*;
 import flash.utils.*;
 import flash.events.*;
 
 public class Game extends MovieClip
 {
  
  private var targets:Array = new Array();
  
  public function Game() 
  {
   startGame();
  }
  
  private function startGame() : void {
   var target:Target = new Target();
   target.x = 320;
   target.y = 240;
   this.addChild(target);
   this.addEventListener(Event.ENTER_FRAME, gameLoop);   
  }
  
  private function gameLoop(e:Event) :void {
   
  }
  
 }

Here you will see several things. First we add a target to our game just to see something on the screen. Next or actually first we call our function startGame from the constructor. And last we add a function that will be called every frame:
this.addEventListener(Event.ENTER_FRAME, gameLoop);
This will be our game loop. Now you can run the project and see what we get - a lonely target stuck at the center of our game. Lets change this - we will add target on regular basis. We need a counter for this - targetCounter.
private var targetCounter:int;
  
private const TARGETCOUNTER:int = 1000;
And we will add the variable lastTime:
private var lastTime:int;
And a code to the gameLoop function to track how much time have passed.
   if(lastTime == 0) lastTime = getTimer();
   var timeDiff:int = getTimer() - lastTime;
   lastTime += timeDiff;
Here is the full code:
 import flash.display.*;
 import flash.utils.*;
 import flash.events.*;
 
 public class Game extends MovieClip
 {
  
  private var targets:Array = new Array();
  
  private var lastTime:int;
  
  private var targetCounter:int;
  
  private const TARGETCOUNTER:int = 500;
  
  public function Game() 
  {
   startGame();
  }
  
  private function startGame() : void {
   lastTime = 0;
   targetCounter = 0;
   this.addEventListener(Event.ENTER_FRAME, gameLoop);   
  }
  
  private function gameLoop(e:Event) :void {
   if(lastTime == 0) lastTime = getTimer();
   var timeDiff:int = getTimer() - lastTime;
   lastTime += timeDiff;
  }
  
 }
Now we will start with adding targets and moving them around. I want to mention that the code is not optimized but I think it will be easier for beginners to understand it this way. Here is how we change the game loop now:
  private function gameLoop(e:Event) :void {
   if(lastTime == 0) lastTime = getTimer();
   var timeDiff:int = getTimer() - lastTime;
   lastTime += timeDiff;
   
   // next target counter
   targetCounter -= timeDiff;
   
   if (targetCounter <= 0) {
    // add new target
    var target:Target = new Target();
    target.x = -30;
    target.y = Math.random() * 480; // random
    this.addChild(target);
    targets.push(target);
    targetCounter = TARGETCOUNTER;
   }
   // move all targets
   for (var i:int = targets.length - 1; i >= 0; i--) {
    var tg:Target = targets[i];
    tg.x += timeDiff * 0.1;
    // check if the target is outside the screen
    if (tg.x > 670) { // 640 + 30
     this.removeChild(tg);
     targets.splice(i, 1);
    }
   }
  }
And here is the result:

Now its time to add the action. We will add the function mouseDown:
  private function mouseDown(e:MouseEvent) {
   
  }
And at startGame we will add this row:
this.addEventListener(MouseEvent.MOUSE_DOWN, mouseDown);
And here is the full code of mouseDown:
  private function mouseDown(e:MouseEvent):void {
   if (e.target is Target) {
    var target:Target = e.target as Target;
    target.hit = true;
   }
  }
And now we must change the part where we check if we must remove a target:
    if (tg.x > 670 || tg.hit) { // 640 + 30
     this.removeChild(tg);
     targets.splice(i, 1);
    }
And that's it all. Here is the full code if you've missed something:
Game.as
package  
{
 
 import flash.display.*;
 import flash.utils.*;
 import flash.events.*;
 
 public class Game extends MovieClip
 {
  
  private var targets:Array = new Array();
  
  private var lastTime:int;
  
  private var targetCounter:int;
  
  private const TARGETCOUNTER:int = 1000;
  
  public function Game() 
  {
   startGame();
  }
  
  private function startGame() : void {
   lastTime = 0;
   targetCounter = 0;
   this.addEventListener(Event.ENTER_FRAME, gameLoop);  
   this.addEventListener(MouseEvent.MOUSE_DOWN, mouseDown);
  }
  
  private function gameLoop(e:Event) :void {
   if(lastTime == 0) lastTime = getTimer();
   var timeDiff:int = getTimer() - lastTime;
   lastTime += timeDiff;
   
   // next target counter
   targetCounter -= timeDiff;
   
   if (targetCounter <= 0) {
    // add new target
    var target:Target = new Target();
    target.x = -30;
    target.y = Math.random() * 480; // random
    this.addChild(target);
    targets.push(target);
    targetCounter = TARGETCOUNTER;
   }
   // move all targets
   for (var i:int = targets.length - 1; i >= 0; i--) {
    var tg:Target = targets[i];
    tg.x += timeDiff * 0.1;
    // check if the target is outside the screen
    if (tg.x > 670 || tg.hit) { // 640 + 30
     this.removeChild(tg);
     targets.splice(i, 1);
    }
   }
  }
  
  private function mouseDown(e:MouseEvent):void {
   if (e.target is Target) {
    var target:Target = e.target as Target;
    target.hit = true;
   }
  }
  
 }

}
Target.as
package  
{
 
 import flash.display.*;
 
 public class Target extends MovieClip
 {
  
  public var hit:Boolean = false;
  
  public function Target() 
  {
   graphics.beginFill(0x00ff00);
   graphics.drawCircle(0, 0, 30);
   graphics.endFill();
  }
  
 }

}
And the final result:








No comments :

Post a Comment