Chinaunix首页 | 论坛 | 博客
  • 博客访问: 5409825
  • 博文数量: 763
  • 博客积分: 12108
  • 博客等级: 上将
  • 技术积分: 15717
  • 用 户 组: 普通用户
  • 注册时间: 2007-09-28 21:21
个人简介

业精于勤,荒于嬉

文章分类

全部博文(763)

文章存档

2018年(6)

2017年(15)

2016年(2)

2015年(31)

2014年(14)

2013年(87)

2012年(75)

2011年(94)

2010年(190)

2009年(38)

2008年(183)

2007年(28)

分类:

2010-08-24 13:25:14


 

游戏也好,程序也好,随着用户的增加,难免会有需要增加一个在线排行的功能,这样的好处有很多,比较特别的有两点。
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) myInitOpenFeint   // 初始化函数
{

// 设置信息

NSDictionary* settings = [NSDictionary dictionaryWithObjectsAndKeys:

  [NSNumber numberWithInt:UIInterfaceOrientationPortrait (屏幕方向)], OpenFeintSettingDashboardOrientation,

  @"你的游戏名称", OpenFeintSettingShortDisplayName,

  [NSNumber numberWithBool:YES], OpenFeintSettingEnablePushNotifications,

  [NSNumber numberWithBool:NO], OpenFeintSettingDisableUserGeneratedContent,

    [NSNumber numberWithBool:NO], OpenFeintSettingAlwaysAskForApprovalInDebug,

  window, OpenFeintSettingPresentationWindow,

  nil

  ];

// 接口实现类

ofDelegate = [GameOFDelegate new];

ofNotificationDelegate = [GameOFNotificationDelegate new];

ofChallengeDelegate = [GameOFChallengeDelegate new];

OFDelegatesContainer* delegates = [OFDelegatesContainer containerWithOpenFeintDelegate:ofDelegate

  andChallengeDelegate:ofChallengeDelegate

  andNotificationDelegate:ofNotificationDelegate];   


    [OpenFeint initializeWithProductKey:@"
这里输入key
                              andSecret:@"
这里输入密钥"
                         andDisplayName:@"
Your game name"
                            andSettings:
settings    // see OpenFeintSettings.h
                           andDelegates:
delegates];              // see OFDelegatesContainer.h
}
注释:密钥 和  key网站注册帐号后,可在后台的到
代码中ofDelegate和ofChallengeDelegate两个代理分别对应于OF的启动以及challenge模式的启动。
这两个类的具体写法可以参考sample中的例子,我基本上照抄了。

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

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


// 提交成绩, @"排行榜id"  , 通过网站中 Leaderboards 页面,创建 一个 Leaderboards 生成


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


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

备注说明:

// 成就功能就象奖状一样, 一个游戏可以设置多个成就, 比如: 当分数大于 1000时,可以设置解锁 玩家的1000分成就(得到一个1000分的奖状),  当分数大于 2000时,可以设置解锁玩家的 2000分成就(得到一个2000分的奖状)

// 下面语句为,解锁某一个成就, @"571692" 为某个成就 id , 通过网站中 Achievements 页面,创建 一个 Achievements 生成的

[OFAchievementService unlockAchievement: @"571692" onSuccess: OFDelegate() onFailure: OFDelegate()];


以上两个都是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 !
阅读(2420) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~