OpenFeint is a service that enables your iPhone/iPod Touch application the ability to provide online score tracking. The service is free and can easily be incorporated into your applications. This tutorial will cover the integration of OpenFeint 2.4.3 with the Cocos2D-iPhone framework. Before getting started, it is assumed that you already have familiarity with:
* Objective-C
* XCode
* Cocos2D-iPhone framework
The expectation is that you already have a working Cocos2D based application to which you’d like to enable leaderboard functionality. If you’re new to Cocos2D-iPhone, then you should visit http://www.cocos2d-iphone.org to review the available documentation and download the latest framework. You do not have to be a seasoned veteran to use Cocos2D, and the framework makes it very easy to create high quality games. At the time of this writing, version 8.2 of the Cocos2D-iPhone framework was the most stable version, and hence it provides the basis for this tutorial.
There are several features available within OpenFeint in terms of score and event management. Beyond just tracking high scores, the developer can establish goals such that the player can earn achievements or even initiate online challenges. For this tutorial, the focus will be to simply enable an online leaderboard. The player will be able to track their own progress as well as compare their scores against other players via a global leaderboard.
There is also the ability to enable a chat function between players. While I have not tried it, I have been told by other developers that by enabling this feature you’re required to assign a mature rating. The mentality is that unrestricted chat within a game could expose minors to unscrupulous users and content.
Access to the OpenFeint code is done through the OpenFeint developer portal, and there is no charge to enroll in the developer program. Visit http://www.openfeint.com/ to sign-up for access.
Once authenticated with the portal, you’ll have access to the developer home page and will be able to download the OpenFeint SDK.
When enabling an application to use the OpenFeint service, you register it within the developer portal. Selecting the green plus button at the top of the page allows you to start this process. In this example we’ll add a test application, My Crazy App, so that you can see the various screens. Yet, the specific code examples shown later on will reflect the integration process with one of my OpenFeint enabled games.
After selecting submit, the application is given a Client Application ID, Product Key, and Product Secret. As we’ll later see, these values are needed when initializing OpenFeint within our application. Keep them handy as we’ll need them when it comes time to add the respective OpenFeint code to the application.
Create your leaderboards from Leaderboard link in OpenFeint Left side menu.
Now that we’ve enrolled in the OpenFeint program, downloaded the SDK, and created an entry for our application, it is time to start the integrating process within our Cocos2D-iPhone application.
There are some preliminary steps before inclusion of code within your class files. If you’re upgrading from a prior version, the process is relatively straight forward. You simply delete the old OpenFeint folder from your XCode project and need to ensure that you add some additional frameworks, which will be detailed in the following section. Note: it is also important that you go into your project’s directory and also delete both the OpenFeint and build directories.
Let’s review the the OpenFeint README.txt for information on integration of the application.
If you’ve downloaded and extracted the OpenFeint SDK, you’re ready to begin the process. For step 4 of the README file, we’re to drop the unzipped OpenFeint folder into our XCode project. And since the game is landscape only, we’ll remove the Portrait folder found under the Resources directory as suggested for step 5. The following shows the inclusion of the OpenFeint folder within our XCode project.
Continuing on with Step 6, we right click on our project icon within XCode and select Get Info. In looking at the build tab, we added the Linker Flags the value -ObjC as well as selected ‘Call C++ Default Ctors/Dtors in Objective-C’. These are shown in the following screen capture.
For step 7, the README.txt notes the following frameworks that must be included within the project. And if you’re like me, I can never remember the all too convenient path so here it is for reference. Right click on frameworks and add existing framework. Navigate to:
/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulatorx.y.z.sdk/System/Library/Frameworks/
Here are the frameworks you’ll need to ensure you’ve included in your XCode project.
* Foundation
* UIKit
* CoreGraphics
* QuartzCore
* Security
* SystemConfiguration
* libsql3.0.dylib (located in (iPhoneSDK Folder)/usr/lib/)
* CFNetwork
* CoreLocation
* MapKit (if building with SDK 3.0 or newer)
And here we see the frameworks that have been added to the XCode project.
For the latest release of OpenFeint, if you have set your ‘iPhoneOS Deployment Target’ to any version before 3.0 you must weak link some libraries. Select ‘Targets’ in the Groups & Files pane.
* Right click your target and select Get Info.
* Select the ‘General’ tab.
* Under ‘Linked Libraries’ change the following libraries from ‘Required’ to ‘Weak’
* UIKit
* MapKit
For my project I’m not building for lesser versions, which from what I’ve heard though does exclude a sizable base of users.
Finally, in step 9 of the README.txt, we need to add the following line to our prefix header:
#import "OpenFeintPrefix.pch"
At this point we now have the SDK integrated within our XCode project along with some necessary support requirements. Again, this tutorial covers the specific integration of OpenFeint with a Cocs2D-iPhone v8.2 based application. As with most application architectures, there will be various class files such as the application delegate, game scene, and menu scene.
Let’s now add the required OpenFeint code to our project’s AppDelegate.
Within the AppDelegate’s main file we’ll add various code elements ranging from importing other class headers to specific code needed within existing methods. For example, there’s specific OpenFeint code that should be added to applicationWillResignActive, applicationDidBecomeActive, and applicationWillTerminate. These methods can already be found in your Cocos2D application delegate, and we’ll be adding a line here or there to support integration with OpenFeint. The OpenFeint developer documentation details these requirements as it’s expected that you’re taking action based upon the application’s state, such as it shutting down.
Add the following import statements to your AppDelegate’s main file:
#import "OpenFeint.h"
#import "MyOFDelegate.h"
Now locate the respective methods within your AppDelegate’s main file, and add the lines identified for OpenFeint.
- (void)applicationWillResignActive:(UIApplication *)application {
[[SimpleAudioEngine sharedEngine] stopBackgroundMusic];
[[Director sharedDirector] pause];
[OpenFeint applicationWillResignActive]; // Add for OpenFeint
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
[[Director sharedDirector] resume];
[OpenFeint applicationDidBecomeActive]; // Add for OpenFeint
}
- (void)applicationWillTerminate:(UIApplication *)application {
[[SimpleAudioEngine sharedEngine] stopBackgroundMusic];
[[Director sharedDirector] end];
[[NSUserDefaults standardUserDefaults] synchronize]; // Add for OpenFeint
}
Next we’ll create a class that will handle some crucial tasks whenever we call the OpenFeint leaderboard. At the time, I had based this on the included MyOFDelegate files. Pay particular attention to the dashboardDidAppear and dashboardDidDisappear methods. You’ll see that we’re momentarily pausing the Cocos2D director and then re-enabling it once the dashboard disappears. This is a critical step cause otherwise it’s possible that input will be inconsistent or even not captured when the dashboard is displayed. But by pausing the director, we’re ensured that all user input is captured by the dashboard.
Create the following files within your XCode project.
MyOFDelegate.h
//
// MyOFDelegate.h
// MyGame
//
#import "OpenFeintDelegate.h"
@interface MyOFDelegate : NSObject<>
- (void)dashboardWillAppear;
- (void)dashboardDidAppear;
- (void)dashboardWillDisappear;
- (void)dashboardDidDisappear;
- (void)userLoggedIn:(NSString*)userId;
- (BOOL)showCustomOpenFeintApprovalScreen;
@end
MyOFDelegate.m
// MyOFDelegate.m
#import "OpenFeint.h"
#import "MyOFDelegate.h"
#import "cocos2d.h"
@implementation MyOFDelegate
- (void)dashboardWillAppear
{
}
- (void)dashboardDidAppear
{
[[Director sharedDirector] pause];
[[Director sharedDirector] stopAnimation];
}
- (void)dashboardWillDisappear
{
}
- (void)dashboardDidDisappear
{
[[Director sharedDirector] resume];
[[Director sharedDirector] startAnimation];
}
- (void)userLoggedIn:(NSString*)userId
{
OFLog(@"New user logged in! Hello %@", [OpenFeint lastLoggedInUserName]);
}
- (BOOL)showCustomOpenFeintApprovalScreen
{
return NO;
}
@end
For my particular Cocos2D application, I have a splash scene that quickly shows the company logo, the Cocos2D logo, and then transitions to the game’s main menu. I initialize OpenFeint during this process just before loading the main menu. With that said, the header file for the splash scene class has the following code. We’re including the MyOFDelegate class as well as declaring the ofDelegate variable. I’ve streamlined the content to only include the references to the OpenFeint code. I’ve left the reference to the menuScene method though as that’s where I perform the initialization.
// SplashScene.h
// Balloon-Boy
//
// Created by Tim Sills on 12/1/09.
//
#import
#import "cocos2d.h"
@class MyOFDelegate; // Add for OpenFeint
@interface SplashScene : Scene {
MyOFDelegate *ofDelegate; // Add for OpenFeint
}
-(void)menuScene;
@end
For the main file of the splash scene class, we import the following header files:
#import "OpenFeint.h"
#import "MyOFDelegate.h"
For the initialization process, we declare a dictionary that will include the details specific to our application. Where ever it is you want to perform the initialization within your application, add the following code.
NSDictionary* settings = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithInt:UIInterfaceOrientationLandscapeRight], OpenFeintSettingDashboardOrientation, [NSNumber numberWithBool:YES],
OpenFeintSettingDisableUserGeneratedContent, nil];
ofDelegate = [MyOFDelegate new];
OFDelegatesContainer* delegates = [OFDelegatesContainer containerWithOpenFeintDelegate:ofDelegate];
[OpenFeint initializeWithProductKey:@"aMMPDEYldUia4j86uV1mK"
andSecret:@"PMjb1n9dV4MVO09U05R56MUCeJf7VZHnKlQIvRKtn"
andDisplayName:@"My Game"
andSettings:settings // see OpenFeintSettings.h
andDelegates:delegates]; // see OFDelegatesContainer.h
For my particular application, once the initialization has been done, it then transitions to the main menu. If you’re already a registered user you’ll get the welcome back screen or if you’re a new user (or perhaps using a new device), you’ll have the opportunity to either login or register for a new account.
When a user selects the Scores option at the main menu, the following line of of code is executed within the called method. Take note of the text passed text value. This is the lD for our leaderboard that was assigned at the time of creation, which in this case is reflecting the value for the test application registered for this tutorial.
[OpenFeint launchDashboardWithHighscorePage:(NSString*)@"124567"];
The code is pretty self explanatory and launches the high score dashboard for our application. You also have the option of defaulting to other screens when initially launching the OpenFeint dashboard, so be sure to check the SDK for such details.
This all sounds great, but the next question is how do we post these scores to OpenFeint? The process is incredibly simple. For my Balloon-Boy game, after the user’s piloted balloon has had three impacts, the game is over. At this point I give the player the opportunity to play again, but when this method is initially called, I execute the following bit of code to post the user’s score. In particular, I have a variable named currentScore that contains the user’s accumulated score. The currentScore’s value is posted to the OpenFeint leaderboard. It is also important to note the leaderboard ID again. This is the same value given to us when we first created the leaderboard in the developer portal. The leaderboard details are provided again for reference in the following screen capture.
The leaderboard ID is used to identify the specific board for the application that’ll receive the value. The following shows the single line of code used to post the current score to the appropriate leaderboard for our application.
[OFHighScoreService setHighScore:currentScore forLeaderboard:@"124567 " onSuccess:OFDelegate() onFailure:OFDelegate()];The following screen capture shows in my application where the user is presented with the opportunity to either play again or return to the main menu. When this overlay is initially shown, there is a brief confirmation message shown at the bottom of the screen as the score is posted to the OpenFeint leaderboard.
The integration process is nearly complete with only some minor additional changes required. In order to compile the OpenFeint C code, we have to change the extension all of our main class files from .m to .mm. Meaning, gameScene.m now becomes gameScene.mm. There’s no impact to the existing Objetive-C code, but if not done then there will be a lot of problems when attempting to compile the code otherwise.
If you like this article please bookmark us. We will come soon with new article which helps you to develop your games in iPhone.
No comments:
Post a Comment