[OpenFeint-cocos2d]整合教程

来源:互联网 发布:期货自动化交易软件 编辑:程序博客网 时间:2024/06/06 15:42

Integrating OpenFeint with Cocos2D-iPhone Applications

OpenFeint is a service that enables your iPhone/iPod Touchapplication the ability to provide online score tracking.  The serviceis free and can easily be incorporated into your applications.   Thistutorial will cover the integration of OpenFeint 2.4.3 with theCocos2D-iPhone framework.  Before getting started, it is assumed thatyou already have familiarity with:

  • Objective-C
  • XCode
  • Cocos2D-iPhone framework

The expectation is that you already have a working Cocos2D basedapplication 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 latestframework.  You do not have to be a seasoned veteran to use Cocos2D,and the framework makes it very easy to create high quality games.  Atthe time of this writing, version 8.2 of the Cocos2D-iPhone frameworkwas the most stable version, and hence it provides the basis for thistutorial.

There are several features available within OpenFeint in terms ofscore and event management.  Beyond just tracking high scores, thedeveloper can establish goals such that the player can earnachievements or even initiate online challenges.  For this tutorial,the focus will be to simply enable an online leaderboard.  The playerwill be able to track their own progress as well as compare theirscores against other players via a global leaderboard.

There is also the ability to enable a chat function betweenplayers.  While I have not tried it, I have been told by otherdevelopers that by enabling this feature you’re required to assign amature rating.  The mentality is that unrestricted chat within a gamecould expose minors to unscrupulous users and content.

Specifically, the OpenFeint capabilities consist of the following features:

Access to the OpenFeint code is done through the OpenFeint developerportal, 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 thedeveloper home page and will be able to download the OpenFeint SDK.

When enabling an application to use the OpenFeint service, youregister it within the developer portal. Selecting the green plusbutton at the top of the page allows you to start this process. In thisexample we’ll add a test application, My Crazy App, so that you can seethe various screens. Yet, the specific code examples shown later onwill reflect the integration process with one of my OpenFeint enabledgames, Balloon-Boy.

The following screen capture shows the entry of the application details to register the application.

After selecting submit, the application is given a ClientApplication ID, Product Key, and Product Secret. As we’ll later see,these values are needed when initializing OpenFeint within ourapplication. Keep them handy as we’ll need them when it comes time toadd the respective OpenFeint code to the application.

The following shows a closer look at the application’s specificproduct key and secret. They are unique for each registered applicationand are used to identify the specific application when communicatingwith the OpenFeint servers.

The following shows the creation of the game’s leaderboard. It’s astraight forward process initiated by selecting ‘Basic Features’ andthen Leaderboards.

After selecting submit, we see that our leaderboard has beencreated. It is important to note the leaderboard ID as we’ll need thisvalue later on when attempting to post user’s scores to the board. Thevalue identifies the specific leaderboard and is a required element forthe code that is executed when we initiate onlinescore updates.

Now that we’ve enrolled in the OpenFeint program, downloaded theSDK, and created an entry for our application, it is time to start theintegrating process within our Cocos2D-iPhone application.

There are some preliminary steps before inclusion of code withinyour class files.  If you’re upgrading from a prior version, theprocess is relatively straight forward.  You simply delete the oldOpenFeint folder from your XCode project and need to ensure that youadd some additional frameworks, which will be detailed in the followingsection.  Note: it is also important that you go into your project’sdirectory 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 readyto begin the process.  For step 4 of the README file, we’re to drop theunzipped OpenFeint folder into our XCode project. And since the game islandscape only, we’ll remove the Portrait folder found under theResources directory as suggested for step 5.  The following shows theinclusion of the OpenFeint folder within our XCode project.

Continuing on with Step 6, we right click on our project icon withinXCode and select Get Info. In looking at the build tab, we added theLinker Flags the value -ObjC as well as selected ‘Call C++ DefaultCtors/Dtors in Objective-C’. These are shown in the following screencapture.

For step 7, the README.txt notes the following frameworks that mustbe included within the project.  And if you’re like me, I can neverremember 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/<selectframework>

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 ‘iPhoneOSDeployment Target’ to any version before 3.0 you must weak link somelibraries.  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:

view source
print?
1#import "OpenFeintPrefix.pch"

The following screen capture shows the quick update of the project’s prefix header.

At this point we now have the SDK integrated within our XCodeproject along with some necessary support requirements.  Again, thistutorial covers the specific integration of OpenFeint with aCocs2D-iPhone v8.2 based application.  As with most applicationarchitectures, there will be various class files such as theapplication 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 elementsranging from importing other class headers to specific code neededwithin existing methods.  For example, there’s specific OpenFeint codethat should be added to applicationWillResignActive,applicationDidBecomeActive, and applicationWillTerminate.  Thesemethods can already be found in your Cocos2D application delegate, andwe’ll be adding a line here or there to support integration withOpenFeint.  The OpenFeint developer documentation details theserequirements as it’s expected that you’re taking action based upon theapplication’s state, such as it shutting down.

