Let It Blow Wide
Mini Game Tutorial > Let It Blow

The tank is ready to blow its enemies. Just Implement what are needed. Maybe some easy exploding animation amuses your kids.

In this chapter, you will learn how to:

  • check collisions between objects
  • draw an easy animation

Blow an enemy

To destroy enemies, a CannonBall object must know about these. Let's add the checkCollision method into the CannonBall class. This method takes an argument enemies so that it can check all positions of the enemies.

 def checkCollision(enemies)
   return if (!@active)
   return if (enemies.size == 0)
   return if (@target.y > @point.y + SIZE)

   width = enemies[0].size.width
   height = enemies[0].size.height
   enemies.each do |enemy|
     if (@point.x >= enemy.point.x - (width / 2) - SIZE && 
         @point.x <= enemy.point.x + (width + SIZE) / 2 &&
         @point.y >= enemy.point.y - (height / 2) - SIZE &&
         @point.y <= enemy.point.y + (height + SIZE ) / 2)
       enemy.destroy() 
       @exploding = true
     end
   end
 end

Let Them Get Animated

In the previous chapter, A cannon ball disappears immediately when it reaches its target point. In this chapter, you get it animated to show it's exploding.

Using alpha blend makes the animation simple and easy. Take a look at the move method.

 def move()
   if (!@exploding)
     @point.y += @speed
     @exploding = true if (@point.y > @target.y)
   else
     @opacity -= 0.1
     @active = false if (@opacity <= 0.0)
   end
 end

When @exploding is true, it changes @opacity from 1.0 to 0.0 by 0.1 on every timer event. when @opacity reaches 0.0, it changes @active to false so TankGameModel can remove this CannonBall object.

The next method to be modified is draw. This method checks if @exploding is true or not. If true, it draws an oval in red. The size of the oval is calculated with the value of @opacity.

 def draw()
   size = SIZE * (2.0 - @opacity)
   if (@active)
     if (!@exploding)
       NSColor.blueColor.set
     else
       NSColor.redColor.colorWithAlphaComponent(@opacity).set
     end
     point = NSPoint.new(@point.x - size / 2, @point.y - size / 2)
     rect = NSRect.new(point, NSSize.new(size, size))
     path = NSBezierPath.bezierPathWithOvalInRect(rect)
     path.fill
   end
 end

Oh, there is one more thing. Don't forget to initialize @opacity and @exploding. Add the following two lines at initialize.

@opacity = 1.0
@exploding = false 

Enemies Get Destroyed

Let's implement the Enemy.destroy method.

 def destroy()
   @exploding = true
 end

It's very simple. This @exploding is a flag to make an exploding animation at the draw method.

Let Enemies Get Animated

As same as CannonBall objects, using alpha blending is an easy way to make an animation. I think you don't have to have any explanation for this method.

 def move()
   if (!@exploding)
     diff = rand(@speed)
     @point.y -= diff if (@active)
   else
     @opacity -= 0.1
     @active = false if (@opacity <= 0.0)
   end
 end

For the draw method, you have to override the super classes method. Enemy.draw uses NSImage.dissolveToPoint instead of compositeToPoint.

 def draw()
   # use image() instead of @image in case @image is not initialized yet.
   point = NSPoint.new(@point.x - image().size.width / 2, 
                       @point.y - image().size.height / 2)
   @image.dissolveToPoint(point, :fraction, @opacity)
 end

Similar to CannonBall objects, you should not forget to add the two lines below to initialize.

@opacity = 1.0
@exploding = false

Update The World

Okay, CannonBalls and Enemies are ready to get animated. Only thing you do is update the TankGameModel to destroy enemies.

Here is the modified TankGameModel.tick method.

 def tick()
   @tank.tick()
   @borderline = Field.size.height / 3
   @cannons.each do |cannon|
     cannon.move()

     # updated - check collisions and blow enemies!
     cannon.checkCollision(@enemies)
     @cannons.delete(cannon) if (!cannon.active)
   end

   @enemies.each do |enemy|
     enemy.move()
     # updated - delete an enemy if it is not active
     @enemies.delete(enemy) if (!enemy.active)
     if (enemy.reached?(@borderline))
       init()
     end
   end

   # updated - initialize when there are no enemies.
   if (@enemies.size == 0)
     init()
   end
 end

Check It Out!

Here comes the fun time again. Run the game and check if cannonballs blow enemies. Does it look a little bit cheap? Ha-ha, don't blame me. It's just a sample game. I think you can modify it as you want now, can't you?

LetItBlow.jpg SIZE:800x622(?KB)

What we've created so far

LetItBlow.tar.gz SIZE:x(?KB) is the file that we made so far. Here are the steps to run the game.

  1. Untar the tar.gz file at the project folder
  2. Add a group named "TankGame" to the "Resources" group at the left pane of the Xcode project window. (if not exists)
  3. Right click the group and select "Add" -> "Existing Files" and add all the tiff files (if not added yet at the previous chapter)
  4. Run the application by pressing the "Build & Run" button

Let Them Move<Prev|Top:Mini Game Tutorial|Next>Let Them Fight

Leave a comment

Begin the comment with //pukiwiki if you want to write a comment in PukiWiki format.

You must be logged in to post a comment.