当前位置:主页 > 开发频道 > iPhone开发 > 官方SDK >

用Openfeint为App添加在线排行功能

时间: 2010-02-21 15:28 点击:

游戏也好,程序也好,随着用户的增加,难免会有需要增加一个在线排行的功能。本文给出详细教程
作者  deadseafu

原帖地址  http://www.cocoachina.com/bbs/read.php?tid-15038.html

游戏也好,程序也好,随着用户的增加,难免会有需要增加一个在线排行的功能,这样的好处有很 多,比较特别的有两点。
1. 不用考虑虚拟键盘调用后进行的用户名输入,我就是觉得做个虚拟键盘输入名字做rank让我很崩溃所以才出此“下策”
2. 即时监控用户登录情况,随着每个用户的成绩提交,可以大致知道自己的游戏有多少用户。

目前我们的选择有两个,一个是plus+ ,本来我想用它,因为我觉得plus+这个logo和颜色跟我的游戏内容比较合,奈何落花有意流水无情,我申请完等了一个星期后被他否掉 ,在这样半被迫的情况下,我选择了openfeint,并且深深为它的功能所折服,不敢专美,与各位有需要的朋友分享。

注意,我这里说的 情况是在原生程序中使用openfeint,u3d的引擎的不在我的讨论之列。另外我是web程序员出身,很多描述也许不够专业和精确,请各位指出及海涵。

首先,在官网注册为开发者,建立一个项目,你会得到一个项目的client id(用于提问),一个产品编号跟一个密钥,这将放置于程序中,注意不要输错,我曾经因为少粘贴了一位密钥
结果载入程序界面老是报莫名的错误。后 来还是经过Fwish版主的提醒(他也曾经遇到一样的报错),才发现问题所在。
在官网下载SDK,察看它包里的readme,注意看 Building OpenFeint With Your Project 部分
一步一步照做,注意第九步 9. You must have a prefix header. It must have the following line: #import "OpenFeintPrefix.pch"
这个是加在 项目名_Prefix.pch这个文件的最后就可以了。
一般来说,编译出 4000多个错的话,多半是这里没加。另外要将所有#import到openfeint头文件的.m文件的扩展名通通改为.mm,以实现objectC和 C++的混合编译。

完成以上步骤后,可以尝试编译一下,能够顺利编译就没有问题了。

接下来要做的可以在 openfeint附带的sample里面看到,它的sample写得还是比较仔细的,不过它用的是UIKit和nib文件,所以开发游戏的还要根据自己 的引擎做一些修改。

首先,在"项目名AppDelegate.mm"的文件里加入openfeint的载入定义部分,以让其在每次程序 load完以后就起作用。
- (void) startup
{
    ofDelegate = [MyOFDelegate new];
    //ofNotificationDelegate = [SampleOFNotificationDelegate new];
    //ofChallengeDelegate = [SampleOFChallengeDelegate new];
    NSDictionary* settings = [NSDictionary dictionaryWithObjectsAndKeys:
                              [NSNumber numberWithInt: UIDeviceOrientationPortrait],
                              OpenFeintSettingDashboardOrientation,@"ArithMaster",
                              OpenFeintSettingShortDisplayName,  
                              [NSNumber numberWithBool:YES],
                              OpenFeintSettingEnablePushNotifications,
                              [NSNumber numberWithBool:NO],
                              OpenFeintSettingDisableUserGeneratedContent,nil];
    ofChallengeDelegate = [MyChallengeDelegate new];
    OFDelegatesContainer* delegates = [OFDelegatesContainer containerWithOpenFeintDelegate:ofDelegate
                                                                      andChallengeDelegate:ofChallengeDelegate
                                                                   andNotificationDelegate:nil];
    //OFDelegatesContainer* delegates = [OFDelegatesContainer containerWithOpenFeintDelegate:ofDelegate];
    [OpenFeint initializeWithProductKey:@"这里输入key"
                              andSecret:@" 这里输入密钥"
                         andDisplayName:@"Airthmetic Master"
                            andSettings:settings    // see OpenFeintSettings.h
                           andDelegates:delegates];              // see OFDelegatesContainer.h
}

代 码中ofDelegate和ofChallengeDelegate两个代理分别对应于OF的启动以及challenge模式的启动。
这两个类的 具体写法可以参考sample中的例子,我基本上照抄了。

这样做完以后,可以通过执行  [OpenFeint launchDashboard]来进入OF界面,官方文档中建议这个可以作为一个按钮的绑定方法来实现。

另外重要的文档就在开发者界面 里面指定功能里,点击问号会进入帮助界面,会告诉你功能相关头文件和基本的用法,注意调用方法的时候需要察看一下是否包含了带有该方法的头文件。

接 下来我说说怎么提交成绩,很简单,就一句 [OFHighScoreService setHighScore: score forLeaderboard:@"排行榜id" onSuccess:OFDelegate() onFailure:OFDelegate()];
这 个排行榜id是通过在leaderboard里面新建leaderboard取得的,在它的配置选项里可以选择成绩按照降序还是升序排列。一般都认为成绩 是降序的,其实也不其然,比如我的《算术大师》,时间越短排行越高,就要按照升序排列。

