用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 !
原帖地址 http://www.cocoachina.com/bbs/read.php?tid-15038.html
游戏也好,程序也好,随着用户的增加,难免会有需要增加一个在线排行的功能,这样的好处有很 多,比较特别的有两点。
1. 不用考虑虚拟键盘调用后进行的用户名输入,我就是觉得做个虚拟键盘输入名字做rank让我很崩溃所以才出此“下策”
2. 即时监控用户登录情况,随着每个用户的成绩提交,可以大致知道自己的游戏有多少用户。

注意,我这里说的 情况是在原生程序中使用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%
发表评论
本类文章点击排行榜
- [06-26] iPhone 开发过程中的一些小技术
- [03-16] 23个开源App的App Store地址和源
- [06-11] 比较官方iPhone SDK和开源工具链
- [06-11] 简单明了SDK2.2.1无99刀证书真机
- [06-12] iPhone开发, 全区索引, 动态更新
- [06-16] 如何嗅探iphone的网络流量
- [02-03] iPhone在线音乐盒,代码开源
- [06-11] iPhone GUI的PSD分层图
- [03-15] iPhone方块游戏拖动手势源码共
推荐内容
最近更新
- [07-12] 用 cocos2d 创建帧动画
- [07-09] Cocos2D 支持 iAd 的例子代码
- [07-08] 在 App 中充分利用 iPhone OS 3.2 的文件共享特性
- [07-06] UIView做各种动画的demo
- [07-05] 模拟器里 iAD 不显示测试广告的解决办法
- [07-02] 图片如何存入 iPhone 本地 Documents 的方法
- [07-02] UIImageWriteToSavedPhotosAlbum保存图片的方法
- [07-02] 不同版本sdk下针对不同iOS编译后的兼容情况汇总
- [07-02] 发布 iOS4 程序的 checklist(检查流程)


NSString+NSMutableString+NSValue+NSAraay用法汇总
制作iPhone的SOAP应用的详细教程
iPhone方块游戏拖动手势源码共享
用Openfeint为App添加在线排行功能
用Info.plist文件指定软件的运行设备