GameCenter使用指南(初级) PART2

书接上文...

现把功能放上来,具体 使用的体会我会慢慢补充进来.

本部分内容适合需要自定义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支持判断

复制代码
  1. - (BOOL) isGameCenterAvailable
  2. {
  3.     Class gcClass = (NSClassFromString(@"GKLocalPlayer"));
  4.     NSString *reqSysVer = @"4.1";
  5.     NSString *currSysVer = [[UIDevice currentDevice] systemVersion];
  6.     BOOL osVersionSupported = ([currSysVer compare:reqSysVer options:NSNumericSearch] != NSOrderedAscending);
  7.     
  8.     return (gcClass && osVersionSupported);
  9. }


4.2用户登录
复制代码
  1. - (void) authenticateLocalPlayer
  2. {
  3.     [[GKLocalPlayer localPlayer] authenticateWithCompletionHandler:^(NSError *error){
  4.         if (error == nil) {
  5.             //成功处理
  6.             NSLog(@"成功");
  7.             NSLog(@"1--alias--.%@",[GKLocalPlayer localPlayer].alias);
  8.             NSLog(@"2--authenticated--.%d",[GKLocalPlayer localPlayer].authenticated);
  9.             NSLog(@"3--isFriend--.%d",[GKLocalPlayer localPlayer].isFriend);
  10.             NSLog(@"4--playerID--.%@",[GKLocalPlayer localPlayer].playerID);
  11.             NSLog(@"5--underage--.%d",[GKLocalPlayer localPlayer].underage);
  12.         }else {
  13.             //错误处理
  14.             NSLog(@"失败  %@",error);
  15.         }
  16.     }];
  17. }

对于 开发者来说,Game Center必须经过测试才能上线,没有上线的程序在测试环境中登录时会出现sandbox提示.如图4-1.
  
GameCenter使用指南(初级) PART2_第1张图片
图4-1

4.3用户变更检测
由于4.0以后系统支持多任务,玩家的机器有可能被不同的玩家接触,导致Game Center上的用户发生变化,当发生变化的时候,程序必须在游戏中通知玩家.
复制代码
  1. - (void) registerForAuthenticationNotification
  2. {
  3.     NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
  4.     [nc addObserver:self
  5.            selector:@selector(authenticationChanged)
  6.                name:GKPlayerAuthenticationDidChangeNotificationName
  7.              object:nil];
  8. }

  9. - (void) authenticationChanged
  10. {
  11.     if ([GKLocalPlayer localPlayer].isAuthenticated)
  12.     {
  13.         ;// Insert code here to handle a successful authentication.
  14.     }
  15.     else
  16.     {
  17.         ;// Insert code here to clean up any outstanding Game Center-related classes.
  18.     }
  19. }


5.对Leaderboard进行操作
5.1上传一个分数
//上传分数
复制代码
  1. - (void) reportScore: (int64_t) score forCategory: (NSString*) category
  2. {
  3.     GKScore *scoreReporter = [[[GKScore alloc] initWithCategory:category] autorelease];
  4.     scoreReporter.value = score;
  5.     
  6.     [scoreReporter reportScoreWithCompletionHandler:^(NSError *error) {
  7.         if (error != nil)
  8.         {
  9.             // handle the reporting error
  10.             NSLog(@"上传分数出错.");
  11.             //If your application receives a network error, you should not discard the score.
  12.             //Instead, store the score object and attempt to report the player’s process at
  13.             //a later time.
  14.         }else {
  15.             NSLog(@"上传分数成功");
  16.         }

  17.     }];
  18. }


当上传分数出错的时候,要将上传的分数存储起来,比如将SKScore存入一个NSArray中.等可以上传的时候再次尝试.

5.2下载一个分数
复制代码
  1. //GKScore objects provide the data your application needs to create a custom view.
  2. //Your application can use the score object’s playerID to load the player’s alias.
  3. //The value property holds the actual value you reported to Game Center. the formattedValue
  4. //property provides a string with the score value formatted according to the parameters
  5. //you provided in iTunes Connect.
  6. - (void) retrieveTopTenScores
  7. {
  8.     GKLeaderboard *leaderboardRequest = [[GKLeaderboard alloc] init];
  9.     if (leaderboardRequest != nil)
  10.     {
  11.         leaderboardRequest.playerScope = GKLeaderboardPlayerScopeGlobal;
  12.         leaderboardRequest.timeScope = GKLeaderboardTimeScopeAllTime;
  13.         leaderboardRequest.range = NSMakeRange(1,10);
  14.         leaderboardRequest.category = @"TS_LB";
  15.         [leaderboardRequest loadScoresWithCompletionHandler: ^(NSArray *scores, NSError *error) {
  16.             if (error != nil){
  17.                 // handle the error.
  18.                 NSLog(@"下载失败");
  19.             }
  20.             if (scores != nil){
  21.                 // process the score information.
  22.                 NSLog(@"下载成功....");
  23.                 NSArray *tempScore = [NSArray arrayWithArray:leaderboardRequest.scores];
  24.                 for (GKScore *obj in tempScore) {
  25.                     NSLog(@"    playerID            : %@",obj.playerID);
  26.                     NSLog(@"    category            : %@",obj.category);
  27.                     NSLog(@"    date                : %@",obj.date);
  28.                     NSLog(@"    formattedValue    : %@",obj.formattedValue);
  29.                     NSLog(@"    value                : %d",obj.value);
  30.                     NSLog(@"    rank                : %d",obj.rank);
  31.                     NSLog(@"**************************************");
  32.                 }
  33.             }
  34.         }];
  35.     }
  36. }

