iTouchBalls
===========
Jordi Fita <jfita@geishastudios.com>
:comments:


Introduction
------------

'iTouchBalls' is an http://developer.apple.com/devcenter/ios/index.action[iOS]
port of http://www.geishastudios.com/literate/balls.html[Balls!], a very simple
puzzle game in which the player must remove an specific number of bouncing
balls from the screen by starting a chain reaction of explosions.  In this
port, instead of using the mouse, the player must tap on the screen to start
the first explosion and trigger the chain reaction.

Being an iOS application, 'iTouchBalls' is written in Objective-C.


Download
--------

There is no precompiled version of 'iTouchBalls' available because I highly
doubt that Apple would allow this game in his
http://www.apple.com/iphone/apps-for-iphone/[App Store].  However, the source
code, extracted with
http://www.geishastudios.com/literate/atangle.html[atangle], and an
http://developer.apple.com/technologies/tools/xcode.html[Xcode] project file
are available at the following URL:

http://www.geishastudios.com/download/balls-ios.zip

Also, for those interesed in this port's original
http://www.methods.co.nz/asciidoc/[AsciiDoc] document, the latest version is
always available at:

http://dev.geishastudios.com/literate/src/tip/balls-ios/


:leveloffset: 1
include::code.txt[]
Code
====

The View
--------

Even tough Apple recommends to separate the application in three different
responsibilities using a Model-View-Controller (MVC) pattern, I've decided to
put everything in a single `UIView` derived class which I named `BallsView`.

[source, Objective-C]
----
<<BallsView.h>>=
//
// iTouchBalls - A simple game with balls.
// Copyright (c) 2011 Jordi Fita <jfita@geishastudios.com>
//
<<license>>
//
#import <UIKit/UIKit.h>

@interface BallsView: UIView {
    <<BallsView interface>>
}

@end
----

[source, Objective-C]
----
<<BallsView.m>>=
//
// iTouchBalls - A simple game with balls.
// Copyright (c) 2011 Jordi Fita <jfita@geishastudios.com>
//
<<license>>
//
<<BallsView includes>>
#import "BallsView.h"
#import "Ball.h"
#import "Explosion.h"
#import "Level.h"

@implementation BallsView

<<view constructor>>

<<update function>>

<<draw function>>

<<tap function>>

- (void)dealloc {
    <<release main loop>>
    <<release BallsView interface>>
    [super dealloc];
}

@end
----

This class must be initialized by calling the `UIView` inherited
`initWithFrame` function and passing the frame with the view's size.

[source, Objective-C]
----
<<create view>>=
BallsView *view = [[BallsView alloc] initWithFrame:frame];
----

This method, besides calling its parent's method and initialize the object's
interface, sets the view's background color as well as the application's main
loop which will update the game's logic and force a redraw of the view.

[source, Objective-C]
----
<<view constructor>>=
- (id)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        <<init BallsView interface>>
        self.backgroundColor = [UIColor colorWithRed:42.0f / 255.0f green:84.0f / 255.0f blue:128.0f / 255.0f alpha:1.0f];
        <<set up main loop>>
    }
    return self;
}
----

Once the view is created, I can set it to the application's window to make the
view visible.  The function that I am using to set the view, `setContentView`,
is not documented and, in fact, XCode will complain that `UIWindow` might not
respond to this message.  The method exists and I use it because I remember
using it from regular OS X development.  Unfortunately, I wasn't able to set
the view using any other method.

[source, Objective-C]
----
<<set view in window>>=
[window setContentView:view];
----


Main Loop
---------

Differing from traditional imperative applications, an iOS application does not
have the common even loop in which the application can check for incoming
events and act upon them.  This is all handled by the `UIApplicationMain`
function, among other initialization and set up routines.  Unfortunately, for
games, this means that I no longer have the option to add the calls to the
methods that update the game's internal logic each frame in that loop.
Instead, I need to find a way to call my update function periodically.  This is
where `NSTimer` comes to help me.

With `NSTimer` I can schedule a call to a function of my choice at some point
in the future and this call will be repeated until the timer gets invalidated.
Given that I want to update the game's logic at an speed of 15 frames per
second, I need to call the update function every 66 milliseconds (1000 / 15.)

[source, Objective-C]
----
<<set up main loop>>=
mainLoop =
    [NSTimer scheduledTimerWithTimeInterval:0.066f
                                     target:self
                                   selector:@selector(update)
                                   userInfo:nil
                                    repeats:YES];
----

The `mainLoop` variable is defined in the `BallsView` class and released when
the class is deallocated.

[source, Objective-C]
----
<<BallsView interface>>=
NSTimer *mainLoop;
----

[source, Objective-C]
----
<<release main loop>>=
[mainLoop release];
----