至于提交成就也就一句 [OFAchievementService unlockAchievement: @"成就id" onSuccess: OFDelegate() onFailure: OFDelegate()];
这些成就可以在任何条件判断后执行,比如我指定了一个成就在成绩低于12秒的时候触发,就 可以写 if(costsecond < 12) 触发成就 ,可以放心的是在你解锁了该成就以后,再次达到成就触发条件也不会重复触发成就。

以 上两个都是OF的基本功能,使用也相对简单,我接下来要说的是高级功能里面的challenge,我为这个折腾了两个晚上,苦于资料稀缺,无人可问,终于 攻克。
challenge就是挑战功能,我的理解是它其实是一种延时对战机制,用户A在完成了指定的游戏以后,可以将游戏过程数据和结果打包传输 到OF的服务器上,然后你的被挑战者从服务器上下载这些数据,以跟你同样的条件进行游戏,并且在最后跟你的游戏成绩比较,这样就完成了一次挑战的过程。大 家或许也想到了,在《算术大师》里,这种机制跟游戏的相性天然吻合,我的实现是把“被挑战者下载数据以后做完题目跟挑战者比较”这个过程当成两个西部牛仔 的对决,谁速度更快,谁就能够打落对方的帽子。OF的文档里提到,这个同样适用于赛车游戏的场合,挑战者的数据可以作为一辆幽灵车显示在被挑战者的画面 中,可以想见,被挑战者更加不允许犯错,所以还是能够增加游戏的乐趣和对抗程度的。

下面说说代码,首先是发送挑战,这个相对简单,直接上 代码吧
- (void)_sendChallenge
{
     ChallengeData  data;

    data.score = score; //给挑战数据赋值

    NSData* challengeData = [NSData dataWithBytes:(void const*)&data length:sizeof(ChallengeData)];  //这句对我来说比较深奥了,只有敬畏地照抄了


    [OFChallengeService
     displaySendChallengeModal:@"挑战编号"
     challengeText:[NSString stringWithFormat:@"my score is %d,come on!", score]
     challengeData:challengeData];
}



- (void)challenge:(id)sender{
    
    if ([OpenFeint hasUserApprovedFeint])
    {
        [self _sendChallenge];
    }
    else
    {
        OFDelegate nilDelegate;
        OFDelegate sendChallengeDelegate(self, @selector(_sendChallenge));
        [OpenFeint presentUserFeintApprovalModal:sendChallengeDelegate deniedDelegate:nilDelegate];
    }
}

千万注意!根据我的实测,挑战数据似乎是C++的变量比较不会出问题,我用 NSString,NSMutableString结果在打包上传,下载解包后变成了空值,我熬的两个晚上有一个多晚上都在搞这个,结果用了C++的数 组,立马就没事情了,所以,可能打包进去的数据需要类似这样的处理data.leftnum=[leftnum objectAtIndex:i] intValue];


challenge的delegate,主要是在这 个函数里处理
- (void)userLaunchedChallenge:(OFChallengeToUser*)challengeToLaunch withChallengeData:(NSData*)challengeData
前面一个参数里面有挑战的名称,用户等信息,后面一个 NSData里面则是完整的游戏过程数据。
这个只要按照sample里照做就可以了。设置完成后,用户在openfeint内接受挑战后将以这个 delegate为入口进行后续的游戏过程处理。

最后是挑战结果处理,一般就是写个方法判断输赢平,然后设置两个回调方法
        OFDelegate success(self, @selector(_submittedCompletedChallenge));    
        OFDelegate failure(self, @selector(_failedSubmittingCompletedChallenge));
        [OFChallengeService
         submitChallengeResult:challenge.resourceId
         result:challenge.result
         resultDescription:[NSString stringWithFormat:@"my score is %d,see you next time!", correctnum]
         onSuccess:success
         onFailure:failure];
我建议在 _submittedCompletedChallenge不要回传数据,似乎要按照传过来的数据的格式才行,否则会出错,而回传数据只有一种情况需要用 到:就是被挑战者反复尝试挑战挑战者。

challenge的适用大致就是如此了,不解的话,建议反复研究OF自带的sample,另外挑 战模式的测试需要用户注册两个帐户通过在OF的界面下切换来调试,当然,一模拟器一设备是最理想的。

有一些挑战相关的数据,都是可以从它 传给delegate的两个参数里取得的,比如我在游戏里设置了一个成就,就是在"little Cocoa"发出的挑战中打败little Cocoa,则能获得游戏中最大的一个成就:超越开发者,这就需要判断传过来的用户名,通过对OF的源码的研究,我以这样的方式取得了用户名: [challenge.challenge.challenger name] ,当时觉得自己很牛逼,哈哈。

以上大致就是我在使用 openfeint过程中的一点心得,如果有问题的话请向我提出,如果知道的话,我会尽量解答。
另外OF其实提供了很完备的社区功能,你可以在系 统里面发布公告,跟你的用户通过游戏内置的论坛进行交流,发pm给你的用户,这些原本需要复杂代码实现的功能都已经由其替你实现。所以确实能够让你的游戏 从一个单机游戏进入多人游戏的世界,从何在乐趣上进步一个台阶。
最后我用一句xbox的口号结束这个教程,这也被写在了我游戏的loading页 面:Game Experience may change during online play via openfeint !

顶一下(13)

100%

踩一下(0)

0%

发表评论

评价: 中立 好评 差评 请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。

表情:

论坛新帖 进入论坛...