书接上文...
现把功能放上来,具体
使用的体会我会慢慢补充进来.
本部分内容适合需要自定义Game Center的程序,便于搭配自己
游戏整体的UI.如果懒得自己做Game Center,可以使用ViewController来做,这些,不在本文的范围内.具体要如何做,参看GKTapper例子.
4.总体功能
在使用各个功能前,你需要了解一下块函数.
传送门:
https://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/Blocks/Articles/00_Introduction.html
4.1 对Game Center支持判断
复制代码
- - (BOOL) isGameCenterAvailable
- {
- Class gcClass = (NSClassFromString(@"GKLocalPlayer"));
- NSString *reqSysVer = @"4.1";
- NSString *currSysVer = [[UIDevice currentDevice] systemVersion];
- BOOL osVersionSupported = ([currSysVer compare:reqSysVer options:NSNumericSearch] != NSOrderedAscending);
-
- return (gcClass && osVersionSupported);
- }
|
4.2用户登录
复制代码
- - (void) authenticateLocalPlayer
- {
- [[GKLocalPlayer localPlayer] authenticateWithCompletionHandler:^(NSError *error){
- if (error == nil) {
- //成功处理
- NSLog(@"成功");
- NSLog(@"1--alias--.%@",[GKLocalPlayer localPlayer].alias);
- NSLog(@"2--authenticated--.%d",[GKLocalPlayer localPlayer].authenticated);
- NSLog(@"3--isFriend--.%d",[GKLocalPlayer localPlayer].isFriend);
- NSLog(@"4--playerID--.%@",[GKLocalPlayer localPlayer].playerID);
- NSLog(@"5--underage--.%d",[GKLocalPlayer localPlayer].underage);
- }else {
- //错误处理
- NSLog(@"失败 %@",error);
- }
- }];
- }
|
对于
开发者来说,Game Center必须经过测试才能上线,没有上线的程序在测试环境中登录时会出现sandbox提示.如图4-1.
图4-1
4.3用户变更检测
由于4.0以后系统支持多任务,玩家的机器有可能被不同的玩家接触,导致Game Center上的用户发生变化,当发生变化的时候,程序必须在游戏中通知玩家.
复制代码
- - (void) registerForAuthenticationNotification
- {
- NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
- [nc addObserver:self
- selector:@selector(authenticationChanged)
- name:GKPlayerAuthenticationDidChangeNotificationName
- object:nil];
- }
- - (void) authenticationChanged
- {
- if ([GKLocalPlayer localPlayer].isAuthenticated)
- {
- ;// Insert code here to handle a successful authentication.
- }
- else
- {
- ;// Insert code here to clean up any outstanding Game Center-related classes.
- }
- }
|
5.对Leaderboard进行操作
5.1上传一个分数
//上传分数
复制代码
- - (void) reportScore: (int64_t) score forCategory: (NSString*) category
- {
- GKScore *scoreReporter = [[[GKScore alloc] initWithCategory:category] autorelease];
- scoreReporter.value = score;
-
- [scoreReporter reportScoreWithCompletionHandler:^(NSError *error) {
- if (error != nil)
- {
- // handle the reporting error
- NSLog(@"上传分数出错.");
- //If your application receives a network error, you should not discard the score.
- //Instead, store the score object and attempt to report the player’s process at
- //a later time.
- }else {
- NSLog(@"上传分数成功");
- }
- }];
- }
|
当上传分数出错的时候,要将上传的分数存储起来,比如将SKScore存入一个NSArray中.等可以上传的时候再次尝试.
5.2下载一个分数
复制代码
- //GKScore objects provide the data your application needs to create a custom view.
- //Your application can use the score object’s playerID to load the player’s alias.
- //The value property holds the actual value you reported to Game Center. the formattedValue
- //property provides a string with the score value formatted according to the parameters
- //you provided in iTunes Connect.
- - (void) retrieveTopTenScores
- {
- GKLeaderboard *leaderboardRequest = [[GKLeaderboard alloc] init];
- if (leaderboardRequest != nil)
- {
- leaderboardRequest.playerScope = GKLeaderboardPlayerScopeGlobal;
- leaderboardRequest.timeScope = GKLeaderboardTimeScopeAllTime;
- leaderboardRequest.range = NSMakeRange(1,10);
- leaderboardRequest.category = @"TS_LB";
- [leaderboardRequest loadScoresWithCompletionHandler: ^(NSArray *scores, NSError *error) {
- if (error != nil){
- // handle the error.
- NSLog(@"下载失败");
- }
- if (scores != nil){
- // process the score information.
- NSLog(@"下载成功....");
- NSArray *tempScore = [NSArray arrayWithArray:leaderboardRequest.scores];
- for (GKScore *obj in tempScore) {
- NSLog(@" playerID : %@",obj.playerID);
- NSLog(@" category : %@",obj.category);
- NSLog(@" date : %@",obj.date);
- NSLog(@" formattedValue : %@",obj.formattedValue);
- NSLog(@" value : %d",obj.value);
- NSLog(@" rank : %d",obj.rank);
- NSLog(@"**************************************");
- }
- }
- }];
- }
- }
|
说明:
1) playerScope:表示检索玩家分数范围.
2) timeScope:表示某一段时间内的分数
3) range:表示分数排名的范围
4) category:表示你的Leaderboard的ID.
5.3玩家信息交互
Game Center最重要的一个功能就是玩家交互.所以,必须检索已经登录玩家的好友信息.根据自己的需要做出设置,比如,可以与好友比较分数,或者好友排行榜等.
//检索已登录用户好友列表
复制代码
- - (void) retrieveFriends
- {
- GKLocalPlayer *lp = [GKLocalPlayer localPlayer];
- if (lp.authenticated)
- {
- [lp loadFriendsWithCompletionHandler:^(NSArray *friends, NSError *error) {
- if (error == nil)
- {
- [self loadPlayerData:friends];
- }
- else
- {
- ;// report an error to the user.
- }
- }];
-
- }
- }
|
上面的friends得到的只是一个身份列表,里面存储的是NSString,想要转换成好友ID,必须调用- (void) loadPlayerData: (NSArray *) identifiers方法,该方法得到的array里面存储的才是GKPlayer对象.如下
复制代码
- /*
- Whether you received player identifiers by loading the identifiers for the local player’s
- friends, or from another Game Center class, you must retrieve the details about that player
- from Game Center.
- */
- - (void) loadPlayerData: (NSArray *) identifiers
- {
- [GKPlayer loadPlayersForIdentifiers:identifiers withCompletionHandler:^(NSArray *players, NSError *error) {
- if (error != nil)
- {
- // Handle the error.
- }
- if (players != nil)
- {
- NSLog(@"得到好友的alias成功");
- GKPlayer *friend1 = [players objectAtIndex:0];
- NSLog(@"friedns---alias---%@",friend1.alias);
- NSLog(@"friedns---isFriend---%d",friend1.isFriend);
- NSLog(@"friedns---playerID---%@",friend1.playerID);
- }
- }];
- }
|
至此,leaderboard功能介绍完毕
6.对Achievement进行操作
这一部分内容比较多,而且有的地方有点重复的感觉.
6.1汇报一个成就的进度
对于一个玩家可见的成就,你需要尽可能的报告给玩家解锁的进度;对于一个一部完成的成就,则不需要,当玩家的进度达到100%的时候,会自动解锁该成就.
复制代码
- - (void) reportAchievementIdentifier: (NSString*) identifier percentComplete: (float) percent
- {
- GKAchievement *achievement = [[[GKAchievement alloc] initWithIdentifier: identifier] autorelease];
- if (achievement)
- {
- achievement.percentComplete = percent;
- [achievement reportAchievementWithCompletionHandler:^(NSError *error)
- {
- if (error != nil)
- {
- //The proper way for your application to handle network errors is retain
- //the achievement object (possibly adding it to an array). Then, periodically
- //attempt to report the progress until it is successfully reported.
- //The GKAchievement class supports the NSCoding protocol to allow your
- //application to archive an achie
- NSLog(@"报告成就进度失败 ,错误信息为: \n %@",error);
- }else {
- //对用户提示,已经完成XX%进度
- NSLog(@"报告成就进度---->成功!");
- NSLog(@" completed:%d",achievement.completed);
- NSLog(@" hidden:%d",achievement.hidden);
- NSLog(@" lastReportedDate:%@",achievement.lastReportedDate);
- NSLog(@" percentComplete:%f",achievement.percentComplete);
- NSLog(@" identifier:%@",achievement.identifier);
- }
- }];
- }
- }
|
其中该函数的参数中identifier是你成就的ID, percent是该成就完成的百分比
6.2读取一个成就
方法一:得到所有的成就
复制代码
- - (void) loadAchievements
- {
- NSMutableDictionary *achievementDictionary = [[NSMutableDictionary alloc] init];
- [GKAchievement loadAchievementsWithCompletionHandler:^(NSArray *achievements,NSError *error)
- {
- if (error == nil) {
- NSArray *tempArray = [NSArray arrayWithArray:achievements];
- for (GKAchievement *tempAchievement in tempArray) {
- [achievementDictionary setObject:tempAchievement forKey:tempAchievement.identifier];
- NSLog(@" completed:%d",tempAchievement.completed);
- NSLog(@" hidden:%d",tempAchievement.hidden);
- NSLog(@" lastReportedDate:%@",tempAchievement.lastReportedDate);
- NSLog(@" percentComplete:%f",tempAchievement.percentComplete);
- NSLog(@" identifier:%@",tempAchievement.identifier);
- }
- }
- }];
- }
|
函数中NSArray返回的是你的所有成就ID.
方法二:根据ID获取成就
复制代码
- - (GKAchievement*) getAchievementForIdentifier: (NSString*) identifier
- {
- NSMutableDictionary *achievementDictionary = [[NSMutableDictionary alloc] init];
- GKAchievement *achievement = [achievementDictionary objectForKey:identifier];
- if (achievement == nil)
- {
- achievement = [[[GKAchievement alloc] initWithIdentifier:identifier] autorelease];
- [achievementDictionary setObject:achievement forKey:achievement.identifier];
- }
- return [[achievement retain] autorelease];
- }
|
6.3获取成就描述和图片
在自定义界面中,玩家需要一个成就描述,以及该成就的图片,Game Center提供了该功能.当然,你也可以自己在程序中完成,毕竟玩家不可能时刻处于在线状态.
复制代码
- - (NSArray*)retrieveAchievmentMetadata
- {
- //读取成就的描述
- [GKAchievementDescription loadAchievementDescriptionsWithCompletionHandler:
- ^(NSArray *descriptions, NSError *error) {
- if (error != nil)
- {
- // process the errors
- NSLog(@"读取成就说明出错");
- }
- if (descriptions != nil)
- {
- // use the achievement descriptions.
- for (GKAchievementDescription *achDescription in descriptions) {
- NSLog(@"1..identifier..%@",achDescription.identifier);
- NSLog(@"2..achievedDescription..%@",achDescription.achievedDescription);
- NSLog(@"3..title..%@",achDescription.title);
- NSLog(@"4..unachievedDescription..%@",achDescription.unachievedDescription);
- NSLog(@"5............%@",achDescription.image);
-
- //获取成就图片,如果成就未解锁,返回一个大文号
- /*
- [achDescription loadImageWithCompletionHandler:^(UIImage *image, NSError *error) {
- if (error == nil)
- {
- // use the loaded image. The image property is also populated with the same image.
- NSLog(@"成功取得成就的图片");
- UIImage *aImage = image;
- UIImageView *aView = [[UIImageView alloc] initWithImage:aImage];
- aView.frame = CGRectMake(50, 50, 200, 200);
- aView.backgroundColor = [UIColor clearColor];
- [[[CCDirector sharedDirector] openGLView] addSubview:aView];
- }else {
- NSLog(@"获得成就图片失败");
- }
- }];
- */
- }
- }
- }];
- return nil;
- }
|
如果你不主动使用注释中的方法,那么你得到的description中不会有图片,这样可以减少网络的使用,尽量少下载东西.当使用注释中的代码时,如果成就已经解锁,则返回该成就的图标,如果没有解锁,则返回一个大问号,至于未解锁图标是否可以自定义,我找寻的结果好像是不可以.
以上,Achievement完成.