The function referenced in the `selector` parameter is the function that will
be called repeatedly every 0.066 seconds.  This function's responsibility is to
update the balls and the explosions in the game as well as to check whether the
game is done.  Once these are updated, I trigger a redraw by telling iOS that
the view needs to display again.

[source, Objective-C]
----
<<update function>>=
- (void)update {
    <<update balls>>
    <<check if there is any explosion>>
    <<update explosions>>
    <<check whether level is over>>
    [self setNeedsDisplay];
}
----

The drawing is performed in `drawRect:`.  Here I need to get the current
graphic's context and then simply draw the balls, the explosions, and the
status text onto this context, if there is any ball on the level.  If there are
no balls yet, I need to tell the player to tap the screen to start the level.

[source, Objective-C]
----
<<draw function>>=
- (void)drawRect:(CGRect)rect {
    CGContextRef context = UIGraphicsGetCurrentContext();
    if ([balls count] == 0) {
        <<draw next level label>>
    } else {
        <<draw balls>>
        <<draw explosions>>
        <<draw status>>
    }
    CGContextStrokePath(context);
}
----

To draw the label, I am going to use `NSString` `drawAtPoint:withFont` which
prints the text at the given point on the current context -- the one I've got
when called `UIGraphisGetCurrentContext` -- with the specified font.  As I want
this text to be drawn at the view's center, fist I need to compute the position
where to draw the text.  Fortunately, `NSString` also has the `sizeWithFont:`
function that returns the rendered string's size if it were drawn using the
passed font.  Knowing the text's size as well as the view's size, the position
on there to start drawing is half the view' size less half the text size, in
both vertical and horizontal.

[source, Objective-C]
----
<<draw next level label>>=
CGRect viewRect = [self bounds];
UIFont *font = [UIFont boldSystemFontOfSize:20.0];
CGSize size = [nextLevelLabel sizeWithFont:font];
CGPoint pos = CGPointMake(viewRect.origin.x + (viewRect.size.width - size.width) / 2,
                          viewRect.origin.y + (viewRect.size.height - size.height) / 2);
[[UIColor whiteColor] set];
[nextLevelLabel drawAtPoint:pos withFont:font];
----

The next level label is just an string which prompts the user to tap on the
screen to start the level.

[source, Objective-C]
----
<<BallsView interface>>=
NSString *nextLevelLabel;
----

[source, Objective-C]
----
<<init BallsView interface>>=
nextLevelLabel = @"Tap to Start Next Level";
----


Status Text
-----------

The status text is an string with the number of balls removed from the level
and the target balls to remove.  I need to get the current level and the
remaining balls on the screen to know the number of removed balls, that I can
get with a simple subtraction.

[source, Objective-C]
----
<<draw status>>=
Level *level = [levels objectAtIndex:currentLevel];
int removedBalls = level.balls - [balls count];
NSString *status = [NSString stringWithFormat:@"%d/%d", removedBalls, level.target];
----

This string needs to be drawn at the screen's bottom right corner.  Again, I am
using `NSString` `sizeWithFont:` to know the area used by the text with the
intended font but this time I have to subtract the whole text's size from the
view's size to render the text at the bottom's right corner.

[source, Objective-C]
----
<<draw status>>=
CGRect viewRect = [self bounds];
UIFont *font = [UIFont systemFontOfSize:15.0];
CGSize size = [status sizeWithFont:font];
CGPoint pos = CGPointMake(viewRect.origin.x + viewRect.size.width - size.width,
                          viewRect.origin.y + viewRect.size.height - size.height);
[[UIColor whiteColor] set];
[status drawAtPoint:pos withFont:font];
----


Levels
------

The levels only requires two pieces of information: the number of balls
bouncing on the screen and the minimum number of balls to remove, known as
target.  These two never change during the lifetime of a level and thus can be
set read-only.

[source, Objective-C]
----
<<Level.h>>=
//
// iTouchBalls - A simple game with balls
// Copyright (c) 2011 Jordi Fita
//
<<license>>
//
#import <Foundation/Foundation.h>

@interface Level: NSObject {
    unsigned int balls;
    unsigned int target;
}

@property (readonly) unsigned int balls;
@property (readonly) unsigned int target;

----

These two values are initialized in the Level's `initWithBalls:target:`
method.

[source, Objective-C]
----
<<Level.h>>=
- (id)initWithBalls:(unsigned int)balls target:(unsigned int)target;
----

[source, Objective-C]
----
<<Level.m>>=
//
// iTouchBalls - A simple game with balls.
// Copyright (c) 2011 Jordi Fita
//
<<license>>
//
#import "Level.h"

@implementation Level

@synthesize balls;
@synthesize target;

