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
In this augmented reality tutorial you will learn how to make a simple augmented reality game for the iPhone/iPod touch!
In this game you will utilize the camera, gyroscope, and Cocos2d framework. Sounds exciting right?
It definitely was fun exploring these technologies while writing this article. There is a bit of math and conversions, but don’t worry – it’s nothing too hard!
To use this augmented reality tutorial, you need an iPhone 4 because the augmented reality tutorial uses the gyroscope to move your view of the world.
You also need to have at least basic knowledge of Cocos2D and have Cocos2D installed. If you are a complete beginner to Cocos2D, you should go through some of the other Cocos2D tutorials on this site first.
Are you ready to start blasting some virtual aliens? Let’s go!
Getting Started
Open Xcode and from the File menu select New\New Project. Next choose the iOS\cocos2d\cocos2d template, and click Next. Name the project ARSpaceships, click Next, choose a folder to save your project in, and click Create.
We will reuse some of the resources from the Space Shooter game, so download them and unzip the file.
Once you have the file downloaded, drag the the Fonts, Sounds, and Spritesheets folders into the Resources group inside your Xcode project. Make sure Copy items into destination group’s folder is checked and ARSpaceships target is checked, then click Finish. At this point your project should look like this:
We will use some of these items later on.
Roll the Camera!
If you run the app right now, it is pretty boring. A black screen with Hello World, who hasn’t seen this before! Let’s start turning this into something cool. Select the AppDelegate.h file and add a UIView to the interface.
UIView *overlay;
Now open the AppDelegate.m file. Scroll down to the EAGLView *glView line and change the pixelFormat to kEAGLColorFormatRGBA8. It will now look like this:
EAGLView *glView = [EAGLView viewWithFrame:[window bounds]
pixelFormat:kEAGLColorFormatRGBA8 depthFormat:0];
If you do not change the pixel format the image from the camera will not display. Since this in an augmented reality game, we don’t want that!
Below the [window addSubview: viewController.view]; line of code we will add the following lines of code:
// set the background color of the view
[CCDirector sharedDirector].openGLView.backgroundColor = [UIColor clearColor];
[CCDirector sharedDirector].openGLView.opaque = NO;
// set value for glClearColor
glClearColor(0.0, 0.0, 0.0, 0.0);
// prepare the overlay view and add it to the window
overlay = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
overlay.opaque = NO;
overlay.backgroundColor=[UIColor clearColor];
[window addSubview:overlay];
Here we are setting the background color of the openGLView to clear, setting the view not opaque, setting the glClearColor, and finally creating and adding a UIView named overlay which we will use for the camera.
Next add the following code below the code you just added.
#define CAMERA_TRANSFORM 1.24299
UIImagePickerController *uip;
@try {
uip = [[[UIImagePickerController alloc] init] autorelease];
uip.sourceType = UIImagePickerControllerSourceTypeCamera;
uip.showsCameraControls = NO;
uip.toolbarHidden = YES;
uip.navigationBarHidden = YES;
uip.wantsFullScreenLayout = YES;
uip.cameraViewTransform = CGAffineTransformScale(uip.cameraViewTransform,
CAMERA_TRANSFORM, CAMERA_TRANSFORM);
}
@catch (NSException * e) {
[uip release];
uip = nil;
}
@finally {
if(uip) {
[overlay addSubview:[uip view]];
[overlay release];
}
}
[window bringSubviewToFront:viewController.view];
First we define a constant for the scaling of the camera. The camera has an aspect ratio of 4:3 and the screen of the iPhone has an aspect ratio of 3:4, so we will need to scale the camera image to make up for this discrepancy.
Second, we are creating an UIImagePickerController, setting some properties so it is just the camera with no controls, scaling the UIImagePickerController, and then adding it to the overlay view.
Lastly we need to bring the viewController..view (which contains the Cocos2D display) to the front so it appears in front of the camera view.
At this point we can go ahead and Run the app. Once it loads you will see that the image coming from the camera is now your background with Hello World on top.
Shake, Rattle, and Roll…Well at Least Yaw!
Since we now have the reality portion of the app working, next we will focus on the tougher portion of this augmented reality tutorial.
First we need to add the CoreMotion framework to your project. Click on the project file, select the ARSpaceships target, select the Build Phases tab, then expand Link Binary With Libraries.
Click the + button, select CoreMotion.framework, then click the Add button. Now we are all set to start using the gyroscope in the project.
Open HelloWorldLayer.h and add the following import statements at the top of the file.
#include <CoreMotion/CoreMotion.h>
#import <CoreFoundation/CoreFoundation.h>
Inside the interface add the following variables.
CMMotionManager *motionManager;
CCLabelTTF *yawLabel;
CCLabelTTF *posIn360Label;
Add the property statement below the interface.
@property (nonatomic, retain) CMMotionManager *motionManager;
Now it is time to get into the meat and potatoes of this project. Open the HelloWorldLayer.m file. Inside the if ((self=[super init])) statement which is inside the init method, delete the current lines creating the “Hello World” label and add the following code to setup the new labels.
// add and position the labels
yawLabel = [CCLabelTTF labelWithString:@"Yaw: " fontName:@"Marker Felt" fontSize:12];
posIn360Label = [CCLabelTTF labelWithString:@"360Pos: " fontName:@"Marker Felt" fontSize:12];
yawLabel.position = ccp(50, 240);
posIn360Label.position = ccp(50, 300);
[self addChild: yawLabel];
[self addChild:posIn360Label];
Nothing fancy here, just adding some labels with a font and some text. The positions for the labels are all along the left hand side of the screen.
Next you need to setup the motion manager, which will start the gyroscope.
self.motionManager = [[[CMMotionManager alloc] init] autorelease];
motionManager.deviceMotionUpdateInterval = 1.0/60.0;
if (motionManager.isDeviceMotionAvailable) {
[motionManager startDeviceMotionUpdates];
}
[self scheduleUpdate];
Here we allocate and initialize the motion manager. We also set the update interval to sixty times per second. If the device has the gyroscope capabilities, then start the updates. Finally we schedule the update.
Make sure to add the synthesize statement at the top of this file.
@synthesize motionManager;
Since we have scheduled the update, we will need to add an update method. Add the following code below the init method.
-(void)update:(ccTime)delta {
CMDeviceMotion *currentDeviceMotion = motionManager.deviceMotion;
CMAttitude *currentAttitude = currentDeviceMotion.attitude;
// 1: Convert the radians yaw value to degrees then round up/down
float yaw = roundf((float)(CC_RADIANS_TO_DEGREES(currentAttitude.yaw)));
// 2: Convert the degrees value to float and use Math function to round the value
[yawLabel setString:[NSString stringWithFormat:@"Yaw: %.0f", yaw]];
// 3: Convert the yaw value to a value in the range of 0 to 360
int positionIn360 = yaw;
if (positionIn360 < 0) {
positionIn360 = 360 + positionIn360;
}
[posIn360Label setString:[NSString stringWithFormat:@"360Pos: %d", positionIn360]];
}
At this point you can Run the app. You will see the values for the Yaw and positionIn360 change in their respective labels.