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?
What we've created so far
is the file that we made so far. Here are the steps to run the game.
- Untar the tar.gz file at the project folder
- Add a group named "TankGame" to the "Resources" group at the left pane of the Xcode project window. (if not exists)
- Right click the group and select "Add" -> "Existing Files" and add all the tiff files (if not added yet at the previous chapter)
- Run the application by pressing the "Build & Run" button