- (id)initWithBalls:(unsigned int)balls_ target:(unsigned int)target_ {
    self = [super init];
    if (self) {
        balls = balls_;
        target = target_;
    }

    return self;
}

----

The levels are initialized by the `BallsView` when created and they are stored
in an `NSArray` object.  I also keep a variable to know in which level the game
is currently.  This variable is initially set to the first level, which is `0`.

[source, Objective-C]
----
<<BallsView interface>>=
NSArray *levels;
unsigned int currentLevel;
----

For convenience, I am going to add a class method to `Level` that creates the
level and calls `autorelease` on it, thus freeing me to have to keep the
references and releasing them when adding them to the array.

[source, Objective-C]
----
<<Level.h>>=
+ (id)levelWithBalls:(unsigned int)balls target:(unsigned int)target;

@end
----

[source, Objective-C]
----
<<Level.m>>=
+ (id)levelWithBalls:(unsigned int)balls target:(unsigned int)target {
    Level *level = [[Level alloc] initWithBalls:balls target:target];
    return [level autorelease];
}

@end
----

With this method in place, now I can create the levels thus:

[source, Objective-C]
----
<<init BallsView interface>>=
levels = [[NSArray alloc] initWithObjects:
    [Level levelWithBalls:4 target:1],
    [Level levelWithBalls:4 target:2],
    [Level levelWithBalls:8 target:4],
    [Level levelWithBalls:15 target:7],
    [Level levelWithBalls:25 target:12],
    [Level levelWithBalls:30 target:17],
    [Level levelWithBalls:30 target:20],
    [Level levelWithBalls:30 target:25],
    [Level levelWithBalls:30 target:28],
    [Level levelWithBalls:30 target:30],
    nil];
currentLevel = 0;
----

The array must be released when the `BallsView` is done.

[source, Objective-C]
----
<<release BallsViews interface>>=
[levels release];
----


Balls
-----

The balls in this game are just circles that bounce around the screen.  Thus,
they need a position, a direction, a radius and a color.  But, to make it
easier to draw onto a Quartz context, I am going to store the balls as the
rectangle that encloses the circle, the direction it is moving, and its color.

[source, Objective-C]
----
<<Ball.h>>=
//
// iTouchBalls - A simple game with balls.
// Copyright (c) 2011 Jordi Fita <jfita@geishastudios.com>
//
<<license>>
//
#import <UIKit/UIKit.h>

@interface Ball: NSObject {
    UIColor *color;
    CGPoint dir;
    CGRect rect;
}

<<Ball constructor declaration>>
<<Ball draw declaration>>
<<Ball update declaration>>

@property (nonatomic, retain) UIColor *color;
@property (nonatomic) CGPoint dir;
@property (nonatomic) CGRect rect;
<<Ball radius property declaration>>
<<Ball position property declaration>>

@end
----

[source, Objective-C]
----
<<Ball.m>>=
//
// iTouchBalls - A simple game with balls.
// Copyright (c) 2011 Jordi Fita <jfita@geishastudios.com>
//
<<license>>
//
#import "Ball.h"

@implementation Ball

@synthesize color;
@synthesize dir;
@synthesize rect;

<<Ball constructor>>

<<Ball draw>>

<<Ball update>>

<<Ball radius property>>

<<Ball position property>>

- (void)dealloc {
    [color release];
    [super dealloc];
}

@end
----

Ball's constructor expects a point, a radius and a color but then constructs
the rectangle centered at the given point.  The initial direction is towards
the screen's top-left corner.

[source, Objective-C]
----
<<Ball constructor declaration>>=
- (id)initWithPosition:(CGPoint)pos radius:(CGFloat)radius color:(UIColor *)color;
----

[source, Objective-C]
----
<<Ball constructor>>=
- (id)initWithPosition:(CGPoint)pos radius:(CGFloat)radius color:(UIColor *)ballColor {
    self = [super init];
    if (self) {
        [ballColor retain];
        self.color = ballColor;
        self.dir = CGPointMake(-1.0f, -1.0f);
        self.rect = CGRectMake(pos.x - radius, pos.y - radius, radius * 2, radius * 2);
    }
    return self;
}
----

I do this because then drawing the ball to a context is just a matter to pass
the appropriate attributes to the functions.

[source, Objective-C]
----
<<Ball draw declaration>>=
- (void)drawToContext:(CGContextRef)context;
----

[source, Objective-C]
----
<<Ball draw>>=
- (void)drawToContext:(CGContextRef)context {
    CGContextSetFillColorWithColor(context, self.color.CGColor);
    CGContextFillEllipseInRect(context, self.rect);
}
----

Thus drawing all the balls is a matter of calling this function with the
context to draw on.