说明:
1)    playerScope:表示检索玩家分数范围.
2)    timeScope:表示某一段时间内的分数
3)    range:表示分数排名的范围
4)    category:表示你的Leaderboard的ID.

5.3玩家信息交互
Game Center最重要的一个功能就是玩家交互.所以,必须检索已经登录玩家的好友信息.根据自己的需要做出设置,比如,可以与好友比较分数,或者好友排行榜等.
//检索已登录用户好友列表
复制代码
  1. - (void) retrieveFriends
  2. {
  3.     GKLocalPlayer *lp = [GKLocalPlayer localPlayer];
  4.     if (lp.authenticated)
  5.     {
  6.         [lp loadFriendsWithCompletionHandler:^(NSArray *friends, NSError *error) {
  7.             if (error == nil)
  8.             {
  9.                 [self loadPlayerData:friends];
  10.             }
  11.             else
  12.             {
  13.                 ;// report an error to the user.
  14.             }
  15.         }];
  16.         
  17.     }
  18. }

上面的friends得到的只是一个身份列表,里面存储的是NSString,想要转换成好友ID,必须调用- (void) loadPlayerData: (NSArray *) identifiers方法,该方法得到的array里面存储的才是GKPlayer对象.如下
复制代码
  1. /*
  2. Whether you received player identifiers by loading the identifiers for the local player’s
  3. friends, or from another Game Center class, you must retrieve the details about that player
  4. from Game Center.
  5. */
  6. - (void) loadPlayerData: (NSArray *) identifiers
  7. {
  8.     [GKPlayer loadPlayersForIdentifiers:identifiers withCompletionHandler:^(NSArray *players, NSError *error) {
  9.         if (error != nil)
  10.         {
  11.             // Handle the error.
  12.         }
  13.         if (players != nil)
  14.         {
  15.             NSLog(@"得到好友的alias成功");
  16.             GKPlayer *friend1 = [players objectAtIndex:0];
  17.             NSLog(@"friedns---alias---%@",friend1.alias);
  18.             NSLog(@"friedns---isFriend---%d",friend1.isFriend);
  19.             NSLog(@"friedns---playerID---%@",friend1.playerID);
  20.         }
  21.     }];
  22. }


至此,leaderboard功能介绍完毕

6.对Achievement进行操作
这一部分内容比较多,而且有的地方有点重复的感觉.
6.1汇报一个成就的进度
对于一个玩家可见的成就,你需要尽可能的报告给玩家解锁的进度;对于一个一部完成的成就,则不需要,当玩家的进度达到100%的时候,会自动解锁该成就.
复制代码
  1. - (void) reportAchievementIdentifier: (NSString*) identifier percentComplete: (float) percent
  2. {
  3.     GKAchievement *achievement = [[[GKAchievement alloc] initWithIdentifier: identifier] autorelease];
  4.     if (achievement)
  5.     {
  6.         achievement.percentComplete = percent;
  7.         [achievement reportAchievementWithCompletionHandler:^(NSError *error)
  8.          {
  9.              if (error != nil)
  10.              {
  11.                  //The proper way for your application to handle network errors is retain
  12.                  //the achievement object (possibly adding it to an array). Then, periodically
  13.                  //attempt to report the progress until it is successfully reported.
  14.                  //The GKAchievement class supports the NSCoding protocol to allow your
  15.                  //application to archive an achie
  16.                  NSLog(@"报告成就进度失败 ,错误信息为: \n %@",error);
  17.              }else {
  18.                  //对用户提示,已经完成XX%进度
  19.                  NSLog(@"报告成就进度---->成功!");
  20.                  NSLog(@"    completed:%d",achievement.completed);
  21.                  NSLog(@"    hidden:%d",achievement.hidden);
  22.                  NSLog(@"    lastReportedDate:%@",achievement.lastReportedDate);
  23.                  NSLog(@"    percentComplete:%f",achievement.percentComplete);
  24.                  NSLog(@"    identifier:%@",achievement.identifier);
  25.              }
  26.          }];
  27.     }
  28. }

