Augmented Reality Tutorial for iOS
An augmented reality tutorial for iOS. By Nicholas Waynik.
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
Augmented Reality Tutorial for iOS
30 mins
Gratuitous Lasers and Explosions!
So far our augmented reality game is coming along really well, except there’s one major problem: those darn spaceships are getting away scott free!
Obviously we can’t have that, so let’s add some awesome lasers and explosions.
Before we start, let’s get rid of the labels that are on the screen – those were just there for debugging purposes. So search through HelloWorldLayer.m and comment out all matches for yawLabel and posIn360Label. Once you’re done, compile and run and make sure everything still works ok.
Now for the fun part - let’s add some firepower to the game! First we will add a method to check if the player’s firing area hits a space ship. Inside the HelloWorldLayer.h file add the following line of code before @end.
- (BOOL) circle:(CGPoint) circlePoint withRadius:(float) radius collisionWithCircle:(CGPoint) circlePointTwo collisionCircleRadius:(float) radiusTwo;
Moving on to the HelloWorldLayer.m add the method above the dealloc.
- (BOOL) circle:(CGPoint) circlePoint withRadius:(float) radius collisionWithCircle:(CGPoint) circlePointTwo collisionCircleRadius:(float) radiusTwo {
float xdif = circlePoint.x - circlePointTwo.x;
float ydif = circlePoint.y - circlePointTwo.y;
float distance = sqrt(xdif*xdif+ydif*ydif);
if(distance <= radius+radiusTwo) return YES;
return NO;
}
This method is used to check if the radii of two points overlap. The input parameters are for the position of the enemy spaceship and the center of the screen. The radii for both points are set to 50.
First we find the difference between the two points for both x and y. Next we calculate the distance. You may remember this calculation from your studies, it’s called the Pythagorean Theorem. You can read more about this here.
Next we will add a scope to the screen so we can see where our firepower be aimed at. Download the resources for this project, unzip the file, and drag scope.png into your project under the Resources folder. Make sure the “Copy items into destination group’s folder” is checked then click Finish.
Find the init method in HelloWorldLayer.m and add the following code to setup that sprite just before [self scheduleUpdate];
// Add the scope crosshairs
CCSprite *scope = [CCSprite spriteWithFile:@"scope.png"];
scope.position = ccp(240, 160);
[self addChild:scope z:15];
// Allow touches with the layer
[self registerWithTouchDispatcher];
If you run the app now, you will see the scope crosshairs in the center of the screen.
Great, now let’s add some explosions when the player taps the screen. We will follow the same steps to add Explosion.plist as we did for scope.png. From the resources for the project that you downloaded earlier, drag Explosion.plist into the Resources folder in Xcode, make sure the “Copy items into destination group’s folder” is checked, and click Finish.
You may be wondering what this file is. I used an awesome program to create it, which you may have heard of. It is called Particle Designer, from the good folks of 71 Squared. I will not cover how to create these files, but it is as easy as selecting a type of particle system, making adjustments, and exporting it to a plist.
Now, right before the dealloc method add the following code.
-(void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
CGPoint location = CGPointMake(240,160);
// 1
for (EnemyShip *enemyShip in enemySprites) {
if (enemyShip.timeToLive > 0) {
// Check to see if yaw position is in range
BOOL wasTouched = [self circle:location withRadius:50 collisionWithCircle:enemyShip.position collisionCircleRadius:50];
if (wasTouched) {
enemyShip.timeToLive = 0;
enemyShip.visible = false;
enemyCount -= 1;
}
}
}
// 2
CCParticleSystemQuad *particle = [CCParticleSystemQuad particleWithFile:@"Explosion.plist"];
particle.position = ccp(240,160);
[self addChild:particle z:20];
particle.autoRemoveOnFinish = YES;
// 3
if (enemyCount == 0) {
// Show end game
CGSize winSize = [CCDirector sharedDirector].winSize;
CCLabelBMFont *label = [CCLabelBMFont labelWithString:@"You win!" fntFile:@"Arial.fnt"];
label.scale = 2.0;
label.position = ccp(winSize.width/2, winSize.height/2);
[self addChild:label z:30];
}
}
The first section of this code uses the collision detection method we added earlier to check if a space ship is inside of the scope. If one of the space ships was shot, then we will set some properties on the ship to hide it and reduce the enemyCount variable by one. The second section adds the particle system explosion in the center of the screen. The third and final section checks to see if the enemyCount variable equals zero, and if it does, it displays a label to inform the player that the game is over.
The game is a little bit boring at this point in time, so let’s add some very basic AI to change up the position of the space ships after a certain amount of time. At the bottom of the update method add the following code.
// Loop through array of Space Ships and if the timeToLive is zero
// change the yawPosition of the sprite
for (EnemyShip *enemyShip in enemySprites) {
enemyShip.timeToLive--;
if (enemyShip.timeToLive == 0) {
int x = arc4random() % 360;
[enemyShip setPosition:ccp(5000, 160)];
enemyShip.yawPosition = x;
enemyShip.timeToLive = kTimeToLive;
}
}
This code will loop through the enemySprites array and update the timeToLive property. Then it will check to see if that property is equal to zero, if it is then it will assign the ship a different random yawPosition and reset the timeToLive. Go ahead and run the game. The game is now much harder to track those space ships down and shoot them!
Pump up the Volume!
Games without audio can seem very boring, so let’s spice things up!
At the top of HellowWorldLayer.m add the import statement for the Simple Audio Engine, which is included with Cocos2D.
#import "SimpleAudioEngine.h"
Scroll down the file and add the following code to the bottom of the init method just before the end of the if ((self=[super init])) statement.
[[SimpleAudioEngine sharedEngine] playBackgroundMusic:@"SpaceGame.caf" loop:YES];
[[SimpleAudioEngine sharedEngine] preloadEffect:@"explosion_large.caf"];
[[SimpleAudioEngine sharedEngine] preloadEffect:@"laser_ship.caf"];
This will load the background music and preload the effects.
Now, continue scrolling down the file and locate the ccTouchesBegan method. At the top of this method add the following line of code.
[[SimpleAudioEngine sharedEngine] playEffect:@"laser_ship.caf"];
This will play a laser sound effect when the user touches the screen.
Stay inside of the ccTouchesBegan method. In the enemyShip in enemySprites for loop, add the following line inside the (wasTouched) if statement.
[[SimpleAudioEngine sharedEngine] playEffect:@"explosion_large.caf"];
This will play the explosion sound effect when a ship is hit!
Compile and run your code, and enjoy your new tunes!