[source, Objective-C]
----
<<draw balls>>=
for (Ball *ball in balls) {
    [ball drawToContext:context];
}
----

Although this approach makes updating the balls a little more complicated
because now, besides updating the current position according to the direction,
I have to find the rectangle's center position in order to know whether to
change the direction when the ball must bounce around the screen's limits,
which are passed as a parameter when updating.

Given that I'll use the balls position later to know whether the balls collides
with an explosion, I think it is better to put this center position in a
`position` property of `Ball`.  This property returns the Ball's enclosing
rectangle's origin point but with an offset equal to the ball's radius.

[source, Objective-C]
----
<<Ball position property declaration>>=
@property (nonatomic, readonly) CGPoint position;
----

[source, Objective-C]
----
<<Ball position property>>=
- (CGPoint)position {
    return CGPointMake(self.rect.origin.x + self.radius,
                       self.rect.origin.y + self.radius);
}
----

The ball's radius is also a property, for the same reason as the position, and
can also be extracted from the ball's rectangle, knowing that both the
rectangle's width and height -- they are the same value -- are the ball's
diameter, the radius is half either of these values.

[source, Objective-C]
----
<<Explosion radius property declaration>>=
@property (nonatomic, readonly) CGFloat radius;
----

[source, Objective-C]
----
<<Explosion radius property>>=
- (CGFloat)radius {
    return self.rect.size.width / 2;
}
----

With these two properties, it is now easy to write the function that updates
the ball's position.

[source, Objective-C]
----
<<Ball update declaration>>=
- (void)updateWithBounds:(CGRect)bounds;
----

[source, Objective-C]
----
<<Ball update>>=
- (void)updateWithBounds:(CGRect)bounds {
    self.rect = CGRectMake(
        self.rect.origin.x + self.dir.x,
        self.rect.origin.y + self.dir.y,
        self.rect.size.width, self.rect.size.height);

    CGPoint center = self.position;
    if (center.x < bounds.origin.x) {
        self.dir = CGPointMake(1.0f, self.dir.y);
    } else if (center.x >= bounds.origin.x + bounds.size.width) {
        self.dir = CGPointMake(-1.0f, self.dir.y);
    }
    if (center.y < bounds.origin.y) {
        self.dir = CGPointMake(self.dir.x, 1.0f);
    } else if (center.y >= bounds.origin.y + bounds.size.height) {
        self.dir = CGPointMake(self.dir.x, -1.0f);
    }
}
----

Calling the update function is as easy as drawing, but instead of passing the
context, I need to pass the view's bounds rectangle to keep the balls within
the view.

[source, Objective-C]
----
<<update balls>>=
CGRect bounds = [self bounds];
for (Ball *ball in balls) {
    [ball updateWithBounds:bounds];
}
----

`balls`, both when drawing and when updating, is an object of type
`NSMutableArray` owned by `BallsViews` and thus is created when initializing
`BallsView`.

[source, Objective-C]
----
<<BallsView interface>>=
NSMutableArray *balls;
----

[source, Objective-C]
----
<<init BallsView interface>>=
balls = [[NSMutableArray alloc] init];
----

Of course, since `BallsView` has ownership of this object, it is also
responsible of releasing it.

[source, Objective-C]
----
<<release BallsView interface>>=
[balls release];
----


Explosions
----------

Like the balls, the explosions in `iTouchBalls` are simple circles.  But,
unlike the balls, instead of moving around the screen they change their radius
in such a way to mimic an explosion's blast.  Like I did for the balls, I am
going to store the explosions as the rectangle that encloses the explosion and
its color.  The explosion has also a 'growth rate' which is the speed in which
the explosion grows or shrinks.

[source, Objective-C]
----
<<Explosion.h>>=
//
// iTouchBalls - A simple game with balls.
// Copyright (c) 2011 Jordi Fita <jfita@geishastudios.com>
//
<<license>>
//
#import <UIKit/UIKit.h>

@class Ball;

@interface Explosion: NSObject {
    UIColor *color;
    CGFloat growthRate;
    CGRect rect;
};

<<Explosion constructor declaration>>
<<Explosion draw declaration>>
<<Explosion update declaration>>
<<Explosion collides declaration>>

@property (nonatomic, retain) UIColor *color;
@property (nonatomic) CGFloat growthRate;
@property (nonatomic) CGRect rect;
<<Explosion radius property declaration>>

@end
----

[source, Objective-C]
----
<<Explosion.m>>=
//
// iTouchBalls - A simple game with balls.
// Copyright (c) 2011 Jordi Fita <jfita@geishastudios.com>
//
<<license>>
//
#import "Explosion.h"
#import "Ball.h"

@implementation Explosion

@synthesize color;
@synthesize growthRate;
@synthesize rect;

