SpriteKitはUIViewControllerがsubclassではないので、UIViewControllerでGameCenterの機能を使う方法とは若干異なる。
MyScene.h
#import <SpriteKit/SpriteKit.h>
#import <GameKit/GameKit.h>
@interface MyScene : SKScene <GKGameCenterControllerDelegate>
@end
MyScene.m
#import "MyScene.h"
@implementation MyScene {
BOOL _touch;
GKLocalPlayer *_localPlayer;
}
// 画面作成
-(id)initWithSize:(CGSize)size {
if (self = [super initWithSize:size]) {
// ゲーム開始ボタン作成
SKLabelNode *startLabel = [SKLabelNode labelNodeWithFontNamed:@"Verdana-Bold"];
startLabel.text = @"GAME START";
startLabel.fontSize = 25;
startLabel.name = @"GameStart";
startLabel.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame)-50);
[self addChild:startLabel];
// LeaderBoardを表示するボタン作成
SKLabelNode *scoreLabel = [SKLabelNode labelNodeWithFontNamed:@"Verdana-Bold"];
scoreLabel.text = @"SCORE RANKING";
scoreLabel.fontSize = 25;
scoreLabel.name = @"Score";
scoreLabel.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame)-120);
[self addChild:scoreLabel];
// GameCenter認証
[self authenticateLocalPlayer];
}
return self;
}
// GameCenter認証
- (void)authenticateLocalPlayer
{
__weak typeof(self) weakSelf = self;
_localPlayer = [GKLocalPlayer localPlayer];
__weak GKLocalPlayer *weakPlayer = _localPlayer;
weakPlayer.authenticateHandler = ^(UIViewController *viewController, NSError *error)
{
if (viewController != nil) // LOGIN
{
[weakSelf showAuthenticationDialogWhenReasonable:viewController];
}
else if (weakPlayer.isAuthenticated) // LOGIN済
{
[weakSelf authenticatedPlayer:weakPlayer];
}
else
{
[weakSelf disableGameCenter];
}
};
}
// GameCenter認証画面
-(void)showAuthenticationDialogWhenReasonable:(UIViewController *)controller
{
[[[[[UIApplication sharedApplication] delegate] window] rootViewController] presentViewController:controller animated:YES completion:nil];
}
// GameCenter認証OK
-(void)authenticatedPlayer:(GKLocalPlayer *)player
{
player = _localPlayer;
}
// GameCenter認証NG
-(void)disableGameCenter
{
}
// 画面タップ時
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
if(_touch==NO){
UITouch *touch = [touches anyObject];
CGPoint location = [touch locationInNode:self];
SKNode *node = [self nodeAtPoint:location];
// ゲーム開始(シーンを推移させる)
if(node != nil && [node.name isEqualToString:@"GameStart"]) {
_touch = YES;
}
// Leader Board表示
if(node != nil && [node.name isEqualToString:@"Score"]) {
[self showGameCenter];
}
}
}
// フレーム更新時に呼ばれる
-(void)update:(CFTimeInterval)currentTime {
}
// Leader Board表示
-(void)showGameCenter {
GKGameCenterViewController *gameCenterController = [[GKGameCenterViewController alloc] init];
if (gameCenterController != nil)
{
gameCenterController.gameCenterDelegate = self;
gameCenterController.viewState = GKGameCenterViewControllerStateLeaderboards;
UIViewController *vc = self.view.window.rootViewController;
[vc presentViewController: gameCenterController animated: YES completion:nil];
}
}
// Leader Boardが閉じたとき呼ばれる
- (void)gameCenterViewControllerDidFinish:(GKGameCenterViewController *)gameCenterViewController {
[[[[[UIApplication sharedApplication] delegate] window] rootViewController] dismissViewControllerAnimated:YES completion:nil];
}
@end
ポイント:画面をモーダルで表示するpresentViewControllerも、画面を閉じるdismissViewControllerAnimatedも、[self dismissViewControllerAnimated ...] や [self dismissViewControllerAnimated ...] とコーディングすると、ビルド時に「No vislble @interface for declares the selector... 」などのエラーとなる。
従って、rootViewControllerを取得して 画面表示あるいは画面を閉じる操作をする必要がある。
参考記事:
http://stackoverflow.com/questions/12398782/authplayerwithcompletionhandler-deprecated-so-how-do-i-use-authenticatehandler
http://www.raywenderlich.com/forums/viewtopic.php?f=2&t=10844
【SpriteKitの最新記事】