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)。

  • 基 于“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)。

  • 在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。

时间: 2024-08-02 12:09:25

iOS开发——高级技术&GameCenter服务的相关文章

iOS开发——高级技术&蓝牙服务

蓝牙服务 蓝牙 随着蓝牙低功耗技术BLE(Bluetooth Low Energy)的发展,蓝牙技术正在一步步成熟,如今的大部分移动设备都配备有蓝牙4.0,相比之前的蓝牙技术耗电量大大降低.从iOS的发展史也不难看 出苹果目前对蓝牙技术也是越来越关注,例如苹果于2013年9月发布的iOS7就配备了iBeacon技术,这项技术完全基于蓝牙传输.但是众所周知苹果 的设备对于权限要求也是比较高的,因此在iOS中并不能像Android一样随意使用蓝牙进行文件传输(除非你已经越狱).在iOS中进行蓝牙传输

iOS开发——高级技术&PassBook服务

PassBook服务 Passbook是苹果推出的一个管理登机牌.会员卡.电影票.优惠券等信息的 工具.Passbook就像一个卡包,用于存放你的购物卡.积分卡.电影票.礼品卡等,而这些票据就是一个“Pass”.和物理票据不同的是你可以动态更 新Pass的信息,提醒用户优惠券即将过期:甚至如果你的Pass中包含地理位置信息的话当你到达某个商店还可以动态提示用户最近商店有何种优惠活动:当 用户将一张团购券添加到Passbook之后,用户到了商店之后Passbook可以自动弹出团购券,店员扫描之后进

iOS开发——高级技术&iCloud服务

iCloud服务 iCloud 是苹果提供的云端服务,用户可以将通讯录.备忘录.邮件.照片.音乐.视频等备份到云服务器并在各个苹果设备间直接进行共享而无需关心数据同步问题,甚至 即使你的设备丢失后在一台新的设备上也可以通过Apple ID登录同步.当然这些内容都是iOS内置的功能,那么对于开放者如何利用iCloud呢?苹果已经将云端存储功能开放给开发者,利用iCloud开发者 可以存储两类数据:用户文档和应用数据.应用配置项.前者主要用于一些用户文档.文件的存储,后者更类似于日常开放中的偏好设置

iOS开发——高级技术&通讯录服务

通讯录服务 AddressBook iOS中带有一 个Contacts应用程序来管理联系人,但是有些时候我们希望自己的应用能够访问或者修改这些信息,这个时候就要用到 AddressBook.framework框架.iOS中的通讯录是存储在数据库中的,由于iOS的权限设计,开发人员是不允许直接访问通讯录数据库 的,必须依靠AddressBook提供的标准API来实现通讯录操作.通过AddressBook.framework开发者可以从底层去操作 AddressBook.framework的所有信息

iOS开发——高级技术&社交服务

社交服务 Social 现 在很多应用都内置“社交分享”功能,可以将看到的新闻.博客.广告等内容分享到微博.微信.QQ.空间等,其实从iOS6.0开始苹果官方就内置了 Social.framework专门来实现社交分享功能,利用这个框架开发者只需要几句代码就可以实现内容分享.下面就以一个分享到新浪微博的功能为例 来演示Social框架的应用,整个过程分为:创建内容编辑控制器,设置分享内容(文本内容.图片.超链接等),设置发送(或取消)后的回调事件,展示控 制器. 程序代码: 1 // 2 //

iOS开发——高级技术&内购服务

内购服务 大家都知道做iOS开发本身的收入有三种来源:出售应用.内购和广告.国内用户通常很少直接 购买应用,因此对于开发者而言(特别是个人开发者),内购和广告收入就成了主要的收入来源.内购营销模式,通常软件本身是不收费的,但是要获得某些特权就 必须购买一些道具,而内购的过程是由苹果官方统一来管理的,所以和Game Center一样,在开发内购程序之前要做一些准备工作(下面的准备工作主要是针对真机的,模拟器省略Provisioning Profile配置过程): 前四步和Game Center基本

iOS开发——高级技术OC篇&运行时(Runtime)机制

运行时(Runtime)机制 本文将会以笔者个人的小小研究为例总结一下关于iOS开发中运行时的使用和常用方法的介绍,关于跟多运行时相关技术请查看笔者之前写的运行时高级用法及相关语法或者查看响应官方文档. 下面就来看看什么是运行时,我们要怎么在iOS开发中去使用它. 官方介绍: 这里我们主要关注的是最后一种! 下面来看看Runtime的相关总结 #pragma mark 获取属性成员 /********************************************************

iOS开发——高级技术&摇一摇功能的实现

摇一摇功能的实现 在AppStore中多样化功能越来越多的被使用了,所以今天就开始介绍一些iOS开发的比较实用,但是我们接触的比较少的功能,我们先从摇一摇功能开始 在 UIResponder中存在这么一套方法 1 - (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_3_0); 2 3 - (void)motionEnded:

iOS开发——高级技术精选OC篇&Runtime之字典转模型实战

Runtime之字典转模型实战 如果您还不知道什么是runtime,那么请先看看这几篇文章: http://www.cnblogs.com/iCocos/p/4734687.html http://www.cnblogs.com/iCocos/p/4676679.html http://www.cnblogs.com/iCocos/p/4725527.html 关于runtime的详细介绍及其相关的小实例 好了,这里就不多废话了,直接开干! 先来看看怎么使用Runtime给模型类赋值 iOS开发