<<Explosion constructor>>

<<Explosion draw>>

<<Explosion update>>

<<Explosion collides>>

<<Explosion radius property>>

- (void)dealloc {
    [color release];
    [super dealloc];
}

@end
----

Explosion's constructor expects a position, a radius, and a color but then
constructs the rectangle centered at the specified point.  The initial growth
ratio is set to 1 pixel per each update.

[source, Objective-C]
----
<<Explosion constructor declaration>>=
- (id)initWithPosition:(CGPoint)pos radius:(CGFloat)radius color:(UIColor *)color;
----

[source, Objective-C]
----
<<Explosion constructor>>=
- (id)initWithPosition:(CGPoint)pos radius:(CGFloat)radius color:(UIColor *)explosionColor {
    self = [super init];
    if (self) {
        [explosionColor retain];
        self.color = explosionColor;
        self.growthRate = 1.0f;
        self.rect = CGRectMake(pos.x - radius, pos.y - radius, radius * 2, radius * 2);
    }
    return self;
}
----

This rectangle centered around the explosion renders the drawing of said
explosion dead simple, just like I did with the balls.

[source, Objective-C]
----
<<Explosion draw declaration>>=
- (void)drawToContext:(CGContextRef)context;
----

[source, Objective-C]
----
<<Explosion draw>>=
- (void)drawToContext:(CGContextRef)context {
    CGContextSetFillColorWithColor(context, self.color.CGColor);
    CGContextFillEllipseInRect(context, self.rect);
}
----

Calling this function for all explosions and passing the view's context draws
them all on the screen.

[source, Objective-C]
----
<<draw explosions>>=
for (Explosion *explosion in explosions) {
    [explosion drawToContext:context];
}
----

But updating the rectangle is now a little more involved than just updating the
radius property.  Now I have to grow or shrink the explosion's rectangle around
the center.  Given that the growth rate is exactly how many pixels the radius
grow each update, I only have to move the rectangle's position *away* from the
center by that amount while, at the same time, I make the rectangle bigger by
*double* that amount, because the rectangle's size represents the diameter, not
the radius.  Of course, if the growth is negative (i.e., shrinking) then the
operation is reversed, but this happens automatically because the growth rate's
variable is negative.

Another thing to take into account when updating the explosions is that they
grow until a certain limit.  This limit is passed as a parameter to the update
function, but this limit is the maximum radius, which is half the rectangle's
width or height.  When this limit is reached, then the explosion starts to
shrink until the ball's diagonal is 0.

[source, Objective-C]
----
<<Explosion update declaration>>=
- (void)updateWithMaxRadius:(CGFloat)radius;
----

[source, Objective-C]
----
<<Explosion update>>=
- (void)updateWithMaxRadius:(CGFloat)maxRadius {
    if (self.radius > 0) {
        self.rect = CGRectMake(
            self.rect.origin.x - self.growthRate,
            self.rect.origin.y - self.growthRate,
            self.rect.size.width + self.growthRate * 2,
            self.rect.size.height + self.growthRate * 2);

        if (self.radius / 2 > maxRadius) {
            self.growthRate = -1;
        }
    }
}
----

To make the code a little easier to understand, I've added a new property to
`Explosion` which hides the details of how I need to extract the radius from
the explosion's rectangle.

[source, Objective-C]
----
<<Ball radius property declaration>>=
@property (nonatomic, readonly) CGFloat radius;
----

[source, Objective-C]
----
<<Ball radius property>>=
- (CGFloat)radius {
    return self.rect.size.width / 2;
}
----

Although the idea behind Explosion's `updateWithMaxRadius:` is the same as the
ball's `updateWithBounds:`, traversing and updating the explosions is not as
straightforward as with the balls.  The main difference is that besides calling
the update function, I have to check whether the explosions collide with a ball
or not.  I also have to make sure that explosions no longer valid (i.e., its
radius reached 0) get removed from the game.

[source, Objective-C]
----
<<update explosions>>=
for (int explosionIndex = 0 ; explosionIndex < [explosions count] ; ++explosionIndex) {
    Explosion *explosion = [explosions objectAtIndex:explosionIndex];
    [explosion updateWithMaxRadius:30.0f];
    <<check whether to remove explosion>>
    <<otherwise check whether explosion collides with balls>>
}
----

The check whether the explosion must be removed, I need to know its radius.  If
the radius reached 0, then the explosion is no longer valid and must be removed
from the array.  I also need to subtract one from the explosion's index or I
would skip the next explosion, because removing the explosion moves all
posterior explosions one position to the beginning of the array.

[source, Objective-C]
----
<<check whether to remove explosion>>=
if (explosion.radius <= 0) {
    [explosions removeObjectAtIndex:explosionIndex];
    --explosionIndex;
}
----

