ios9 game center白屏 打开白屏

IOS平台游戏如何对接GameCenter
现在随着手游市场的不断扩大,活跃在平台下的游戏厂商为了增加玩家的粘性,以及为自己的游戏前途考虑都纷纷开始接入苹果国内公司的游戏平台GameC今天呢我就把我对接GameCenter的一些心得以及操作分享给大家,内容很简单也希望在这方面有经验的也可以跟我分享一下。
1.itunesConnect配置:
打开ItunesConnect,选中你的应用,在自己的应用页面上面找到GameCenter选项,如图:
点击打开GameCenter显示如图效果:
apple GameCenter分为两块:&排行榜&与&成就&。首先我们先来添加排行榜:
添加成就:
每个应用的成就点数最多为1000点,属性Hidden(隐藏),如果将其设置为YES,则在用户获得成就或取得一定进展前,成就是不可见的。
如果要让用户能够接受基于已获得的成就的挑战,则需在iTunes Connect中创建成就时选中复选框&可多次获得&。
每个成就需要配置本地化描述;每个成就都有两个描述,一个在用户获得成就前显示,另一个在用户获得成就后显示。另外还需要给每个成就提供已付图像,尺寸为512X512,(应用发布后就不能删除其中的成就)
分别编辑完排行榜与成就后,最终在ItunesConnect中的效果:
对于开发者来说,GameCenter必须经过测试才能上线,没有上线的程序在测试环境中登录时会出现sandBox提示。
好了,itunesConnect部分的基本配置就介绍完了,是不是很简单。下面我们来讲一下程序部分~
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Apple为大家接入GameCenter提供了GameKit.framework,在需要使用GameCenter的类中都要导入GameKit.h;在.h文件中加入协议&GKGameCenterControllerDelegate&.
1.游戏中心管理器
创建共享的游戏管理器,不仅可以将GameCenter功能放在独立的类中,还可以轻松的在新项目中添加GameCenter功能。
判断是否支持GameCenter:
//是否支持GameCenter
- (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);
2,身份验证
GameCenter是一种需要验证身份的服务,如果没有登录就得先验证身份,否则什么也做不了。
//身份验证
- (void)authenticateLocalUser{
GKLocalPlayer *localPlayer = [GKLocalPlayer localPlayer];
localPlayer.authenticateHandler = ^(UIViewController *viewController, NSError *error){
if (viewController != nil) {
[self presentViewController:viewController animated:YES completion:nil];
if ([GKLocalPlayer localPlayer].authenticated) {
// Get the default leaderboard identifier.
[[GKLocalPlayer localPlayer] loadDefaultLeaderboardIdentifierWithCompletionHandler:^(NSString *leaderboardIdentifier, NSError *error) {
if (error != nil) {
NSLog(@&%@&, [error localizedDescription]);
3.用户变更检测
//用户变更检测
- (void)registerFoeAuthenticationNotification{
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
[nc addObserver:self selector:@selector(authenticationChanged) name:GKPlayerAuthenticationDidChangeNotificationName object:nil];
- (void)authenticationChanged{
if([GKLocalPlayer localPlayer].isAuthenticated){
4.提交得分
向GameCenter验证身份后,便可提交得分了。
创建GKStore对象:
- (void) reportScore: (int64_t) score forCategory: (NSString*) category{
GKScore *scoreReporter = [[GKScore alloc] initWithCategory:category];
scoreReporter.value =
[scoreReporter reportScoreWithCompletionHandler:^(NSError *error) {
if(error != nil){
NSData *saveSocreData = [NSKeyedArchiver archivedDataWithRootObject:scoreReporter];
//未能提交得分,需要保存下来后继续提交
[self storeScoreForLater:saveSocreData];
NSLog(@&提交成功&);
- (void)storeScoreForLater:(NSData *)scoreData{
NSMutableArray *savedScoresArray = [[NSMutableArray alloc] initWithArray:[[NSUserDefaults standardUserDefaults] objectForKey:@&savedScores&]];
[savedScoresArray addObject:scoreData];
[[NSUserDefaults standardUserDefaults] setObject:savedScoresArray forKey:@&savedScores&];
若得分提交不成功,需要再重新提交得分:
//重新提交分数
- (void)submitAllSavedScores{
NSMutableArray *savedScoreArray = [[NSMutableArray alloc] initWithArray:[[NSUserDefaults standardUserDefaults] objectForKey:@&savedScores&]];
[[NSUserDefaults standardUserDefaults] removeObjectForKey:@&savedScores&];
for(NSData *scoreData in savedScoreArray){
GKScore *scoreReporter = [NSKeyedUnarchiver unarchiveObjectWithData:scoreData];
[scoreReporter reportScoreWithCompletionHandler:^(NSError *error) {
if(error != nil){
NSData *saveSocreData = [NSKeyedArchiver archivedDataWithRootObject:scoreReporter];
//未能提交得分,需要保存下来后继续提交
[self storeScoreForLater:saveSocreData];
NSLog(@&提交成功&);
5.显示排行榜
创建GKLocalboardViewController来显示排行榜.
- (void)showGameCenter{
GKGameCenterViewController *gameView = [[GKGameCenterViewController alloc] init];
if(gameView != nil){
gameView.gameCenterDelegate =
[gameView setLeaderboardCategory:@&com.xxxx.test&];
[gameView setLeaderboardTimeScope:GKLeaderboardTimeScopeAllTime];
[self presentViewController:gameView animated:YES completion:^{
- (void)gameCenterViewControllerDidFinish:(GKGameCenterViewController *)gameCenterViewController{
[self dismissViewControllerAnimated:YES completion:nil];
6.得分成就
挑战让用户可以通过GameCenter向玩家发起得分或成就方面的挑战。挑战分为四种:&无效&,&待处理&,&已结束&,&已谢绝&。
- (void)reportAchievment:(NSString *)identifier withPercentageComplete:(double)percentComplete{
GKAchievement *achievement = [[GKAchievement alloc] initWithIdentifier:identifier];
[achievement setPercentComplete:percentComplete];
[achievement reportAchievementWithCompletionHandler:^(NSError *error) {
if(error != nil){
NSLog(@&error:%@&, [error localizedDescription]);
NSLog(@&提交成就成功&);
示例演示:
1.在sandbox环境中登录GameCenter
登录成功以后会在上方显示一个横幅&Welcome....&,点击GameCenter app就会显示您以及您游戏的相关信息.
3.排行榜界面
成就的图标为在后台配置的图标;
5.添加好友
点击右上角的&加号&按钮,会弹出一个添加好友的界面,输入对方AppleID即可给对方发送好友请求。
6.发起挑战
对方收到挑战信息推送界面
好了,gameCenter的接入到这边就告一段落了,若在开发中有新的发现我会及时跟新这篇文章,欢迎大家评论分享自己的看法。Cocos2d-x中集成iOS GameCenter实例
NovaCreo| 09:14|次浏览|
Apple Store中每一个游戏几乎都集成了Game Center,在现在制作的塔防游戏中,我也将Game Center集成了进去。虽然网上有现成的教程甚至是代码,但是自己在走这个流程的过程中,还是磕磕绊绊碰到了一些问题。在这里记录一下,以备不时之需。
首先,创建一个leaderboard或者achievement。在没有添加leaderboard或achievement的情况下,即使在程
序中集成了gamecenter相关代码,调试时也会得到一个类似于“未识别的应用”这样的提示。我在模拟器调试时得到提示,真机调试压根就没有提示。关
于如何创建leaderboard/achievement,请参考这篇教程:/gamedev
/misc/29.html。需要注意
是:“Achievement
ID”一项必须是一个唯一的id,建议以“app名+成就名”的方式来命名,比如smashangels.firstsoldier,该ID创建后就没法
再进行更改了,但是可以删除;每个成就必须有一个512*512或者的图片,否则无法创建成就。
在创建完成后,就要着手进行编码了。因为几乎每个游戏都要用到gamecenter,所以我将通用的代码封装到OC类NCSGameCenter
中,然后再根据每个游戏的需要,给NCSGameCenter一个wrapper。基本的代码在上面给出的链接里面也有,我这里将完整的代码再贴一遍。
[NCSGameCenter.h]
#import &UIKit/UIKit.h&
#import &Foundation/Foundation.h&
#import &GameKit/GameKit.h&
@interface NCSGameCenter : NSObject & GKLeaderboardViewControllerDelegate, GKAchievementViewControllerDelegate, GKMatchmakerViewControllerDelegate, GKMatchDelegate& {
BOOL gameCenterA
BOOL userA
@property (assign, readonly) BOOL gameCenterA
@property (nonatomic, copy) NSString* leaderboardN
//本地成就字典,用来保存已经下载下来的成就,以避免重复从gamecenter获取成就状态
@property (nonatomic, retain) NSMutableDictionary* achievementD
+ (NCSGameCenter *)sharedGameC
- (void) authenticateLocalU
- (void) registerForAuthenticationN
- (void) showL
- (void) leaderboardViewControllerDidFinish:(GKLeaderboardViewController *)viewC
//上传分数到Gamecenter
- (void) reportScore:(int64_t)score forCategory:(NSString*)
//从gamecenter下载前X个分数
- (void) retrieveTopXScores:(int)
- (void) showA
- (void) achievementViewControllerDidFinish:(GKAchievementViewController *)achievementC
- (void) loadA
- (void) clearA
- (void) reportAchievement:(NSString*)id percent:(float)
- (void) unlockAchievement:(GKAchievement*)achievement percent:(float)
- (GKAchievement*) getAchievementForID:(NSString*)
[NCSGameCenter.m]
#import "NCSGameCenter.h"
@implementation NCSGameCenter
@synthesize gameCenterA
//静态初始化 对外接口
static NCSGameCenter *sharedHelper =
static UIViewController* currentModalViewController =
+ (NCSGameCenter *) sharedGameCenter {
if (!sharedHelper) {
sharedHelper = [[NCSGameCenter alloc] init];
return sharedH
//用于验证
- (BOOL)isGameCenterAvailable {
// check for presence of GKLocalPlayer API
Class gcClass = (NSClassFromString(@"GKLocalPlayer"));
// check if the device is running iOS 4.1 or later
NSString *reqSysVer =@"4.1";
NSString *currSysVer = [[UIDevice currentDevice] systemVersion];
BOOL osVersionSupported = ([currSysVer compare:reqSysVer
options:NSNumericSearch] != NSOrderedAscending);
return (gcClass && osVersionSupported);
- (id)init {
if ((self = [super init])) {
gameCenterAvailable = [self isGameCenterAvailable];
if (gameCenterAvailable) {
NSNotificationCenter *nc =
[NSNotificationCenter defaultCenter];
[nc addObserver:self
selector:@selector(authenticationChanged)
name:GKPlayerAuthenticationDidChangeNotificationName
object:nil];
//后台回调登陆验证
- (void)authenticationChanged {
if ([GKLocalPlayer localPlayer].isAuthenticated &&!userAuthenticated) {
NSLog(@"Authentication changed: player authenticated.");
userAuthenticated = TRUE;
} else if (![GKLocalPlayer localPlayer].isAuthenticated && userAuthenticated) {
NSLog(@"Authentication changed: player not authenticated");
userAuthenticated = FALSE;
- (void)authenticateLocalUser {
if (!gameCenterAvailable)
if ([GKLocalPlayer localPlayer].authenticated == NO) {
[[GKLocalPlayer localPlayer] authenticateWithCompletionHandler:nil];
NSLog(@"Already authenticated!");
//认证完毕后从gamecenter中获取成就状态,以备后面上传成就时查询
[self loadAchievement];
- (void) registerForAuthenticationNotification
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
[nc addObserver:self
selector:@selector(authenticationChanged)
name:GKPlayerAuthenticationDidChangeNotificationName
object:nil];
//显示排行榜
- (void) showLeaderboard
if (!gameCenterAvailable)
GKLeaderboardViewController *leaderboardController = [[GKLeaderboardViewController alloc] init];
if (leaderboardController != nil) {
leaderboardController.leaderboardDelegate =
UIWindow *window = [[UIApplication sharedApplication] keyWindow];
currentModalViewController = [[UIViewController alloc] init];
[window addSubview:currentModalViewController.view];
[currentModalViewController presentModalViewController:leaderboardController animated:YES];
//关闭排行榜回调
- (void)leaderboardViewControllerDidFinish:(GKLeaderboardViewController *)viewController{
if(currentModalViewController !=nil){
[currentModalViewController dismissModalViewControllerAnimated:NO];
[currentModalViewController release];
[currentModalViewController.view removeFromSuperview];
currentModalViewController =
//上传分数到排行榜
- (void) reportScore: (int64_t) score forCategory: (NSString*) category
GKScore *scoreReporter = [[[GKScore alloc] initWithCategory:category] autorelease];
scoreReporter.value =
[scoreReporter reportScoreWithCompletionHandler:^(NSError *error) {
if (error != nil)
NSLog(@"上传分数出错.");
NSLog(@"上传分数成功");
//下载分数
- (void) retrieveTopXScores:(int)number
GKLeaderboard *leaderboardRequest = [[GKLeaderboard alloc] init];
if (leaderboardRequest != nil)
leaderboardRequest.playerScope = GKLeaderboardPlayerScopeG
leaderboardRequest.timeScope = GKLeaderboardTimeScopeAllT
leaderboardRequest.range = NSMakeRange(1,number);
leaderboardRequest.category = leaderboardN
[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) {
: %@",obj.playerID);
: %@",obj.category);
: %@",obj.date);
formattedValue
: %@",obj.formattedValue);
: %d",obj.value);
: %d",obj.rank);
NSLog(@"**************************************");
//汇报成就
//通过ID汇报成就
- (void) reportAchievement:(NSString*)id percent:(float)percent
if ( !gameCenterAvailable ) {
NSLog(@"ERROR: GameCenter is not available currently");
GKAchievement* achievement = [[[GKAchievement alloc] initWithIdentifier:id] autorelease];
[self unlockAchievement:achievement percent:percent];
//通过成就指针汇报成就
- (void) unlockAchievement:(GKAchievement *)achievement percent:(float)percent
if ( achievement != nil )
achievement.percentComplete =
achievement.showsCompletionBanner = YES;
[achievement reportAchievementWithCompletionHandler:^(NSError* error){
if ( error != nil)
NSLog(@"上传成就错误,错误提示为\n%@", error);
NSLog(@"上传成就成功\n");
[self displayAchievement:achievement];
//显示成就
- (void) showAchievementboard
if (!gameCenterAvailable)
GKAchievementViewController *achievementController = [[GKAchievementViewController alloc] init];
if (achievementController != nil) {
achievementController.achievementDelegate =
UIWindow *window = [[UIApplication sharedApplication] keyWindow];
currentModalViewController = [[UIViewController alloc] init];
[window addSubview:currentModalViewController.view];
[currentModalViewController presentModalViewController:achievementController animated:YES];
//关闭成就回调
- (void)achievementViewControllerDidFinish:(GKAchievementViewController *)viewController{
if(currentModalViewController !=nil){
[currentModalViewController dismissModalViewControllerAnimated:NO];
[currentModalViewController release];
[currentModalViewController.view removeFromSuperview];
currentModalViewController =
//打印某个成就
- (void) displayAchievement:(GKAchievement*)achievement
if ( achievement == nil)
NSLog(@"completed:%d", pleted);
NSLog(@"lastReportDate:%@", achievement.lastReportedDate);
NSLog(@"percentComplete:%f", achievement.percentComplete);
NSLog(@"identifier:%@", achievement.identifier);
//加载所有成就。经测试,只能获取到已经上传过的成就状态。
- (void) loadAchievement
if ( self.achievementDictionary == nil )
self.achievementDictionary = [[NSMutableDictionary alloc] init];
[GKAchievement loadAchievementsWithCompletionHandler:^(NSArray* achievements, NSError* error){
if ( error == nil && achievements != nil )
NSArray* tempArray = [NSArray arrayWithArray:achievements];
for(GKAchievement* tempAchievement in tempArray)
[self.achievementDictionary setObject:tempAchievement
forKey:tempAchievement.identifier];
[self displayAchievement:tempAchievement];
//通过成就id生成成就。首先从本地成就字典查询,查询不到则生成一个。
- (GKAchievement*) getAchievementForID: (NSString*) id
if ( self.achievementDictionary == nil )
self.achievementDictionary = [[NSMutableDictionary alloc] init];
GKAchievement *achievement = [self.achievementDictionary objectForKey:id];
if (achievement == nil)
achievement = [[[GKAchievement alloc] initWithIdentifier:id] autorelease];
[self.achievementDictionary setObject:achievement
forKey:achievement.identifier];
[self displayAchievement:achievement];
return [[achievement retain] autorelease];
//初始化所有成就状态。经测试,这段代码暂时无效。
- (void) clearAchievements
NSEnumerator* enumerator = [self.achievementDictionary objectEnumerator];
for(NSObject* obj in enumerator)
[self unlockAchievement:(GKAchievement*)obj percent:0.0];
在当前的项目中,为了方便,我将所有的成就id保存在一个plist文件中,格式如下:
&key&0&/key&
&string&smashangels.firstsoldier&/string&
在C++代码中定义一个枚举类型
typedef enum {
kFirstSoldier = 0,
kFirstWar,
} DIAAchievementID;
然后,就可以通过CCDictionary来方便的通过DIAAchievementID来查询到对应的成就id。实际封装的Gamecenter wrapper如下(只封装了成就部分):
DIAAchievement.h
#ifndef __DIA_ACHIEVEMENT_H__
#define __DIA_ACHIEVEMENT_H__
#include &vector&
#include "cocos2d.h"
USING_NS_CC;
typedef vector& DIAAchievementID & DIAAchievementIDV;
class DIAAchievement
DIAAchievement();
virtual ~DIAAchievement();
static DIAAchievement* instance();
virtual void release();
// Unlock achievement APIs
void unlockAchievement(DIAAchievementID id);
void openGameCenter();
const DIAAchievementIDV getAllLockedAchievement();
const DIAAchievementIDV getAllUnlockedAchievement();
protected:
bool isAchievementUnlocked(DIAAchievementID id);
const char* getIdentifierById(DIAAchievementID id);
CCDictionary* m_pAchievementD
static DIAAchievement* sI
#if ( CC_TARGET_PLATFORM == CC_PLATFORM_IOS )
void registerAchievementController();
#define sGameCenter DIAAchievement::instance()
#endif // __DIA_ACHIEVEMENT_H__
DIAAchievement.mm
#include "DIAAchievement.h"
#include "NCSGameCenter.h"
DIAAchievement* DIAAchievement::sInstance = NULL;
DIAAchievement::DIAAchievement()
this-&m_pAchievementDict = CCDictionary::createWithContentsOfFileThreadSafe("data/achievement.plist");
DIAAchievement::~DIAAchievement()
DIAAchievement* DIAAchievement::instance()
if ( sInstance == NULL )
sInstance = new DIAAchievement();
void DIAAchievement::release()
if ( sInstance )
sInstance = NULL;
void DIAAchievement::registerAchievementController()
[[NCSGameCenter sharedGameCenter] authenticateLocalUser];
//公共函数,通过成就id获取成就指针
GKAchievement* getAchievementByID(const char* id)
GKAchievement* pRet = NULL;
NSString* identifier = [[NSString alloc] initWithUTF8String:id];
pRet = [[NCSGameCenter sharedGameCenter] getAchievementForID:identifier];
// 打开Gamecenter面板,并将起始页定位在成就页。
void DIAAchievement::openGameCenter()
[[NCSGameCenter sharedGameCenter] showAchievementboard];
//判断成就是否已经解锁
bool DIAAchievement::isAchievementUnlocked(DIAAchievementID id)
bool ret =
const char* pIdentifier = this-&getIdentifierById(id);
GKAchievement* achievement = getAchievementByID(pIdentifier);
if ( achievement )
//解锁成就
void DIAAchievement::unlockAchievement(DIAAchievementID id)
const char* pIdentifier = this-&getIdentifierById(id);
GKAchievement* achievement = getAchievementByID(pIdentifier);
if ( achievement != NULL && pleted != YES )
[[NCSGameCenter sharedGameCenter] unlockAchievement:achievement
percent:100.0];
const char* DIAAchievement::getIdentifierById(DIAAchievementID id)
const CCString* pIdStr = this-&m_pAchievementDict-&valueForKey(id);
if ( pIdStr )
return pIdStr-&getCString();
return NULL;
最终,在IOS cocos2d-x项目中的AppController.mm中添加DIAAchievement.h头文件,并在didFinishLaunchingWithOptions方法中添加如下代码完成用户登录。
sGameCenter-&registerAchievementController();
在需要解锁成就的地方增加类似下面的代码即可完成成就解锁。
sGameCenter-&unlockAchievement(kFirstSoldier);
在AppController.mm的dealloc方法中添加如下代码释放DIAAchievement的全局指针。
sGameCenter-&release();
来自:novacreo6522人阅读
iOS/Android Game开发笔记(22)
我们的游戏需要支持多个账号,包括facebook, gamecenter, weibo等第三方账号的登陆支持,并且可以在游戏中切换账号。
现在遇到一个问题,GameCenter无法从游戏中logout。搜索了一下,并且研读了文档,确实不行,唯一logout的方法是用户自己在GameCenter App中注销。
那么对于多账号的游戏,如果想登出gamecenter账号,只能在上一层做封装,注销自己封装的账号,但是gamecenter还是处于登陆状态的。切换账号后,如果并非一个gamecenter账号,你需要自己识别并禁用gamecenter相关功能(比如隐藏gamecenter排行榜入口等),而不能紧紧判断game center是否已经登陆。
此外,如果用户切换账号后再次登陆game center账号,此时由于game center已经登陆,如果使用apple提供的game center manager类就不会再次请求授权,所以最好自己判断一下,如果已经登陆,就用当前登陆game center账号的信息模拟登陆成功。当然,有个问题是不能切换game center用户,这是没办法的了。。
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:424181次
积分:6265
积分:6265
排名:第2095名
原创:178篇
转载:12篇
评论:305条
(5)(3)(4)(1)(1)(1)(3)(1)(2)(4)(1)(1)(2)(1)(3)(1)(2)(2)(2)(2)(1)(1)(13)(7)(3)(2)(1)(2)(2)(1)(2)(4)(2)(5)(7)(1)(1)(1)(3)(4)(4)(2)(1)(1)(3)(1)(1)(1)(1)(1)(2)(2)(3)(1)(1)(1)(3)(4)(3)(2)(2)(1)(1)(2)(3)(11)(1)(4)(4)(6)(1)(1)(5)(5)(2)

我要回帖

更多关于 苹果gamecenter白屏 的文章

 

随机推荐