Add the following import statements to your AppDelegate’s main file:

view source
print?
1#import "OpenFeint.h"
2#import "SampleOFDelegate.h"

Now locate the respective methods within your AppDelegate’s main file, and add the lines identified for OpenFeint.

view source
print?
01- (void)applicationWillResignActive:(UIApplication *)application {
02[[SimpleAudioEngine sharedEngine] stopBackgroundMusic];
03[[Director sharedDirector] pause];
04[OpenFeint applicationWillResignActive]; // Add for OpenFeint
05}
06  
07- (void)applicationDidBecomeActive:(UIApplication *)application {
08[[Director sharedDirector] resume];
09[OpenFeint applicationDidBecomeActive]; // Add for OpenFeint
10}
11- (void)applicationWillTerminate:(UIApplication *)application {
12[[SimpleAudioEngine sharedEngine] stopBackgroundMusic];
13[[Director sharedDirector] end];
14[[NSUserDefaults standardUserDefaults] synchronize]; // Add for OpenFeint
15}

Next we’ll create a class that will handle some crucial taskswhenever we call the OpenFeint leaderboard. At the time, I had basedthis on the included SampleOFDelegate files. Pay particular attentionto the dashboardDidAppear and dashboardDidDisappear methods. You’ll seethat we’re momentarily pausing the Cocos2D director and thenre-enabling it once the dashboard disappears. This is a critical stepcause otherwise it’s possible that input will be inconsistent or evennot captured when the dashboard is displayed. But by pausing thedirector, we’re ensured that all user input is captured by thedashboard.

Create the following files within your XCode project.

SampleOFDelegate.h

view source
print?
01//
02//  SampleOFDelegate.h
03//  Balloon-Boy
04//
05//  Created by Tim Sills on 12/4/09.
06//
07#import "OpenFeintDelegate.h"
08@interface SampleOFDelegate : NSObject< OpenFeintDelegate >
09- (void)dashboardWillAppear;
10- (void)dashboardDidAppear;
11- (void)dashboardWillDisappear;
12- (void)dashboardDidDisappear;
13- (void)userLoggedIn:(NSString*)userId;
14- (BOOL)showCustomOpenFeintApprovalScreen;
15@end

SampleOFDelegate.m

view source
print?
01//  SampleOFDelegate.m
02//  Balloon-Boy
03//
04//  Created by Tim Sills on 12/4/09.
05//
06#import "OpenFeint.h"
07#import "SampleOFDelegate.h"
08#import "cocos2d.h"
09@implementation SampleOFDelegate
10  
11- (void)dashboardWillAppear
12{
13}
14  
15- (void)dashboardDidAppear
16{
17[[Director sharedDirector] pause];
18[[Director sharedDirector] stopAnimation];
19}
20  
21- (void)dashboardWillDisappear
22{
23}
24  
25- (void)dashboardDidDisappear
26{
27[[Director sharedDirector] resume];
28[[Director sharedDirector] startAnimation];
29}
30  
31- (void)userLoggedIn:(NSString*)userId
32{
33OFLog(@"New user logged in! Hello %@", [OpenFeint lastLoggedInUserName]);
34}
35  
36- (BOOL)showCustomOpenFeintApprovalScreen
37{
38return NO;
39}
40  
41@end

For my particular Cocos2D application, I have a splash scene thatquickly shows the company logo, the Cocos2D logo, and then transitionsto the game’s main menu. I initialize OpenFeint during this processjust before loading the main menu. With that said, the header file forthe splash scene class has the following code. We’re including theSampleOFDelegate class as well as declaring the ofDelegate variable.I’ve streamlined the content to only include the references to theOpenFeint code. I’ve left the reference to the menuScene method thoughas that’s where I perform the initialization.

view source
print?
01//  SplashScene.h
02//  Balloon-Boy
03//
04//  Created by Tim Sills on 12/1/09.
05//
06#import <UIKit/UIKit.h>
07#import "cocos2d.h"
08@class SampleOFDelegate; // Add for OpenFeint
09@interface SplashScene : Scene {
10SampleOFDelegate *ofDelegate; // Add for OpenFeint
11}
12-(void)menuScene;
13@end

For the main file of the splash scene class, we import the following header files:

view source
print?
1#import "OpenFeint.h"
2#import "SampleOFDelegate.h"

Within my method that is called before transitioning to the mainmenu (menuScene), I initialize OpenFeint. It is here where we can setthe orientation, disable chat, and provide our application specificvalues such as the product key. You might recall that these wereprovided when first registering the application within OpenFeint’sdeveloper portal as shown in the following:

For the initialization process, we declare a dictionary that willinclude the details specific to our application. Where ever it is youwant to perform the initialization within your application, add thefollowing code.