If the explosion is still active (i.e., its radius is greater than 0) then I
need to check whether collides with any of the balls on the screen.  If the
explosion is colliding with a ball, that ball is replaced with a new explosion
at the same position and with the same color as the colliding ball.  The new
explosion is added at the array's beginning in order to be draw 'under' older
explosions.  This is because I am drawing the explosions from the first index
to the last.  If the drawing for-loop was done in reverse, then putting the
explosion at the array's end would be enough, and it could even improve the
application's performance.

[source, Objective-C]
----
<<otherwise check whether explosion collides with balls>>=
else {
    for (int ballIndex = 0 ; ballIndex < [balls count] ; ++ballIndex) {
        Ball *ball = [balls objectAtIndex:ballIndex];
        if ([explosion collidesWithBall:ball]) {
            Explosion *newExplosion =
                [[Explosion alloc] initWithPosition:ball.position
                                             radius:ball.radius
                                              color:ball.color];
            [explosions insertObject:newExplosion atIndex:0];
            [newExplosion release];
            [balls removeObjectAtIndex:ballIndex];
            --ballIndex;
        }
    }
}
----

Knowing that both the explosion and the ball are circles, I can compute the
euclidean distance between the two to check whether they are colliding or not.
If the distance is less than the sum of their radius, then the explosion and
the ball are colliding.  To avoid the square root in computing the euclidean
distance, instead of the actual distance, which I do not require, I am going to
check whether the 'squared' distance is less than the 'squared' sum of their
radii.

[source, Objective-C]
----
<<Explosion collides declaration>>=
- (BOOL)collidesWithBall:(Ball *)ball;
----

[source, Objective-C]
----
<<Explosion collides>>=
- (BOOL)collidesWithBall:(Ball *)ball {
    CGFloat maxDistance = (self.radius + ball.radius) * (self.radius + ball.radius);
    CGPoint center = CGPointMake(self.rect.origin.x + self.radius,
                                 self.rect.origin.y + self.radius);
    CGPoint ballCenter = ball.position;
    return ((center.x - ballCenter.x) * (center.x - ballCenter.x) +
            (center.y - ballCenter.y) * (center.y - ballCenter.y)) < maxDistance;
}
----

The only last thing to check for is whether the level is done or not.  The
level is done when the last explosion is fired and destroyed.  This happens
when the there was any explosion before the last update and then there is not
more explosion left.  Since the player can only start a single explosion per
level, if there is no longer an explosion available, then I can assume there is
nothing else to do.

[source, Objective-C]
----
<<check if there is any explosion>>=
BOOL anyExplosionLeft = [explosions count] > 0;
----

[source, Objective-C]
----
<<check whether level is over>>=
if (anyExplosionLeft && [explosions count] == 0) {
----

To end the level, the only thing I have to do is remove all the balls from
their array.  But before that, I need to check if we reached the level's target
amount of balls to remove.  With the number of balls still left and the number
of balls that there were initially, I can readily find out whether the level is
completed or not.  If it is, then move to the next level, if there are more
levels.

[source, Objective-C]
----
<<check whether level is over>>=
    Level *level = [levels objectAtIndex:currentLevel];
    if (level.balls - [balls count] >= level.target) {
        nextLevelLabel = @"Tap to Start Next Level";
        if (currentLevel < [levels count] - 1) {
            ++currentLevel;
        }
    } else {
        nextLevelLabel = @"Oops.  Try Again!";
    }
    [balls removeAllObjects];
}
----

`explosions`, like `balls` above, is an object of class `NSMutableArray` owned
by `BallsView` and created with it.

[source, Objective-C]
----
<<BallsView interface>>=
NSMutableArray *explosions;
----

[source, Objective-C]
----
<<init BallsView interface>>=
explosions = [[NSMutableArray alloc] init];
----

As `BallsView` has ownership of this object, it is also responsible to release
them.

[source, Objective-C]
----
<<release BallsView interface>>=
[explosions release];
----


Tap, Tap, Tapping
-----------------

Now that I have most of the pieces in place, I need to be able to start the
game by tapping on the screen.

When starting, the game waits for the player to tap the screen before creating
the balls for the current level.  I know when the player tapped the screen
because `BallsView` receives the `touchesEnded:withEvent` message from the
underlaying system.  I've chosen `touchesEnded:withEvent` instead of
`touchesBegan:withEvent` because I am going to use the same message to create
the explosions and I want a way to rectify, as it were, the explosion's initial
position if I did choose the wrong spot.

[source, Objective-C]
----
<<tap function>>=
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
    <<create balls if level has not already started>>
    <<otherwise create explosion if no explosion exists>>
}
----

