There are no active ads.

Introduction to iOS Development: Programming Pong (Part 4)

How do you develop apps for iOS? It’s a common question that many computer enthusiasts ask, and one we here at TechnoBuffalo hope to answer with this series of posts.

Learning how to develop software can be one of the most intimidating prospects for the average computer user, and with the growing saturation of applications in mobile marketplaces, it is becoming increasingly difficult to get your work noticed. That’s what this series is for, helping you learn iOS development from a conceptual perspective. No prior knowledge of computer programming will be necessary. Over the coming weeks, we’ll examine the iPhone’s ability to deliver immersive, intuitive content, a unique opportunity for both developers and consumers.

Today’s tutorial will be a continuation of last week’s lesson, recreating the classic game of Pong. When we parted last, we had finally found an efficient way to create our scoreboard. Now, we will finish our application by applying some game logic to our project.

1.  After opening up Apple’s integrated development environment (Xcode 4), head on over to the implementation file (PongViewController.m). This is where we define variables we created in the initialization, or header, file. Under the #import tag, you should place the following pieces of #define code. These clarify some of the rules of the game, such as the score that it takes to win and the ball’s speed.

——————————————————–

#define kGameStateRunning 1
#define kGameStatePaused  2

#define kBallSpeedX 3
#define kBallSpeedY 4

#define kComputerMoveSpeed 3.25
#define kScoreToWin 15

——————————————————–

2.  Scroll down to the touchesMoved method that we created earlier and place the cursor underneath it. We’ll now be adding the heart and soul of our game, defining many of the pseudo-variables we just created. We’re going to set up a timer to be constantly running through our code, but we’ll go into detail on that idea shortly. Here, we are setting up court bounds, computer’s action, and scoring logic.

——————————————————–

-(void) gameLoop {
if(gameState == kGameStateRunning) {

playerScoreText.hidden = YES;
computerScoreText.hidden = YES;

winOrLoseLabel.hidden = YES;

ball.center = CGPointMake(ball.center.x + ballVelocity.x , ball.center.y + ballVelocity.y);

if(ball.center.x > self.view.bounds.size.width || ball.center.x < 0) {
ballVelocity.x =- ballVelocity.x;
}

if(ball.center.y > self.view.bounds.size.height || ball.center.y < 0) {
ballVelocity.y =- ballVelocity.y;
}

if (CGRectIntersectsRect (ball.frame, playerPaddle.frame)) {
CGRect frame = ball.frame;
frame.origin.x = playerPaddle.frame.origin.x – frame.size.height;
ball.frame = frame;
ballVelocity.x =- ballVelocity.x;
}

if (CGRectIntersectsRect (ball.frame, computerPaddle.frame)) {
CGRect frame = ball.frame;
frame.origin.x = CGRectGetMaxX(computerPaddle.frame);
ball.frame = frame;
ballVelocity.x =- ballVelocity.x;
}

// Begin Simple AI
if(ball.center.x <= self.view.center.x) {
if(ball.center.y < computerPaddle.center.y) {
CGPoint compLocation = CGPointMake(computerPaddle.center.x, computerPaddle.center.y – kComputerMoveSpeed);
computerPaddle.center = compLocation;
}

if(ball.center.y > computerPaddle.center.y) {
CGPoint compLocation = CGPointMake(computerPaddle.center.x, computerPaddle.center.y + kComputerMoveSpeed);
computerPaddle.center = compLocation;
}
}

// Begin Scoring Game Logic
if(ball.center.x <= 0) {
playerScoreValue++;
[self reset:(playerScoreValue >= kScoreToWin)];
}

if(ball.center.x > self.view.bounds.size.width) {
computerScoreValue++;
[self reset:(computerScoreValue >= kScoreToWin)];
}
}
}

——————————————————–

3.  Now, we have to add code for restarting after one match is finished. To do this, we will add a method underneath the majority of our game logic. The following code will force the application to reset its logic and scoreboard, but this is only called if the value of the highest score matches our #define method.

——————————————————–

-(void)reset:(BOOL) newGame {
self.gameState = kGameStatePaused;

ball.center = CGPointMake(241, 159);

playerScoreText.hidden = NO;
computerScoreText.hidden = NO;

playerScoreText.text = [NSString stringWithFormat:@”%d”,playerScoreValue];
computerScoreText.text = [NSString stringWithFormat:@”%d”,computerScoreValue];

if(newGame) {
winOrLoseLabel.hidden = NO;

if(computerScoreValue > playerScoreValue) {
winOrLoseLabel.text = @”Game Over!”;
} else {
winOrLoseLabel.text = @”You Win!”;
}

computerScoreValue = 0;
playerScoreValue = 0;
}
}

——————————————————–

4. To prevent our game from launching as the application loads, we need to make sure that it launches in the state of being paused. Below is a method that will help us accomplish this.

——————————————————–

– (void)viewDidLoad {
[super viewDidLoad];

self.gameState = kGameStatePaused;
ballVelocity = CGPointMake(kBallSpeedX,kBallSpeedY);

[NSTimer scheduledTimerWithTimeInterval:0.01 target:self selector:@selector(gameLoop) userInfo:nil repeats:YES];

winOrLoseLabel.hidden = YES;

[winOrLoseLabel setFont:[UIFont fontWithName:@”kongtext” size:36]];

[playerScoreText setFont:[UIFont fontWithName:@”kongtext” size:36]];
[computerScoreText setFont:[UIFont fontWithName:@”kongtext” size:36]];
}

——————————————————–

5.  You have to manage your memory carefully, so we will make sure that we deallocate the storage that we used throughout this application at the end of the implementation file.

——————————————————–

– (void)dealloc {
[super dealloc];

[ball release];
[playerPaddle
[computerPaddle release];
[playerScoreText release];
[computerScoreText release];
[winOrLoseLabel release];
}

——————————————————–

6.  Next, we will need to create an additional label and add it to our application. After you finish adding the code below to the initialization file, head on over to Interface Builder and drag in a new label. Double-click on File’s Owner and move to the Connections pane. Here, you should drag from the variable we create to your newly created label. Note the fact that you do not necessarily need @property call-outs for NSIntegers.

——————————————————–

IBOutlet UILabel *winOrLoseLabel;

CGPoint ballVelocity;

NSInteger gameState;

NSInteger playerScoreValue;
NSInteger computerScoreValue;

@property(nonatomic,retain)  IBOutlet UILabel *winOrLoseLabel;

@property(nonatomic) CGPoint ballVelocity;

@property(nonatomic) NSInteger gameState;

-(void)reset:(BOOL) newGame;

@synthesize winOrLoseLabel,ballVelocity,gameState;

——————————————————–

7.  Head on over to the implementation file and @synthesize all of the variables we just created. It’s a minor detail and takes little effort, but the application will fail to run otherwise.

8.  We need to add one final piece of code. Move to our touchesMoved method that we created in our implementation file. Under the CGPoint line, write in the following code, which will start the game when the player touches the paddle.

——————————————————–

self.gameState = kGameStateRunning;

——————————————————–

9.  You have successfully completed your first full-featured iOS game! Pat yourself on the back. Build your application and run it on your machine, show it off to friends, and brag about your amazing programming skills.

Questions?

If you have any questions about the topics discussed in this lesson, feel free to voice them in the comments below. We will do our best to ensure that you have a relatively painless experience developing for iOS. Stay tuned for the next installment of this series, which is released weekly.

To read previous installments from this series, check the links below.


Advertisement