GameCenter服务javascript
Game Center是由苹果发布的在线多人游戏社交网络,经过它游戏玩家能够邀请好友进行多人游戏,它也会记录玩家的成绩并在排行榜中展现,同时玩家每通过必定 的阶段会得到不一样的成就。这里就简单介绍一下如何在本身的应用中集成Game Center服务来让用户得到积分、成就以及查看游戏排行和已得到成就。java
由 于Game Center是苹果推出的一项重要服务,苹果官方对于它的控制至关严格,所以使用Game Center以前必需要作许多准备工做。一般须要通过如下几个步骤(下面的准备工做主要是针对真机的,模拟器省略Provisioning Profile配置过程):数组
在苹果开发者中心建立支持Game Center服务的App ID并指定具体的Bundle ID,假设是“com.cmjstudio.kctest”(注意这个Bundle ID就是往后要开发的游戏的Bundle ID)。服务器
基 于“com.cmjstudio.kctest”建立开发者配置文件(或描述文件)并导入对应的设备(建立过程当中选择支持Game Center服务的App ID,这样iOS设备在运行指定Boundle ID应用程序就知道此应用支持Game Center服务)。网络
在iTunes Connect中建立一个应用(假设叫“KCTest”,这是一款足球竞技游戏)并指定“套装ID”为以前建立的“com.cmjstudio.kctest”,让应用和这个App关联(注意这个应用不须要提交)。框架
在iTunes Connect的“用户和职能”中建立沙盒测试用户(因为在测试阶段应用尚未正式提交到App Store,因此只有沙盒用户能够登陆Game Center)。异步
在iTunes Connect中配置此应用Game Center(这里配置了游戏在游戏中心的显示名称为“CMJ”),在其中添加排行榜和成就(假设添加一个排行榜ID“Goals”表示进球个数;两个成 就ID分别为“AdidasGoldBall”、“AdidasGoldBoot”表明金球奖和金靴奖成就,点数分别为80、100)。ide
在iOS“设置”中找到Game Center容许沙盒,不然真机没法调试(若是是模拟器不须要此项设置)。布局
有了以上准备就能够在应用程序中增长积分、添加成就了,固然在实际开发过程积分和成就都是基于玩家所经过的关卡来完成的,为了简化这个过程这里就直接经过几个按钮手动触发这些事件。Game Center开发须要使用GameKit框架,首先熟悉一下经常使用的几个类:测试
GKLocalPlayer:表示本地玩家,在GameKit中还有一个GKPlayer表示联机玩家,为了保证非联网用户也能够正常使用游戏功能,通常使用GKLocalPlayer。
GKScore:管理游戏积分,例如设置积分、排名等。
GKLeaderboard:表示游戏排行榜,主用用于管理玩家排名,例如加载排行榜、设置默认排行榜、加载排行榜图片等。
GKAchievement:表示成就,主用用于管理玩家成就,例如加载成就、提交成就,重置成就等。
GKAchievementDescription:成就描述信息,包含成就的标题、得到前描述、得到后描述、是否可重复得到成就等信息。
GKGameCenterViewController:排行榜、成就查看视图控制器。若是应用自己不须要本身开发排行榜、成就查看试图能够直接调用此控制器。
下 面就以一个简单的示例来完成排行榜、成就设置和查看,在这个演示程序中经过两种方式来查看排行和成就:一种是直接使用框架自带的 GKGameCenterViewContrller调用系统视图查看,另外一种是经过API本身读取排行榜、成就信息并显示。此外在应用中有两个添加按钮 分别用于设置得分和成就。应用大体布局以下:
1.首先看一下主视图控制器KCMainTableViewController:
主 视图控制器调用GKLeaderboard的loadLeaderboardsWithCompletionHandler:方法加载了全部排行榜,这个 过程须要注意每一个排行榜(GKLeaderboard)中的scores属性是没有值的,若是要让每一个排行榜的scores属性有值必须调用一次排行榜的 loadScoresWithCompletionHandler:方法。
调用GKAchievement的 loadAchievementsWithCompletionHandler:方法加载加载成就,注意这个方法只能得到完成度不为0的成就,若是完成度 为0是得到不到的;而后调用GKAchievementDesciption的 loadAchievementDescriptionsWithCompletionHandler:方法加载了全部成就描述,这里加载的是全部成就描 述(无论完成度是否为0);紧接着调用了每一个成就描述的loadImageWithCompletionHandler:方法加载成就图片。
将得到的排行榜、成就、成就描述、成就图片信息保存,并在导航到详情视图时传递给排行榜视图控制器和成就视图控制器以便在子控制器视图中展现。
在主视图控制器左上方添加查看游戏中心控制按钮,点击按钮调用GKGameCenterViewController来展现排行榜、成就、玩家信息,这是系统自带的一个游戏中心视图方便和后面咱们本身得到的信息对比。
程序以下
1 /
2 // KCMainTableViewController.m 3 // kctest 4 // 5 // Created by Kenshin Cui on 14/4/5. 6 // Copyright (c) 2015年 cmjstudio. All rights reserved. 7 // 静态表格 8 #import "KCMainTableViewController.h" 9 #import 10 #import "KCLeaderboardTableViewController.h" 11 #import "KCAchievementTableViewController.h" 12 @interface KCMainTableViewController () 13 @property (strong,nonatomic) NSArray *leaderboards;//排行榜对象数组 14 @property (strong,nonatomic) NSArray *achievements;//成就 15 @property (strong,nonatomic) NSArray *achievementDescriptions;//成就描述 16 @property (strong,nonatomic) NSMutableDictionary *achievementImages;//成就图片 17 @property (weak, nonatomic) IBOutlet UILabel *leaderboardLabel; //排行个数 18 @property (weak, nonatomic) IBOutlet UILabel *achievementLable; //成就个数 19 @end 20 @implementation KCMainTableViewController 21 #pragma mark - 控制器视图事件 22 - (void)viewDidLoad { 23 [super viewDidLoad]; 24 [self authorize]; 25 } 26 #pragma mark - UI事件 27 - (IBAction)viewGameCenterClick:(UIBarButtonItem *)sender { 28 [self viewGameCenter]; 29 } 30 #pragma mark - GKGameCenterViewController代理方法 31 //点击完成 32 -(void)gameCenterViewControllerDidFinish:(GKGameCenterViewController *)gameCenterViewController{ 33 NSLog(@"完成."); 34 [gameCenterViewController dismissViewControllerAnimated:YES completion:nil]; 35 } 36 #pragma mark -导航 37 -(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{ 38 //若是是导航到排行榜,则将当前排行榜传递到排行榜视图 39 if ([segue.identifier isEqualToString:@"leaderboard"]) { 40 UINavigationController *navigationController=segue.destinationViewController; 41 KCLeaderboardTableViewController *leaderboardController=[navigationController.childViewControllers firstObject]; 42 leaderboardController.leaderboards=self.leaderboards; 43 }else if ([segue.identifier isEqualToString:@"achievement"]) { 44 UINavigationController *navigationController=segue.destinationViewController; 45 KCAchievementTableViewController *achievementController=[navigationController.childViewControllers firstObject]; 46 achievementController.achievements=self.achievements; 47 achievementController.achievementDescriptions=self.achievementDescriptions; 48 achievementController.achievementImages=self.achievementImages; 49 } 50 } 51 #pragma mark - 私有方法 52 //检查是否通过认证,若是没通过认证则弹出Game Center登陆界面 53 -(void)authorize{ 54 //建立一个本地用户 55 GKLocalPlayer *localPlayer= [GKLocalPlayer localPlayer]; 56 //检查用于受权,若是没有登陆则让用户登陆到GameCenter(注意此事件设置以后或点击登陆界面的取消按钮都会被调用) 57 [localPlayer setAuthenticateHandler:^(UIViewController * controller, NSError *error) { 58 if ([[GKLocalPlayer localPlayer] isAuthenticated]) { 59 NSLog(@"已受权."); 60 [self setupUI]; 61 }else{ 62 //注意:在设置中找到Game Center,设置其容许沙盒,不然controller为nil 63 [self presentViewController:controller animated:YES completion:nil]; 64 } 65 }]; 66 } 67 //UI布局 68 -(void)setupUI{ 69 //更新排行榜个数 70 [GKLeaderboard loadLeaderboardsWithCompletionHandler:^(NSArray *leaderboards, NSError *error) { 71 if (error) { 72 NSLog(@"加载排行榜过程当中发生错误,错误信息:%@",error.localizedDescription); 73 } 74 self.leaderboards=leaderboards; 75 self.leaderboardLabel.text=[NSString stringWithFormat:@"%i",leaderboards.count]; 76 //获取得分,注意只有调用了loadScoresWithCompletionHandler:方法以后leaderboards中的排行榜中的scores属性才有值,不然为nil 77 [leaderboards enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { 78 GKLeaderboard *leaderboard=obj; 79 [leaderboard loadScoresWithCompletionHandler:^(NSArray *scores, NSError *error) { 80 }]; 81 }]; 82 }]; 83 //更新得到成就个数,注意这个个数不必定等于iTunes Connect中的总成就个数,此方法只能获取到成就完成进度不为0的成就 84 [GKAchievement loadAchievementsWithCompletionHandler:^(NSArray *achievements, NSError *error) { 85 if (error) { 86 NSLog(@"加载成就过程当中发生错误,错误信息:%@",error.localizedDescription); 87 } 88 self.achievements=achievements; 89 self.achievementLable.text=[NSString stringWithFormat:@"%i",achievements.count]; 90 //加载成就描述(注意,即便没有得到此成就也能获取到) 91 [GKAchievementDescription loadAchievementDescriptionsWithCompletionHandler:^(NSArray *descriptions, NSError *error) { 92 if (error) { 93 NSLog(@"加载成就描述信息过程当中发生错误,错误信息:%@",error.localizedDescription); 94 return ; 95 } 96 self.achievementDescriptions=descriptions; 97 //加载成就图片 98 _achievementImages=[NSMutableDictionary dictionary]; 99 [descriptions enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { 100 GKAchievementDescription *description=(GKAchievementDescription *)obj; 101 [description loadImageWithCompletionHandler:^(UIImage *image, NSError *error) { 102 [_achievementImages setObject:image forKey:description.identifier]; 103 }]; 104 }]; 105 }]; 106 }]; 107 } 108 //查看Game Center 109 -(void)viewGameCenter{ 110 if (![GKLocalPlayer localPlayer].isAuthenticated) { 111 NSLog(@"未得到用户受权."); 112 return; 113 } 114 //Game Center视图控制器 115 GKGameCenterViewController *gameCenterController=[[GKGameCenterViewController alloc]init]; 116 //设置代理 117 gameCenterController.gameCenterDelegate=self; 118 //显示 119 [self presentViewController:gameCenterController animated:YES completion:nil]; 120 } 121 @end
2.而后看一下排行榜控制器视图KCLeaderboardTableViewController:
在排行榜控制器视图中定义一个leaderboards属性用于接收主视图控制器传递的排行榜信息而且经过一个UITableView展现排行榜名称、得分等。
在排行榜控制器视图中经过GKScore的reportScores: withCompletionHandler:设置排行榜得分,注意每一个GKScore对象必须设置value属性来表示得分(GKScore是经过identifier来和排行榜关联起来的)。
程序以下
1 // 2 // KCLeaderboardTableViewController.m 3 // kctest 4 // 5 // Created by Kenshin Cui on 14/4/5. 6 // Copyright (c) 2015年 cmjstudio. All rights reserved. 7 // 8 #import "KCLeaderboardTableViewController.h" 9 #import 10 //排行榜标识,就是iTunes Connect中配置的排行榜ID 11 #define kLeaderboardIdentifier1 @"Goals" 12 @interface KCLeaderboardTableViewController () 13 @end 14 @implementation KCLeaderboardTableViewController 15 - (void)viewDidLoad { 16 [super viewDidLoad]; 17 } 18 #pragma mark - UI事件 19 //添加得分(这里指的是进球数) 20 - (IBAction)addScoreClick:(UIBarButtonItem *)sender { 21 [self addScoreWithIdentifier:kLeaderboardIdentifier1 value:100]; 22 } 23 #pragma mark - UITableView数据源方法 24 -(NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index{ 25 return 1; 26 } 27 -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ 28 return self.leaderboards.count; 29 } 30 -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ 31 static NSString *identtityKey=@"myTableViewCellIdentityKey1"; 32 UITableViewCell *cell=[self.tableView dequeueReusableCellWithIdentifier:identtityKey]; 33 if(cell==nil){ 34 cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:identtityKey]; 35 } 36 GKLeaderboard *leaderboard=self.leaderboards[indexPath.row]; 37 GKScore *score=[leaderboard.scores firstObject]; 38 NSLog(@"scores:%@",leaderboard.scores); 39 cell.textLabel.text=leaderboard.title;//排行榜标题 40 cell.detailTextLabel.text=[NSString stringWithFormat:@"%lld",score.value]; //排行榜得分 41 return cell; 42 } 43 #pragma mark - 属性 44 #pragma mark - 私有方法 45 /** 46 * 设置得分 47 * 48 * @param identifier 排行榜标识 49 * @param value 得分 50 */ 51 -(void)addScoreWithIdentifier:(NSString *)identifier value:(int64_t)value{ 52 if (![GKLocalPlayer localPlayer].isAuthenticated) { 53 NSLog(@"未得到用户受权."); 54 return; 55 } 56 //建立积分对象 57 GKScore *score=[[GKScore alloc]initWithLeaderboardIdentifier:identifier]; 58 //设置得分 59 score.value=value; 60 //提交积分到Game Center服务器端,注意保存是异步的,而且支持离线提交 61 [GKScore reportScores:@[score] withCompletionHandler:^(NSError *error) { 62 if(error){ 63 NSLog(@"保存积分过程当中发生错误,错误信息:%@",error.localizedDescription); 64 return ; 65 } 66 NSLog(@"添加积分红功."); 67 }]; 68 } 69 @end
3.最后就是成就视图控制器KCAchievementTableViewController:
在 成就视图控制器定义achievements、achievementDescriptions、achievementImages三个属性分别表示成 就、成就描述、成就图片,这三个属性均从主视图控制器中传递进来,而后使用UITableView展现成就、成就图片、成就进度。
建立 GKAchievemnt对象(经过identifier属性来表示具体的成就)并指定完成度,经过调用GKAchievement的 reportAchievements: withCompletionHandler:方法提交完成度到Game Center服务器。
程序以下
1 // 2 // KCAchievementTableViewController.m 3 // kctest 4 // 5 // Created by Kenshin Cui on 14/4/5. 6 // Copyright (c) 2015年 cmjstudio. All rights reserved. 7 // 8 #import "KCAchievementTableViewController.h" 9 #import 10 //成就标识,就是iTunes Connect中配置的成就ID 11 #define kAchievementIdentifier1 @"AdidasGoldenBall" 12 #define kAchievementIdentifier2 @"AdidasGoldBoot" 13 @interface KCAchievementTableViewController () 14 @end 15 @implementation KCAchievementTableViewController 16 #pragma mark - 控制器视图方法 17 - (void)viewDidLoad { 18 [super viewDidLoad]; 19 20 } 21 #pragma mark - UI事件 22 //添加成就 23 - (IBAction)addAchievementClick:(UIBarButtonItem *)sender { 24 [self addAchievementWithIdentifier:kAchievementIdentifier1]; 25 } 26 #pragma mark - UITableView数据源方法 27 -(NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index{ 28 return 1; 29 } 30 -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ 31 return self.achievementDescriptions.count; 32 } 33 -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ 34 static NSString *identtityKey=@"myTableViewCellIdentityKey1"; 35 UITableViewCell *cell=[self.tableView dequeueReusableCellWithIdentifier:identtityKey]; 36 if(cell==nil){ 37 cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:identtityKey]; 38 } 39 GKAchievementDescription *desciption=[self.achievementDescriptions objectAtIndex:indexPath.row]; 40 cell.textLabel.text=desciption.title ;//成就标题 41 //若是已经得到成就则加载进度,不然为0 42 double percent=0.0; 43 GKAchievement *achievement=[self getAchievementWithIdentifier:desciption.identifier]; 44 if (achievement) { 45 percent=achievement.percentComplete; 46 } 47 cell.detailTextLabel.text=[NSString stringWithFormat:@"%3.2f%%",percent]; //成就完成度 48 //设置成就图片 49 cell.imageView.image=[self.achievementImages valueForKey:desciption.identifier]; 50 return cell; 51 } 52 #pragma mark - 私有方法 53 //添加指定类别的成就 54 -(void)addAchievementWithIdentifier:(NSString *)identifier{ 55 if (![GKLocalPlayer localPlayer].isAuthenticated) { 56 NSLog(@"未得到用户受权."); 57 return; 58 } 59 //建立成就 60 GKAchievement *achievement=[[GKAchievement alloc]initWithIdentifier:identifier]; 61 achievement.percentComplete=100;//设置此成就完成度,100表明得到此成就 62 NSLog(@"%@",achievement); 63 //保存成就到Game Center服务器,注意保存是异步的,而且支持离线提交 64 [GKAchievement reportAchievements:@[achievement] withCompletionHandler:^(NSError *error) { 65 if(error){ 66 NSLog(@"保存成就过程当中发生错误,错误信息:%@",error.localizedDescription); 67 return ; 68 } 69 NSLog(@"添加成就成功."); 70 }]; 71 } 72 //根据标识得到已取得的成就 73 -(GKAchievement *)getAchievementWithIdentifier:(NSString *)identifier{ 74 for (GKAchievement *achievement in self.achievements) { 75 if ([achievement.identifier isEqualToString:identifier]) { 76 return achievement; 77 } 78 } 79 return nil; 80 } 81 @end
运行效果:
注意:首次使用游戏时因为没有对Game Center受权,会提示用户登陆Game Center。