In this message I thus need to know whether the level has already started.  I
can easily know that by looking at the number of elements inside the `balls`
array.  If this array is empty, the level hasn't started yet and I must start
the game by creating as many balls as dictated by the current level.

[source, Objective-C]
----
<<create balls if level has not already started>>=
if ([balls count] == 0) {
    <<get current level>>
    <<create levels balls>>
}
----

Given that the view's `currentLevel` property is always within the array's
bounds, the current level object can be retrieved from the array using this
property as the index.

[source, Objective-C]
----
<<get current level>>=
Level *level = [levels objectAtIndex:currentLevel];
----

Using this object, I can get the number of balls to create for the current
level using a for loop.  The balls are created at a random position inside the
view's bounds and each has a random color.

[source, Objective-C]
----
<<create levels balls>>=
NSArray *colors = [[NSArray alloc] initWithObjects:
    [UIColor redColor],
    [UIColor greenColor],
    [UIColor blueColor],
    [UIColor cyanColor],
    [UIColor yellowColor],
    [UIColor magentaColor],
    nil];
CGRect bounds = [self bounds];
for (unsigned int currentBall = 0 ; currentBall < level.balls ; ++currentBall) {
    CGPoint position =
        CGPointMake(bounds.origin.x + arc4random() % (int)bounds.size.width,
                    bounds.origin.y + arc4random() % (int)bounds.size.height);
    UIColor *color = [colors objectAtIndex:(arc4random() % [colors count])];
    Ball *ball = [[Ball alloc] initWithPosition:position
                                         radius:4.0f
                                          color:color];
    [balls addObject:ball];
    [ball release];
}
[colors release];
----

The `arc4random()` is a function that returns a pseudo-random number between 0
and 2^32^-1 and doesn't require a seed value, unlike `rand()`.  Thus, it is
more convenient in this case, but I need to include the `stdlib` header where
it is declared.

[source, Objective-C]
----
<<BallsView includes>>=
#include <stdlib.h>
----

The explosion is easier to create than the balls.  The player can only create a
single explosion, hence I need to check whether there is already an explosion
in the level or not.  If there is none, then I create a 1 pixel explosion at
the position where the player tapped the screen.  I can't create a 0 pixel
explosion because when an explosion reaches 0 it gets removed from the level.

[source, Objective-C]
----
<<otherwise create explosion if no explosion exists>>=
else if ([explosions count] == 0) {
    UITouch *touch = [touches anyObject];
    Explosion *newExplosion =
        [[Explosion alloc] initWithPosition:[touch locationInView:self]
                                     radius: 1.0f
                                      color: [UIColor redColor]];
    [explosions addObject:newExplosion];
    [newExplosion release];
}
----


ifndef::doctype-book[]
[appendix]
endif::doctype-book[]
Main
----

The main file for an iOS application is really simple.  I only have to call
`UIApplicationMain` passing the arguments from the command line and telling
which is the application class.  As with most Objective-C applications, the
main function is wrapped inside an `NSAutoreleasePool` that manages the
application's memory allocation.

[source, Objective-C]
----
<<main.m>>=
//
// iTouchBalls - A simple game with balls.
// Copyright (c) 2011 Jordi Fita <jfita@geishastudios.com>
//
<<license>>
//
#import <UIKit/UIKit.h>

int main(int argc, char *argv[]) {
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    int retVal = UIApplicationMain(argc, argv, @"ITouchBalls", @"ITouchBalls");
    [pool release];

    return retVal;
}
----

The `ITouchBalls` class referenced in the call to `UIApplicationMain` is an
`UIApplication` class that is responsible to create and manage the
application's window.

[source, Objective-C]
----
<<ITouchBalls.h>>=
//
// iTouchBalls - A simple game with balls.
// Copyright (c) 2011 Jordi Fita <jfita@geishastudios.com>
//
<<license>>
//
#import <UIKit/UIKit.h>

@interface ITouchBalls: UIApplication {
    UIWindow *window;
}
@end
----

[source, Objective-C]
----
<<ITouchBalls.m>>=
//
// iTouchBalls - A simple game with balls.
// Copyright (c) 2011 Jordi Fita <jfita@geishastudios.com>
//
<<license>>
//
#import "ITouchBalls.h"
#import "BallsView.h"

@implementation ITouchBalls

<<create and set view>>

- (void)dealloc {
    [window dealloc];
    [super dealloc];
}
@end
----

The `ITouchBalls` class is not only responsible to allocate the window but also
its view, which is the class the actually manages the whole game's logic.  This
must be done inside the `applicationDidFinishLaunching:` function called by
`UIApplicationMain` when the application has done with the initialization
process.  This could be considered the “real” application's main.