其中该函数的参数中identifier是你成就的ID, percent是该成就完成的百分比

6.2读取一个成就
方法一:得到所有的成就
复制代码
  1. - (void) loadAchievements
  2. {
  3.     NSMutableDictionary *achievementDictionary = [[NSMutableDictionary alloc] init];
  4.     [GKAchievement loadAchievementsWithCompletionHandler:^(NSArray *achievements,NSError *error)
  5.      {
  6.          if (error == nil) {
  7.              NSArray *tempArray = [NSArray arrayWithArray:achievements];
  8.              for (GKAchievement *tempAchievement in tempArray) {
  9.                  [achievementDictionary setObject:tempAchievement forKey:tempAchievement.identifier];
  10.                  NSLog(@"    completed:%d",tempAchievement.completed);
  11.                  NSLog(@"    hidden:%d",tempAchievement.hidden);
  12.                  NSLog(@"    lastReportedDate:%@",tempAchievement.lastReportedDate);
  13.                  NSLog(@"    percentComplete:%f",tempAchievement.percentComplete);
  14.                  NSLog(@"    identifier:%@",tempAchievement.identifier);
  15.              }
  16.          }
  17.      }];
  18. }

函数中NSArray返回的是你的所有成就ID.

方法二:根据ID获取成就
复制代码
  1. - (GKAchievement*) getAchievementForIdentifier: (NSString*) identifier
  2. {
  3.     NSMutableDictionary *achievementDictionary = [[NSMutableDictionary alloc] init];
  4.     GKAchievement *achievement = [achievementDictionary objectForKey:identifier];
  5.     if (achievement == nil)
  6.     {
  7.         achievement = [[[GKAchievement alloc] initWithIdentifier:identifier] autorelease];
  8.         [achievementDictionary setObject:achievement forKey:achievement.identifier];
  9.     }
  10.     return [[achievement retain] autorelease];
  11. }


6.3获取成就描述和图片
在自定义界面中,玩家需要一个成就描述,以及该成就的图片,Game Center提供了该功能.当然,你也可以自己在程序中完成,毕竟玩家不可能时刻处于在线状态.
复制代码
  1. - (NSArray*)retrieveAchievmentMetadata
  2. {
  3.     //读取成就的描述
  4.     [GKAchievementDescription loadAchievementDescriptionsWithCompletionHandler:
  5.      ^(NSArray *descriptions, NSError *error) {
  6.          if (error != nil)
  7.          {
  8.              // process the errors
  9.              NSLog(@"读取成就说明出错");
  10.          }
  11.          if (descriptions != nil)
  12.          {
  13.              // use the achievement descriptions.
  14.              for (GKAchievementDescription *achDescription in descriptions) {
  15.                  NSLog(@"1..identifier..%@",achDescription.identifier);
  16.                  NSLog(@"2..achievedDescription..%@",achDescription.achievedDescription);
  17.                  NSLog(@"3..title..%@",achDescription.title);
  18.                  NSLog(@"4..unachievedDescription..%@",achDescription.unachievedDescription);
  19.                  NSLog(@"5............%@",achDescription.image);
  20.                 
  21.                  //获取成就图片,如果成就未解锁,返回一个大文号
  22.                  /*
  23.                  [achDescription loadImageWithCompletionHandler:^(UIImage *image, NSError *error) {
  24.                      if (error == nil)
  25.                      {
  26.                          // use the loaded image. The image property is also populated with the same image.
  27.                          NSLog(@"成功取得成就的图片");
  28.                          UIImage *aImage = image;
  29.                          UIImageView *aView = [[UIImageView alloc] initWithImage:aImage];
  30.                          aView.frame = CGRectMake(50, 50, 200, 200);
  31.                          aView.backgroundColor = [UIColor clearColor];
  32.                          [[[CCDirector sharedDirector] openGLView] addSubview:aView];
  33.                      }else {
  34.                          NSLog(@"获得成就图片失败");
  35.                      }
  36.                  }];
  37.                   */
  38.              }
  39.          }
  40.     }];
  41.     return nil;
  42. }


如果你不主动使用注释中的方法,那么你得到的description中不会有图片,这样可以减少网络的使用,尽量少下载东西.当使用注释中的代码时,如果成就已经解锁,则返回该成就的图标,如果没有解锁,则返回一个大问号,至于未解锁图标是否可以自定义,我找寻的结果好像是不可以.

以上,Achievement完成.

你可能感兴趣的:(GameCenter使用指南(初级) PART2)