iOS開發——高級技術&GameCenter服務

GameCenter服務數組

Game Center是由蘋果發佈的在線多人遊戲社交網絡,經過它遊戲玩家能夠邀請好友進行多人遊戲,它也會記錄玩家的成績並在排行榜中展現,同時玩家每通過必定 的階段會得到不一樣的成就。這裏就簡單介紹一下如何在本身的應用中集成Game Center服務來讓用戶得到積分、成就以及查看遊戲排行和已得到成就。服務器

由 於Game Center是蘋果推出的一項重要服務,蘋果官方對於它的控制至關嚴格,所以使用Game Center以前必需要作許多準備工做。一般須要通過如下幾個步驟(下面的準備工做主要是針對真機的,模擬器省略Provisioning Profile配置過程):網絡

  • 在蘋果開發者中心建立支持Game Center服務的App ID並指定具體的Bundle ID,假設是「com.cmjstudio.kctest」(注意這個Bundle ID就是往後要開發的遊戲的Bundle ID)。框架

130912377293665.png

  • 基 於「com.cmjstudio.kctest」建立開發者配置文件(或描述文件)並導入對應的設備(建立過程當中選擇支持Game Center服務的App ID,這樣iOS設備在運行指定Boundle ID應用程序就知道此應用支持Game Center服務)。異步

130912400738749.png

  • 在iTunes Connect中建立一個應用(假設叫「KCTest」,這是一款足球競技遊戲)並指定「套裝ID」爲以前建立的「com.cmjstudio.kctest」,讓應用和這個App關聯(注意這個應用不須要提交)。ide

  • 在iTunes Connect的「用戶和職能」中建立沙盒測試用戶(因爲在測試階段應用尚未正式提交到App Store,因此只有沙盒用戶能夠登陸Game Center)。佈局

  • 在iTunes Connect中配置此應用Game Center(這裏配置了遊戲在遊戲中心的顯示名稱爲「CMJ」),在其中添加排行榜和成就(假設添加一個排行榜ID「Goals」表示進球個數;兩個成 就ID分別爲「AdidasGoldBall」、「AdidasGoldBoot」表明金球獎和金靴獎成就,點數分別爲80、100)。測試

130912475428701.png

  • 在iOS「設置」中找到Game Center容許沙盒,不然真機沒法調試(若是是模擬器不須要此項設置)。ui

130912515114256.png

有了以上準備就能夠在應用程序中增長積分、添加成就了,固然在實際開發過程積分和成就都是基於玩家所經過的關卡來完成的,爲了簡化這個過程這裏就直接經過幾個按鈕手動觸發這些事件。Game Center開發須要使用GameKit框架,首先熟悉一下經常使用的幾個類:this

  • GKLocalPlayer:表示本地玩家,在GameKit中還有一個GKPlayer表示聯機玩家,爲了保證非聯網用戶也能夠正常使用遊戲功能,通常使用GKLocalPlayer。

  • GKScore:管理遊戲積分,例如設置積分、排名等。

  • GKLeaderboard:表示遊戲排行榜,主用用於管理玩家排名,例如加載排行榜、設置默認排行榜、加載排行榜圖片等。

  • GKAchievement:表示成就,主用用於管理玩家成就,例如加載成就、提交成就,重置成就等。

  • GKAchievementDescription:成就描述信息,包含成就的標題、得到前描述、得到後描述、是否可重複得到成就等信息。

  • GKGameCenterViewController:排行榜、成就查看視圖控制器。若是應用自己不須要本身開發排行榜、成就查看試圖能夠直接調用此控制器。

下 面就以一個簡單的示例來完成排行榜、成就設置和查看,在這個演示程序中經過兩種方式來查看排行和成就:一種是直接使用框架自帶的 GKGameCenterViewContrller調用系統視圖查看,另外一種是經過API本身讀取排行榜、成就信息並顯示。此外在應用中有兩個添加按鈕 分別用於設置得分和成就。應用大體佈局以下:

130912561677966.png

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
複製代碼
複製代碼

 

運行效果:

130913318863555.gif

注意:首次使用遊戲時因爲沒有對Game Center受權,會提示用戶登陸Game Center。

相關文章
相關標籤/搜索