[source, Objective-C]
----
<<create and set view>>=
- (void)applicationDidFinishLaunching:(UIApplication *)application {
----

The first thing I want to do in this function is to retrieve the device's
screen area because I am going to need the area later to create the window and
its view.

The screen area can be retrieved either using the function `bounds` or
`applicationFrame` of `UIScreen` applied to the `mainScreen`.  The difference
between the two functions is that `bounds` will give the total device's area
while `applicationFrame` returns the device's area minus the space occupied by
the status bar, if shown.  In this case, I want to make a full screen window,
thus I'm going to use `bounds`.

[source, Objective-C]
----
<<create and set view>>=
    CGRect frame = [[UIScreen mainScreen] bounds];
----

Now I can make the window and its view, assign the view to the window, mark
this window as the main window, and show it.

[source, Objective-C]
----
<<create and set view>>=
    <<create view>>
    window = [[UIWindow alloc] initWithFrame:frame];
    <<set view in window>>
    [window makeKeyAndVisible];
    [view release];
}
----


ifndef::doctype-book[]
[appendix]
endif::doctype-book[]
Prefix Header
-------------

A 'prefix header' is a header that the compiler automatically includes at the
top of each source file.  This header file is pre-compiled in order to speed up
the building time.  Thus, in this header I import all the other headers used by
an iOS application, but only if the source being compiled is actually an
Objective-C source file.

[source, Objective-C]
----
<<iTouchBalls_Prefix.pch>>=
//
// iTouchBalls - A simple game with balls.
// Copyright (c) 2011 Jordi Fita <jfita@geishastudios.com>
//
<<license>>
//
// Prefix header for all source files.
//
#ifdef __OBJC_
    #import <Foundation/Foundation.h>
    #import <UIKit/UIKit.h>
#endif
----


ifndef::doctype-book[]
[appendix]
endif::doctype-book[]
Plist File
----------

The plist file is an XML file placed inside the application's bundle that has
the essential information about the program.

[source, xml]
----
<<iTouchBalls-Info.plist>>=
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
    <dict>
        <<Bundle Settings>>
    </dict>
</plist>
----

This file is used by iOS to retrieve information about the application.  In
this case it know that that application was written in an English locale.

[source, xml]
----
<<Bundle Settings>>=
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
----

iOS needs to know which kind of binary this bundle is holding: an application,
a framework, a plug-in, etc.  This game is an application, thus I set its type
accordingly.

[source, xml]
----
<<Bundle Settings>>=
<key>CFBundlePackageType</key>
<string>APPL</string>
----

iOS also looks in this file the name of the bundle and the string to show to
the user.  In both cases, I use the same string set by Xcode when building the
application.

[source, xml]
----
<<Bundle Settings>>=
<key>CFBundleName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundleDisplayName</key>
<string>${PRODUCT_NAME}</string>
----

Along with the bundle's name, iOS also shows an icon.  In this case, though,
I'll use an empty icon's filename because I don't have any icon for this game.

[source, xml]
----
<<Bundle Settings>>=
<key>CFBundleIconFile</key>
<string></string>
----

The bundle needs to have an identifier that can be used by iOS to associate
file types to the application, or store the application's settings in the
appropriate place, among other things.  This identifier is a reverse DNS style
string where, generally, the first part is a developer's prefix -- usually the
developer's domain -- followed by the application's name.  The application name
must be http://www.ietf.org/rfc/rfc1034.txt[RFC-1034] compliant.

[source, xml]
----
<<Bundle Settings>>=
<key>CFBundleIdentifier</key>
<string>com.geishastudios.${PRODUCT_NAME:rfc1034identifier}</string>
----

In order to start the application, iOS must know the name of the executable to
run.  The executable can also be written by Xcode when building.

[source, xml]
----
<<Bundle Settings>>=
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
----

As a bundle can host an application for iOS or for regular Mac OS X, I need to
specify that this application requires iOS (formerly called IPhoneOS) to be
run.

[source, xml]
----
<<Bundle Settings>>=
<key>LSRequiresIPhoneOS</key>
<true/>
----

Finally, the bundle's plist needs some extra information that I don't have any
idea whatsoever what they mean.  I just keep the values I've found to every
other plist file.

[source, xml]
----
<<Bundle Settings>>=
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.0</string>
----

ifndef::doctype-book[]
[appendix]
endif::doctype-book[]
License
-------

This program is distributed under the terms of the GNU General Public License
(GPL) version 2.0 as follows:

[source, Objective-C]
----
<<license>>=
// This program is free software; you can redistribute is and/or modify
// it under the terms of the GNU General Public License version 2.0 as
// published by the Free Software Foundation.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 50 Temple Place, Suite 330, Boston, MA 02111-1307  USA
----