view source
print?
1NSDictionary* settings =[NSDictionary dictionaryWithObjectsAndKeys:[NSNumbernumberWithInt:UIInterfaceOrientationLandscapeRight],OpenFeintSettingDashboardOrientation, [NSNumber numberWithBool:YES],
2OpenFeintSettingDisableUserGeneratedContent, nil];
3ofDelegate = [SampleOFDelegate new];
4OFDelegatesContainer* delegates = [OFDelegatesContainer containerWithOpenFeintDelegate:ofDelegate];
5[OpenFeint initializeWithProductKey:@"zGMPDEYldUia4j86uV1mA"
6andSecret:@"QMjb1n9dV4MVO09U05R56MUCeJf7VZHnKlQIvRKtk"
7andDisplayName:@"My Crazy App"
8andSettings:settings    // see OpenFeintSettings.h
9andDelegates:delegates]; // see OFDelegatesContainer.h

For my particular application, once the initialization has beendone, it then transitions to the main menu.  If you’re already aregistered user you’ll get the welcome back screen or if you’re a newuser (or perhaps using a new device), you’ll have the opportunity toeither login or register for a new account.

The following shows the OpenFeint screen that is seen when a newuser or device is detected.  The user can enable OpenFeint oralternatively indicate they don’t want these features right now.

Upon enabling OpenFeint, the application will recognize a devicealready associated with the user’s account and automatically log themin as shown in the following screen capture.

Additional features in the latest OpenFeint release now provide theability to connect with your Twitter and FaceBook accounts as well aseven share your location for geographic based scoring comparisons.

Once logged in, the user can easily review the scores for thevarious applications that use OpenFeint.  In this case, we’re going toreview the leaderboard for Balloon-Boy.  The following shows the layoutof my particular game’s main menu.

When a user selects the Scores option at the main menu, thefollowing line of of code is executed within the called method. Takenote of the text passed text value. This is the lD for our leaderboardthat was assigned at the time of creation, which in this case isreflecting the value for the test application registered for thistutorial.

view source
print?
1[OpenFeint launchDashboardWithHighscorePage:(NSString*)@"181963"];

The code is pretty self explanatory and launches the high scoredashboard for our application. You also have the option of defaultingto other screens when initially launching the OpenFeint dashboard, sobe sure to check the SDK for such details.

In the following screen capture, we see the various leaderboardstracked via OpenFeint.  You might recall that this is what was enabledduring the application registration process within OpenFeint’sdeveloper portal.  My application is very simplistic and simply tracksthe user’s personal score and a global score.  The following provides aview of the global leader board for the Balloon-Boy application.

As mentioned earlier, another neat feature available with the morerecent OpenFeint version is the ability to share your location toidentify other players in your general vicinity.

This all sounds great, but the next question is how do we post thesescores to OpenFeint?  The process is incredibly simple.  For myBalloon-Boy game, after the user’s piloted balloon has had threeimpacts, the game is over.  At this point I give the player theopportunity to play again, but when this method is initially called, Iexecute the following bit of code to post the user’s score.  Inparticular, I have a variable named currentScore that contains theuser’s accumulated score.  The currentScore’s value is posted to theOpenFeint leaderboard.  It is also important to note the leaderboard IDagain.  This is the same value given to us when we first created theleaderboard in the developer portal.  The leaderboard details areprovided again for reference in the following screen capture.

The leaderboard ID is used to identify the specific board for theapplication that’ll receive the value. The following shows the singleline of code used to post the current score to the appropriateleaderboard for our application.

view source
print?
1***************** 181963 is for the marathon leaderboard *************************
2[OFHighScoreService setHighScore:currentScore forLeaderboard:@"181963" onSuccess:OFDelegate() onFailure:OFDelegate()];

The following screen capture shows in my application where the useris presented with the opportunity to either play again or return to themain menu. When this overlay is initially shown, there is a briefconfirmation message shown at the bottom of the screen as the score isposted to the OpenFeint leaderboard. This is as a result of executingthe single line of code noted above.

The integration process is nearly complete with only some minoradditional 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 impactto the existing Objetive-C code, but if not done then there will be alot of problems when attempting to compile the code otherwise.

Lastly, if you’re using a physics engine such as Chipmunk, therewill also be errors at compile time due to the static void method. Inparticular, you’ll receive an error like request for member shape insomething not structure or union. This is an issue of simply needing tocast the shape data and is solved by adding (Sprite *) as shown in thefollowing.

view source
print?
01static void
02eachShape(void *ptr, void* unused)
03{
04cpShape *shape = (cpShape*) ptr;
05Sprite *sprite = (Sprite *)shape->data;
06if( sprite ) {
07cpBody *body = shape->body;
08[sprite setPosition: cpv( body->p.x, body->p.y)];
09[sprite setRotation: (float) CC_RADIANS_TO_DEGREES( -body->a )];
10 }
11}

This concludes the integration of OpenFeint with a Cocos2D-iPhoneapplication tutorial. Hopefully the process went smoothly and you’renow updating scores to an online leaderboard. Feel free to contact meregarding any feedback or content errors.  Also be sure to checkOpenFeint’s own knowledgebase and support forums for additionalinformation.