Hi all boys,
after some days spent to understand the Game Center and the GKTapper i found a great solution that work ever for C++ coders that won't to use UIButtons and IBActions.
Ok let's go!
- 1 Step : We need to be clean...
Do a new folder (Group) called GameCenter and add inside it the GameCenterManager.h and GameCenterManager.m you will find them in the ZIP file attached and add them in the folder by clicking right mouse.
- 2 Step : Let's modify our UntitledViewController...
UntitledViewController.h
{code}
#import <UIKit/UIKit.h>
#import <GameKit/GameKit.h>
#import "GameCenterManager.h"
#import <OpenGLES/EAGL.h>
#import <OpenGLES/ES1/gl.h>
#import <OpenGLES/ES1/glext.h>
#import <OpenGLES/ES2/gl.h>
#import <OpenGLES/ES2/glext.h>
@class GameCenterManager;
@interface UntitledViewController : UIViewController <UIActionSheetDelegate, GKLeaderboardViewControllerDelegate, GameCenterManagerDelegate>
{
EAGLContext *context;
GLuint program;
BOOL active;
BOOL displayLinkSupported;
NSInteger frameInterval;
/*
Use of the CADisplayLink class is the preferred method for controlling your animation timing.
CADisplayLink will link to the main display and fire every vsync when added to a given run-loop.
The NSTimer object is used only as fallback when running on a pre-3.1 device where CADisplayLink isn't available.
*/
id displayLink;
NSTimer *syncTimer;
GameCenterManager *gameCenterManager;
}
@property (nonatomic, retain) GameCenterManager *gameCenterManager;
- (void) setActive;
- (void) setInactive;
- (void) submitScore: (int64_t) _score;
- (void) showLeaderboard;
@end
{/code}
UntitledViewController.m
{code}
#import <QuartzCore/QuartzCore.h>
#import "GameCenterManager.h"
#import "Core.h"
//#import "UntitledViewController.h"
#include "AGK.h"
// Include app header
#include "OurGameName.h"
using namespace AGK;
#define DEG 0.0174532925
#define DEGREES_TO_RADIANS(__ANGLE__) ((__ANGLE__) / 180.0 * M_PI)
// Uniform index.
enum {
UNIFORM_TRANSLATE,
NUM_UNIFORMS
};
GLint uniforms[NUM_UNIFORMS];
// Attribute index.
enum {
ATTRIB_VERTEX,
ATTRIB_COLOR,
NUM_ATTRIBUTES
};
BOOL g_bDisplayLinkReady = FALSE;
@interface UntitledViewController ()
@property (nonatomic, retain) EAGLContext *context;
@end
@implementation UntitledViewController
@synthesize gameCenterManager;
@synthesize context;
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
- (void) showAlertWithTitle: (NSString*) title message: (NSString*) message
{
UIAlertView* alert= [[[UIAlertView alloc] initWithTitle: title message: message
delegate: NULL cancelButtonTitle: @"OK" otherButtonTitles: NULL] autorelease];
[alert show];
}
- (void)awakeFromNib
{
CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.view.layer;
eaglLayer.opaque = TRUE;
eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:TRUE], kEAGLDrawablePropertyRetainedBacking,
kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat,
nil];
agk::SetResolutionMode(1);
agk::InitGL( self.view );
active = FALSE;
displayLinkSupported = FALSE;
frameInterval = 1;
displayLink = nil;
syncTimer = nil;
// Use of CADisplayLink requires iOS version 3.1 or greater.
// The NSTimer object is used as fallback when it isn't available.
NSString *reqSysVer = @"3.1";
NSString *currSysVer = [[UIDevice currentDevice] systemVersion];
if ([currSysVer compare:reqSysVer options:NSNumericSearch] != NSOrderedAscending)
displayLinkSupported = TRUE;
g_bDisplayLinkReady = TRUE;
}
-(BOOL)shouldAutorotateToInterfaceOrientation
UIInterfaceOrientation)interfaceOrientation
{
//return NO;
switch( interfaceOrientation )
{
case UIInterfaceOrientationPortrait: return YES;
case UIInterfaceOrientationPortraitUpsideDown: return YES;
case UIInterfaceOrientationLandscapeLeft: return NO;
case UIInterfaceOrientationLandscapeRight: return NO;
default: return NO;
}
}
- (void)dealloc
{
if (program)
{
glDeleteProgram(program);
program = 0;
}
// Tear down context.
if ([EAGLContext currentContext] == context)
[EAGLContext setCurrentContext:nil];
[gameCenterManager release];
[context release];
[super dealloc];
}
- (void)viewWillAppear
BOOL)animated
{
[self setActive];
[super viewWillAppear:animated];
}
- (void)viewWillDisappear
BOOL)animated
{
[self setInactive];
[super viewWillDisappear:animated];
}
- (void)viewDidLoad
{
[super viewDidLoad];
if([GameCenterManager isGameCenterAvailable])
{
self.gameCenterManager = [[[GameCenterManager alloc] init] autorelease];
[self.gameCenterManager setDelegate: self];
[self.gameCenterManager authenticateLocalUser];
}
else
{
[self showAlertWithTitle: @"Game Center Support Required!"
message: @"The current device does not support Game Center."];
}
}
- (void)viewDidUnload
{
[super viewDidUnload];
if (program)
{
glDeleteProgram(program);
program = 0;
}
self.gameCenterManager = nil;
// Tear down context.
if ([EAGLContext currentContext] == context)
[EAGLContext setCurrentContext:nil];
self.context = nil;
}
- (NSInteger)frameInterval
{
return frameInterval;
}
- (void)setFrameInterval
NSInteger)interval
{
/*
Frame interval defines how many display frames must pass between each time the display link fires.
The display link will only fire 30 times a second when the frame internal is two on a display that refreshes 60 times a second. The default frame interval setting of one will fire 60 times a second when the display refreshes at 60 times a second. A frame interval setting of less than one results in undefined behavior.
*/
if (interval >= 1)
{
// frameInterval = frameInterval;
if (active)
{
[self setInactive];
[self setActive];
}
}
}
- (void)setActive
{
if ( g_bDisplayLinkReady == FALSE )
return;
if (!active)
{
if (displayLinkSupported)
{
// CADisplayLink is API new to iPhone SDK 3.1. Compiling against earlier versions will result in a warning, but can be dismissed
// if the system version runtime check for CADisplayLink exists in -initWithCoder:. The runtime check ensures this code will
// not be called in system versions earlier than 3.1.
displayLink = [NSClassFromString(@"CADisplayLink") displayLinkWithTarget
elf selector
selector(drawView)];
[displayLink setFrameInterval:frameInterval];
[displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
}
else
{
syncTimer = [NSTimer scheduledTimerWithTimeInterval
NSTimeInterval)((1.0 / 60.0) * frameInterval) target
elf selector
selector(drawView
userInfo:nil repeats:TRUE];
}
active = TRUE;
}
}
- (void)setInactive
{
if (active)
{
if (displayLinkSupported)
{
[displayLink invalidate];
displayLink = nil;
}
else
{
[syncTimer invalidate];
syncTimer = nil;
}
active = FALSE;
}
}
- (void)drawView
{
App.Loop();
}
-(void)submitScore: (int64_t) _score
{
//This is the same category id you set in your itunes connect GameCenter LeaderBoard
GKScore *myScoreValue = [[[GKScore alloc] initWithCategory
"YourGameIDLeaderBoard"] autorelease];
myScoreValue.value = _score;
[myScoreValue reportScoreWithCompletionHandler:^(NSError *error){
if(error != nil){
[self showAlertWithTitle
"HighScore" message
"Score saved!"];
} else {
[self showAlertWithTitle
"HighScore" message
"Score not saved!"];
}
}];
}
- (void)showLeaderboard
{
GKLeaderboardViewController *leaderboardController = [[[GKLeaderboardViewController alloc] init] autorelease];
if (leaderboardController != NULL)
{
leaderboardController.category = @"YourGameIDNameLeaderBoard";
leaderboardController.timeScope = GKLeaderboardTimeScopeAllTime;
//leaderboardController.modalPresentationStyle = UIModalPresentationFullScreen;
leaderboardController.leaderboardDelegate = self;
iphone_appAppDelegate *appDelegate = (iphone_appAppDelegate *) [[UIApplication sharedApplication] delegate];
[appDelegate.viewController presentModalViewController:leaderboardController animated:YES];
}
}
- (void)leaderboardViewControllerDidFinish
GKLeaderboardViewController *)viewController
{
iphone_appAppDelegate *appDelegate = (iphone_appAppDelegate *) [[UIApplication sharedApplication] delegate];
[appDelegate.viewController dismissModalViewControllerAnimated:YES];
}
@end
{/code}
3 Step : Let's call our routine from everywhere in C++...
To call the GameCenter command from every where we need to alloc (not init) a variable. This must be placed in OurGame.cpp...
I suggest to put it on the top.
{code}
UntitledViewController *g_View = [UntitledViewController alloc];
{/code}
Remember to add this if you are not sure is already done in OurGame.h
{code}
#import "UntitledViewController.h"
#import "Core.h"
{/code}
We will use #import to be sure to not double the H files.
4 Step : Let's call what we need!!
To show the leaderboard...
{code}
[g_View showLeaderboard];
{/code}
To submit the score...
{code}
[g_View submitScore: PlayerPoints];
{/code}
PlayerPoints can be INT
Well that's all.
I hope this will help all coders that have some problem on showing the subview for LeaderBoard.
after some days spent to understand the Game Center and the GKTapper i found a great solution that work ever for C++ coders that won't to use UIButtons and IBActions.
Ok let's go!
- 1 Step : We need to be clean...
Do a new folder (Group) called GameCenter and add inside it the GameCenterManager.h and GameCenterManager.m you will find them in the ZIP file attached and add them in the folder by clicking right mouse.
- 2 Step : Let's modify our UntitledViewController...
UntitledViewController.h
{code}
#import <UIKit/UIKit.h>
#import <GameKit/GameKit.h>
#import "GameCenterManager.h"
#import <OpenGLES/EAGL.h>
#import <OpenGLES/ES1/gl.h>
#import <OpenGLES/ES1/glext.h>
#import <OpenGLES/ES2/gl.h>
#import <OpenGLES/ES2/glext.h>
@class GameCenterManager;
@interface UntitledViewController : UIViewController <UIActionSheetDelegate, GKLeaderboardViewControllerDelegate, GameCenterManagerDelegate>
{
EAGLContext *context;
GLuint program;
BOOL active;
BOOL displayLinkSupported;
NSInteger frameInterval;
/*
Use of the CADisplayLink class is the preferred method for controlling your animation timing.
CADisplayLink will link to the main display and fire every vsync when added to a given run-loop.
The NSTimer object is used only as fallback when running on a pre-3.1 device where CADisplayLink isn't available.
*/
id displayLink;
NSTimer *syncTimer;
GameCenterManager *gameCenterManager;
}
@property (nonatomic, retain) GameCenterManager *gameCenterManager;
- (void) setActive;
- (void) setInactive;
- (void) submitScore: (int64_t) _score;
- (void) showLeaderboard;
@end
{/code}
UntitledViewController.m
{code}
#import <QuartzCore/QuartzCore.h>
#import "GameCenterManager.h"
#import "Core.h"
//#import "UntitledViewController.h"
#include "AGK.h"
// Include app header
#include "OurGameName.h"
using namespace AGK;
#define DEG 0.0174532925
#define DEGREES_TO_RADIANS(__ANGLE__) ((__ANGLE__) / 180.0 * M_PI)
// Uniform index.
enum {
UNIFORM_TRANSLATE,
NUM_UNIFORMS
};
GLint uniforms[NUM_UNIFORMS];
// Attribute index.
enum {
ATTRIB_VERTEX,
ATTRIB_COLOR,
NUM_ATTRIBUTES
};
BOOL g_bDisplayLinkReady = FALSE;
@interface UntitledViewController ()
@property (nonatomic, retain) EAGLContext *context;
@end
@implementation UntitledViewController
@synthesize gameCenterManager;
@synthesize context;
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
- (void) showAlertWithTitle: (NSString*) title message: (NSString*) message
{
UIAlertView* alert= [[[UIAlertView alloc] initWithTitle: title message: message
delegate: NULL cancelButtonTitle: @"OK" otherButtonTitles: NULL] autorelease];
[alert show];
}
- (void)awakeFromNib
{
CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.view.layer;
eaglLayer.opaque = TRUE;
eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:TRUE], kEAGLDrawablePropertyRetainedBacking,
kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat,
nil];
agk::SetResolutionMode(1);
agk::InitGL( self.view );
active = FALSE;
displayLinkSupported = FALSE;
frameInterval = 1;
displayLink = nil;
syncTimer = nil;
// Use of CADisplayLink requires iOS version 3.1 or greater.
// The NSTimer object is used as fallback when it isn't available.
NSString *reqSysVer = @"3.1";
NSString *currSysVer = [[UIDevice currentDevice] systemVersion];
if ([currSysVer compare:reqSysVer options:NSNumericSearch] != NSOrderedAscending)
displayLinkSupported = TRUE;
g_bDisplayLinkReady = TRUE;
}
-(BOOL)shouldAutorotateToInterfaceOrientation
UIInterfaceOrientation)interfaceOrientation{
//return NO;
switch( interfaceOrientation )
{
case UIInterfaceOrientationPortrait: return YES;
case UIInterfaceOrientationPortraitUpsideDown: return YES;
case UIInterfaceOrientationLandscapeLeft: return NO;
case UIInterfaceOrientationLandscapeRight: return NO;
default: return NO;
}
}
- (void)dealloc
{
if (program)
{
glDeleteProgram(program);
program = 0;
}
// Tear down context.
if ([EAGLContext currentContext] == context)
[EAGLContext setCurrentContext:nil];
[gameCenterManager release];
[context release];
[super dealloc];
}
- (void)viewWillAppear
BOOL)animated{
[self setActive];
[super viewWillAppear:animated];
}
- (void)viewWillDisappear
BOOL)animated{
[self setInactive];
[super viewWillDisappear:animated];
}
- (void)viewDidLoad
{
[super viewDidLoad];
if([GameCenterManager isGameCenterAvailable])
{
self.gameCenterManager = [[[GameCenterManager alloc] init] autorelease];
[self.gameCenterManager setDelegate: self];
[self.gameCenterManager authenticateLocalUser];
}
else
{
[self showAlertWithTitle: @"Game Center Support Required!"
message: @"The current device does not support Game Center."];
}
}
- (void)viewDidUnload
{
[super viewDidUnload];
if (program)
{
glDeleteProgram(program);
program = 0;
}
self.gameCenterManager = nil;
// Tear down context.
if ([EAGLContext currentContext] == context)
[EAGLContext setCurrentContext:nil];
self.context = nil;
}
- (NSInteger)frameInterval
{
return frameInterval;
}
- (void)setFrameInterval
NSInteger)interval{
/*
Frame interval defines how many display frames must pass between each time the display link fires.
The display link will only fire 30 times a second when the frame internal is two on a display that refreshes 60 times a second. The default frame interval setting of one will fire 60 times a second when the display refreshes at 60 times a second. A frame interval setting of less than one results in undefined behavior.
*/
if (interval >= 1)
{
// frameInterval = frameInterval;
if (active)
{
[self setInactive];
[self setActive];
}
}
}
- (void)setActive
{
if ( g_bDisplayLinkReady == FALSE )
return;
if (!active)
{
if (displayLinkSupported)
{
// CADisplayLink is API new to iPhone SDK 3.1. Compiling against earlier versions will result in a warning, but can be dismissed
// if the system version runtime check for CADisplayLink exists in -initWithCoder:. The runtime check ensures this code will
// not be called in system versions earlier than 3.1.
displayLink = [NSClassFromString(@"CADisplayLink") displayLinkWithTarget
elf selector
selector(drawView)];[displayLink setFrameInterval:frameInterval];
[displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
}
else
{
syncTimer = [NSTimer scheduledTimerWithTimeInterval
NSTimeInterval)((1.0 / 60.0) * frameInterval) target
elf selector
selector(drawView
userInfo:nil repeats:TRUE];}
active = TRUE;
}
}
- (void)setInactive
{
if (active)
{
if (displayLinkSupported)
{
[displayLink invalidate];
displayLink = nil;
}
else
{
[syncTimer invalidate];
syncTimer = nil;
}
active = FALSE;
}
}
- (void)drawView
{
App.Loop();
}
-(void)submitScore: (int64_t) _score
{
//This is the same category id you set in your itunes connect GameCenter LeaderBoard
GKScore *myScoreValue = [[[GKScore alloc] initWithCategory
"YourGameIDLeaderBoard"] autorelease];myScoreValue.value = _score;
[myScoreValue reportScoreWithCompletionHandler:^(NSError *error){
if(error != nil){
[self showAlertWithTitle
"HighScore" message
"Score saved!"];} else {
[self showAlertWithTitle
"HighScore" message
"Score not saved!"];}
}];
}
- (void)showLeaderboard
{
GKLeaderboardViewController *leaderboardController = [[[GKLeaderboardViewController alloc] init] autorelease];
if (leaderboardController != NULL)
{
leaderboardController.category = @"YourGameIDNameLeaderBoard";
leaderboardController.timeScope = GKLeaderboardTimeScopeAllTime;
//leaderboardController.modalPresentationStyle = UIModalPresentationFullScreen;
leaderboardController.leaderboardDelegate = self;
iphone_appAppDelegate *appDelegate = (iphone_appAppDelegate *) [[UIApplication sharedApplication] delegate];
[appDelegate.viewController presentModalViewController:leaderboardController animated:YES];
}
}
- (void)leaderboardViewControllerDidFinish
GKLeaderboardViewController *)viewController{
iphone_appAppDelegate *appDelegate = (iphone_appAppDelegate *) [[UIApplication sharedApplication] delegate];
[appDelegate.viewController dismissModalViewControllerAnimated:YES];
}
@end
{/code}
3 Step : Let's call our routine from everywhere in C++...
To call the GameCenter command from every where we need to alloc (not init) a variable. This must be placed in OurGame.cpp...
I suggest to put it on the top.
{code}
UntitledViewController *g_View = [UntitledViewController alloc];
{/code}
Remember to add this if you are not sure is already done in OurGame.h
{code}
#import "UntitledViewController.h"
#import "Core.h"
{/code}
We will use #import to be sure to not double the H files.
4 Step : Let's call what we need!!
To show the leaderboard...
{code}
[g_View showLeaderboard];
{/code}
To submit the score...
{code}
[g_View submitScore: PlayerPoints];
{/code}
PlayerPoints can be INT
Well that's all.
I hope this will help all coders that have some problem on showing the subview for LeaderBoard.



