[OpenFeint-cocos2d]整合教程~稍后

Integrating OpenFeint with Cocos2D-iPhone Applications

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.

Specifically, the OpenFeint capabilities consist of the following features:

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, 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 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.

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

The following shows the creation of the game’s leaderboard. It’s a straight forward process initiated by selecting ‘Basic Features’ and then Leaderboards.

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

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/<select framework>

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:

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 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:

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.

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 tasks whenever we call the OpenFeint leaderboard. At the time, I had based this on the included SampleOFDelegate 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.

SampleOFDelegate.h

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

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 {
33 OFLog(@"New user logged in! Hello %@", [OpenFeint lastLoggedInUserName]);
34 }
35   
36 - (BOOL)showCustomOpenFeintApprovalScreen
37 {
38 return NO;
39 }
40   
41 @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 SampleOFDelegate 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.

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 {
10 SampleOFDelegate *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:

1 #import "OpenFeint.h"
2 #import "SampleOFDelegate.h"

Within my method that is called before transitioning to the main menu (menuScene), I initialize OpenFeint. It is here where we can set the orientation, disable chat, and provide our application specific values such as the product key. You might recall that these were provided when first registering the application within OpenFeint’s developer portal as shown in the following:

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.

1 NSDictionary* settings = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithInt:UIInterfaceOrientationLandscapeRight], OpenFeintSettingDashboardOrientation, [NSNumber numberWithBool:YES],
2 OpenFeintSettingDisableUserGeneratedContent, nil];
3 ofDelegate = [SampleOFDelegate new];
4 OFDelegatesContainer* delegates = [OFDelegatesContainer containerWithOpenFeintDelegate:ofDelegate];
5 [OpenFeint initializeWithProductKey:@"zGMPDEYldUia4j86uV1mA"
6 andSecret:@"QMjb1n9dV4MVO09U05R56MUCeJf7VZHnKlQIvRKtk"
7 andDisplayName:@"My Crazy App"
8 andSettings:settings    // see OpenFeintSettings.h
9 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.

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

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

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

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

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.

1 [OpenFeint launchDashboardWithHighscorePage:(NSString*)@"181963"];

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.

In the following screen capture, we see the various leaderboards tracked via OpenFeint.  You might recall that this is what was enabled during the application registration process within OpenFeint’s developer portal.  My application is very simplistic and simply tracks the user’s personal score and a global score.  The following provides a view of the global leader board for the Balloon-Boy application.

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

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.

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 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. This is as a result of executing the single line of code noted above.

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.

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

01 static void
02 eachShape(void *ptr, void* unused)
03 {
04 cpShape *shape = (cpShape*) ptr;
05 Sprite *sprite = (Sprite *)shape->data;
06 if( sprite ) {
07 cpBody *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-iPhone application tutorial. Hopefully the process went smoothly and you’re now updating scores to an online leaderboard. Feel free to contact me regarding any feedback or content errors.  Also be sure to check OpenFeint’s own knowledgebase and support forums for additional information.

trsills@pocketworx.com

posted @ 2010-02-24 11:17  AlexLiu  阅读(1726)  评论(1编辑  收藏  举报