iPhone Game Development - Chris Craft [103]
Constructing and initializing CALayer instances for the two paddles and the puck.
Loading images for the paddles and puck.
Loading a background image for our table.
Setting the initial position of the paddles and puck. The “actual” position of the paddles and puck are recorded in StateData structures bottomPaddleData and topPaddleData. This allows the application to easily grab this information and move it around. This is a requirement for our GKSession used in HockeyViewController.
Constructing a UILabel to display the score.
Preloading the UIImage objects goalImage, blueWinsImage, and redWinsImage. These images are used in the method displayMessage listed further down in Listing 7.2.
Listing 7.2
Initializing All of the Game Components
- (void)initializeContents {
self.multipleTouchEnabled = true;
CGImageRef puckImg = [[UIImage imageWithContentsOfFile:[[NSBundle mainBundle]
pathForResource:@”AmuckPuck” ofType:@”png”]] CGImage];
puckLayer = [CALayer layer];
puckLayer.frame = CGRectMake(0.0, 0.0, CGImageGetWidth(puckImg),
CGImageGetHeight(puckImg));
puckLayer.contents = (id)puckImg;
puckLayer.anchorPoint = CGPointMake(0.5, 0.5);
CGImageRef paddle1Img = [[UIImage imageWithContentsOfFile:[[NSBundle
mainBundle] pathForResource:@”RedPaddle” ofType:@”png”]] CGImage];
bottomPaddleLayer = [CALayer layer];
bottomPaddleLayer.frame = CGRectMake(0.0, 0.0, CGImageGetWidth(paddle1Img),
CGImageGetHeight(paddle1Img));
bottomPaddleLayer.contents = (id)paddle1Img;
bottomPaddleLayer.anchorPoint = CGPointMake(0.5, 0.57);
CGImageRef paddle2Img = [[UIImage imageWithContentsOfFile:[[NSBundle
mainBundle] pathForResource:@”BluePaddle” ofType:@”png”]] CGImage];
topPaddleLayer = [CALayer layer];
topPaddleLayer.frame = CGRectMake(0.0, 0.0, CGImageGetWidth(paddle2Img),
CGImageGetHeight(paddle2Img));
topPaddleLayer.contents = (id)paddle2Img;
topPaddleLayer.anchorPoint = CGPointMake(0.5, 0.57);
bottomPaddleData.paddleLocation = CGPointMake(160, 380);
topPaddleData.paddleLocation = CGPointMake(160, 100);
bottomPaddleData.puckLocation = CGPointMake(160, 250);
bottomPaddleData.puckVelocity = CGPointMake(0, 0);
// Set the background image
CGImageRef bgImg = [[UIImage imageWithContentsOfFile:[[NSBundle mainBundle]
pathForResource:@”stagebg” ofType:@”png”]] CGImage];
self.layer.contents = (id)bgImg;
// Add our sublayers
[self.layer insertSublayer:puckLayer above:self.layer];
[self.layer insertSublayer:bottomPaddleLayer above:self.layer];
[self.layer insertSublayer:topPaddleLayer above:self.layer];
// Prevent things from drawing outside our layer bounds
self.layer.masksToBounds = YES;
// add a label to display the score
scoreLabel = [[UILabel alloc] initWithFrame:CGRectMake(10.0, 10.0, 150.0,
25.0)];
scoreLabel.textColor = [UIColor whiteColor];
scoreLabel.backgroundColor = [UIColor clearColor];
scoreLabel.font = [UIFont fontWithName:@”Arial” size:18];
scoreLabel.alpha = 0.5;
[self addSubview:scoreLabel];
[self bringSubviewToFront:scoreLabel];
// load images for messages
goalImage = [UIImage imageNamed:@”Goal.png”];
blueWinsImage = [UIImage imageNamed:@”BlueWins.png”];
redWinsImage = [UIImage imageNamed:@”RedWins.png”];
}
Using Core Animation
Today it is fairly common for 2-D games to be powered by 3-D graphics. Graphics accelerators are equipped with powerful capabilities. They can blend, rotate, translate, and more without taxing the processor. Therefore, it makes more sense to use the 3-D accelerator to draw in 2-D than it does to try and manage the pixels by hand. In fact, all the views and animations we have used so far are built on top of an underlying 3-D engine.
Until now we have been using UIViews for all of our graphics needs. We could do the same for this game, but this is a great opportunity to pull back the layers a little and work directly with Core Animation. Core Animation is built directly on top of OpenGL ES, so we get the benefits of 3-D acceleration but without the full complexity of a 3-D environment.
If you have done game programming in the past, you may have used