Game Center Support
by Justin Mosiman · in iTorque 2D · 11/12/2010 (8:53 pm) · 67 replies
With the sad news from InstantAction, I feel that it is more important now than ever to keep iTGB alive. With that, I am going to post instructions on how to integrate Game Center within iTGB. I know that integrating Game Center with Open Feint is easier, but I feel that the two frameworks have a lot of overlapping features and I want to reduce the amount of bloat. If this code has been useful to you, I'd appreciate a War Evolved download :)
There is a lot of setup that you have to do within iTunes Connect to get Game Center to work, so instead of repeating it I'll just point you to the iTunes Connect Game Center docs. Even though the code is here, I still recommend reading the docs to be sure you don't miss anything and can understand what is happening.
Assuming you have iTunes Connect setup, perform the following steps:
1. Create GameCenter.mm and GameCenter.h within the platformiPhone directory in the Xcode Torque project.
2. Add the following to GameCenter.h:
3. Add the following code to GameCenter.mm:
4. Update GameCenterWrapper::reportScore() and GameCenterWrapper::reportAchievement() to include the score category/achievement id that was set in iTunes Connect.
5. To initialize Game Center, call the following Torque Script function:
6. To close Game Center, call:
7. To add a high score, call:
8. To award an achievement, call:
9. To show the leaderboard GUI, call:
10. To show the achievements GUI, call:
11. The Torque Script function gameCenterAuthenticationChanged(%isAvailable) is called whenever the authentication changes. Add this function somewhere in your game to handle logging into Game Center, such as showing the achievements or leaderboard.
Note that it is up to you to decide how you want to indicate that an achievement was achieved. There are more Game Center related functions exposed, and you can decide if you need to use them, but I haven't found a use for them.
If this code has been useful to you, I'd appreciate a War Evolved download :)
Justin
There is a lot of setup that you have to do within iTunes Connect to get Game Center to work, so instead of repeating it I'll just point you to the iTunes Connect Game Center docs. Even though the code is here, I still recommend reading the docs to be sure you don't miss anything and can understand what is happening.
Assuming you have iTunes Connect setup, perform the following steps:
1. Create GameCenter.mm and GameCenter.h within the platformiPhone directory in the Xcode Torque project.
2. Add the following to GameCenter.h:
//
// GameCenter.m
// Torque2D
//
// Created by Justin Mosiman on 10/29/10.
// Copyright 2010 Opsive, LLC. All rights reserved.
//
#import <GameKit/GameKit.h>
#include "console/console.h"
@interface GameCenter : UIViewController <GKLeaderboardViewControllerDelegate, GKAchievementViewControllerDelegate>
{
BOOL isAuthenticated;
BOOL gameCenterAvailable;
UIViewController *gameCenterViewController;
}
@property (nonatomic,retain) UIViewController *gameCenterViewController;
- (void)authenticateLocalPlayer;
- (void)registerForAuthenticationNotification;
- (void)authenticationChanged;
- (BOOL)isAuthenticated;
- (void)reportScore:(int64_t)score forCategory:(NSString*)category;
- (void)reportScore:(GKScore *)scoreReporter;
- (void)saveScoreToDevice:(GKScore *)score;
- (void)retrieveScoresFromDevice;
- (void)showLeaderboard;
- (void)leaderboardViewControllerDidFinish:(GKLeaderboardViewController *)viewController;
- (void)reportAchievementIdentifier:(NSString*)identifier percentComplete:(float)percent;
- (void)reportAchievementIdentifier:(GKAchievement *)achievement;
- (void)saveAchievementToDevice:(GKAchievement *)achievement;
- (void)retrieveAchievementsFromDevice;
- (void)showAchievements;
- (void)achievementViewControllerDidFinish:(GKAchievementViewController *)viewController;
- (void)close;
@end
static GameCenter *gameCenter;
namespace GameCenterWrapper {
void authenticate();
void reportScore(int score, int category);
void reportAchievement(int achievement);
bool isAuthenticated();
void showLeaderboard();
void showAchievements();
void close();
}3. Add the following code to GameCenter.mm:
//
// GameCenter.mm
// Torque2D
//
// Created by Justin Mosiman on 10/29/10.
// Copyright 2010 Opsive, LLC. All rights reserved.
//
#import "platformiPhone/GameCenter.h"
BOOL isGameCenterAvailable()
{
// Check for presence of GKLocalPlayer API.
Class gcClass = (NSClassFromString(@"GKLocalPlayer"));
// The device must be running 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);
}
@implementation GameCenter
@synthesize gameCenterViewController;
//--------------------------------------------------------
// Static functions/variables
//--------------------------------------------------------
static NSString *getGameCenterSavePath()
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
return [NSString stringWithFormat:@"%@/GameCenterSave.txt",[paths objectAtIndex:0]];
}
static NSString *scoresArchiveKey = @"Scores";
static NSString *achievementsArchiveKey = @"Achievements";
//--------------------------------------------------------
// Authentication
//--------------------------------------------------------
- (void)authenticateLocalPlayer {
isAuthenticated = NO; // assume the player isn't authenticated
gameCenterAvailable = isGameCenterAvailable();
if(!gameCenterAvailable){
return;
}
gameCenterViewController = [[UIViewController alloc] init];
[[GKLocalPlayer localPlayer] authenticateWithCompletionHandler:^(NSError *error) {
if (error == nil){
// Insert code here to handle a successful authentication.
isAuthenticated = YES;
[self registerForAuthenticationNotification];
// report any unreported scores or achievements
[self retrieveScoresFromDevice];
[self retrieveAchievementsFromDevice];
// let the scripts know
Con::executef(2,"gameCenterAuthenticationChanged","1");
}else{
Con::executef(2,"gameCenterAuthenticationChanged","0");
}
}];
}
- (void)registerForAuthenticationNotification
{
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
[nc addObserver: self selector:@selector(authenticationChanged) name:GKPlayerAuthenticationDidChangeNotificationName object:nil];
}
- (void)authenticationChanged
{
isAuthenticated = NO; // assume the player isn't authenticated
gameCenterAvailable = isGameCenterAvailable();
if(!gameCenterAvailable){
return;
}
if ([GKLocalPlayer localPlayer].isAuthenticated){
// Insert code here to handle a successful authentication.
isAuthenticated = YES;
// report any unreported scores or achievements
[self retrieveScoresFromDevice];
[self retrieveAchievementsFromDevice];
// let the scripts know
Con::executef(2,"gameCenterAuthenticationChanged","1");
}else{
Con::executef(2,"gameCenterAuthenticationChanged","0");
}
}
- (BOOL)isAuthenticated
{
return gameCenterAvailable && isAuthenticated;
}
//--------------------------------------------------------
// Leaderboard
//--------------------------------------------------------
- (void)reportScore:(int64_t)score forCategory:(NSString*)category
{
if(!gameCenterAvailable)
return;
GKScore *scoreReporter = [[[GKScore alloc] initWithCategory:category] autorelease];
if(scoreReporter){
scoreReporter.value = score;
[scoreReporter reportScoreWithCompletionHandler:^(NSError *error) {
if (error != nil){
// handle the reporting error
[self saveScoreToDevice:scoreReporter];
}
}];
}
}
- (void)reportScore:(GKScore *)scoreReporter
{
if(!gameCenterAvailable)
return;
if(scoreReporter){
[scoreReporter reportScoreWithCompletionHandler:^(NSError *error) {
if (error != nil){
// handle the reporting error
[self saveScoreToDevice:scoreReporter];
}
}];
}
}
- (void)saveScoreToDevice:(GKScore *)score
{
NSString *savePath = getGameCenterSavePath();
// If scores already exist, append the new score.
NSMutableArray *scores = [[[NSMutableArray alloc] init] autorelease];
NSMutableDictionary *dict;
if([[NSFileManager defaultManager] fileExistsAtPath:savePath]){
dict = [[[NSMutableDictionary alloc] initWithContentsOfFile:savePath] autorelease];
NSData *data = [dict objectForKey:scoresArchiveKey];
if(data) {
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
scores = [unarchiver decodeObjectForKey:scoresArchiveKey];
[unarchiver finishDecoding];
[unarchiver release];
[dict removeObjectForKey:scoresArchiveKey]; // remove it so we can add it back again later
}
}else{
dict = [[[NSMutableDictionary alloc] init] autorelease];
}
[scores addObject:score];
// The score has been added, now save the file again
NSMutableData *data = [NSMutableData data];
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
[archiver encodeObject:scores forKey:scoresArchiveKey];
[archiver finishEncoding];
[dict setObject:data forKey:scoresArchiveKey];
[dict writeToFile:savePath atomically:YES];
[archiver release];
}
- (void)retrieveScoresFromDevice
{
NSString *savePath = getGameCenterSavePath();
// If there are no files saved, return
if(![[NSFileManager defaultManager] fileExistsAtPath:savePath]){
return;
}
// First get the data
NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithContentsOfFile:savePath];
NSData *data = [dict objectForKey:scoresArchiveKey];
// A file exists, but it isn't for the scores key so return
if(!data){
return;
}
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
NSArray *scores = [unarchiver decodeObjectForKey:scoresArchiveKey];
[unarchiver finishDecoding];
[unarchiver release];
// remove the scores key and save the dictionary back again
[dict removeObjectForKey:scoresArchiveKey];
[dict writeToFile:savePath atomically:YES];
// Since the scores key was removed, we can go ahead and report the scores again
for(GKScore *score in scores){
[self reportScore:score];
}
}
- (void)showLeaderboard
{
if(!isAuthenticated)
return;
GKLeaderboardViewController *leaderboardController = [[GKLeaderboardViewController alloc] init];
if (leaderboardController != nil) {
leaderboardController.leaderboardDelegate = self;
UIWindow* window = [UIApplication sharedApplication].keyWindow;
[window addSubview: gameCenterViewController.view];
[gameCenterViewController presentModalViewController: leaderboardController animated: YES];
}
}
- (void)leaderboardViewControllerDidFinish:(GKLeaderboardViewController *)viewController
{
[gameCenterViewController dismissModalViewControllerAnimated:YES];
[viewController.view removeFromSuperview];
[viewController release];
}
//--------------------------------------------------------
// Achievements
//--------------------------------------------------------
- (void)reportAchievementIdentifier:(NSString*)identifier percentComplete:(float)percent
{
if(!gameCenterAvailable)
return;
GKAchievement *achievement = [[[GKAchievement alloc] initWithIdentifier: identifier] autorelease];
if (achievement){
achievement.percentComplete = percent;
[achievement reportAchievementWithCompletionHandler:^(NSError *error){
if (error != nil){
[self saveAchievementToDevice:achievement];
}
}];
}
}
- (void)reportAchievementIdentifier:(GKAchievement *)achievement
{
if(!gameCenterAvailable)
return;
if (achievement){
[achievement reportAchievementWithCompletionHandler:^(NSError *error){
if (error != nil){
[self saveAchievementToDevice:achievement];
}
}];
}
}
- (void)saveAchievementToDevice:(GKAchievement *)achievement
{
NSString *savePath = getGameCenterSavePath();
// If achievements already exist, append the new achievement.
NSMutableArray *achievements = [[[NSMutableArray alloc] init] autorelease];
NSMutableDictionary *dict;
if([[NSFileManager defaultManager] fileExistsAtPath:savePath]){
dict = [[[NSMutableDictionary alloc] initWithContentsOfFile:savePath] autorelease];
NSData *data = [dict objectForKey:achievementsArchiveKey];
if(data) {
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
achievements = [unarchiver decodeObjectForKey:achievementsArchiveKey];
[unarchiver finishDecoding];
[unarchiver release];
[dict removeObjectForKey:achievementsArchiveKey]; // remove it so we can add it back again later
}
}else{
dict = [[[NSMutableDictionary alloc] init] autorelease];
}
[achievements addObject:achievement];
// The achievement has been added, now save the file again
NSMutableData *data = [NSMutableData data];
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
[archiver encodeObject:achievements forKey:achievementsArchiveKey];
[archiver finishEncoding];
[dict setObject:data forKey:achievementsArchiveKey];
[dict writeToFile:savePath atomically:YES];
[archiver release];
}
- (void)retrieveAchievementsFromDevice
{
NSString *savePath = getGameCenterSavePath();
// If there are no files saved, return
if(![[NSFileManager defaultManager] fileExistsAtPath:savePath]){
return;
}
// First get the data
NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithContentsOfFile:savePath];
NSData *data = [dict objectForKey:achievementsArchiveKey];
// A file exists, but it isn't for the achievements key so return
if(!data){
return;
}
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
NSArray *achievements = [unarchiver decodeObjectForKey:achievementsArchiveKey];
[unarchiver finishDecoding];
[unarchiver release];
// remove the achievements key and save the dictionary back again
[dict removeObjectForKey:achievementsArchiveKey];
[dict writeToFile:savePath atomically:YES];
// Since the key file was removed, we can go ahead and try to report the achievements again
for(GKAchievement *achievement in achievements){
[self reportAchievementIdentifier:achievement];
}
}
- (void)showAchievements
{
if(!isAuthenticated)
return;
GKAchievementViewController *achievements = [[GKAchievementViewController alloc] init];
if (achievements != nil){
achievements.achievementDelegate = self;
UIWindow* window = [UIApplication sharedApplication].keyWindow;
[window addSubview: gameCenterViewController.view];
[gameCenterViewController presentModalViewController: achievements animated: YES];
}
}
- (void)achievementViewControllerDidFinish:(GKAchievementViewController *)viewController
{
[gameCenterViewController dismissModalViewControllerAnimated:YES];
[viewController.view removeFromSuperview];
[viewController release];
}
//--------------------------------------------------------
// Goodbye
//--------------------------------------------------------
- (void)close
{
[gameCenterViewController release];
}
@end
//--------------------------------------------------------
// Wrapper
//--------------------------------------------------------
void GameCenterWrapper::authenticate(){
if(isGameCenterAvailable()){
gameCenter = [[GameCenter alloc] init];
[gameCenter authenticateLocalPlayer];
}
}
//
// If the category names are updated, make sure they are also updated in iTunes Connect.
//
void GameCenterWrapper::reportScore(int score, int category){
NSString *categoryID = [[NSString alloc] autorelease];
switch (category){
case 0:
categoryID = @"YOUR_CATEGORY_ID_0";
break;
case 1:
categoryID = @"YOUR_CATEGORY_ID_1";
break;
}
[gameCenter reportScore:score forCategory:categoryID];
}
void GameCenterWrapper::reportAchievement(int achievement){
NSString *achievementID = [[NSString alloc] autorelease];
switch (achievement){
case 0:
achievementID = @"YOUR_ACHIEVEMENT_ID_0";
break;
case 1:
achievementID = @"YOUR_ACHIEVEMENT_ID_1";
break;
}
[gameCenter reportAchievementIdentifier:achievementID percentComplete:100.0f]; // no partial achievements
}
bool GameCenterWrapper::isAuthenticated(){
return [gameCenter isAuthenticated];
}
void GameCenterWrapper::showLeaderboard(){
[gameCenter showLeaderboard];
}
void GameCenterWrapper::showAchievements(){
[gameCenter showAchievements];
}
void GameCenterWrapper::close(){
if(isGameCenterAvailable()){
[gameCenter close];
[gameCenter release];
}
}
ConsoleFunction(isGameCenterAvailable,bool,1,1,"()")
{
return isGameCenterAvailable();
}
ConsoleFunction(authenticateGameCenter,void,1,1,"")
{
GameCenterWrapper::authenticate();
}
ConsoleFunction(reportGameCenterScore,void,3,3,"(score, category id)")
{
GameCenterWrapper::reportScore(dAtoi(argv[1]),dAtoi(argv[2]));
}
ConsoleFunction(unlockGameCenterAchievement,void,2,2,"(achievement id)")
{
GameCenterWrapper::reportAchievement(dAtoi(argv[1]));
}
ConsoleFunction(isGameCenterAuthenticated,bool,1,1,"")
{
return GameCenterWrapper::isAuthenticated();
}
ConsoleFunction(showGameCenterLeaderboard,void,1,1,"")
{
GameCenterWrapper::showLeaderboard();
}
ConsoleFunction(showGameCenterAchievements,void,1,1,"")
{
GameCenterWrapper::showAchievements();
}
ConsoleFunction(closeGameCenter,void,1,1,""){
GameCenterWrapper::close();
}4. Update GameCenterWrapper::reportScore() and GameCenterWrapper::reportAchievement() to include the score category/achievement id that was set in iTunes Connect.
5. To initialize Game Center, call the following Torque Script function:
authenticateGameCenter();I put it in the initializeProject() function within game/main.cs. It needs to be one of the first things called once iTGB has initialized.
6. To close Game Center, call:
closeGameCenter();I put it within shutdownProject() of game/main.cs.
7. To add a high score, call:
reportGameCenterScore(%score,%category);
8. To award an achievement, call:
unlockGameCenterAchievement(%achievementID);
9. To show the leaderboard GUI, call:
showGameCenterLeaderboard();
10. To show the achievements GUI, call:
showGameCenterAchievements();
11. The Torque Script function gameCenterAuthenticationChanged(%isAvailable) is called whenever the authentication changes. Add this function somewhere in your game to handle logging into Game Center, such as showing the achievements or leaderboard.
Note that it is up to you to decide how you want to indicate that an achievement was achieved. There are more Game Center related functions exposed, and you can decide if you need to use them, but I haven't found a use for them.
If this code has been useful to you, I'd appreciate a War Evolved download :)
Justin
#2
11/13/2010 (12:50 am)
Thank you for posting this. This will save me a good amount of time.
#3
Thanks for sharing!
11/15/2010 (5:43 pm)
This is awesome! I'll need this for my next game (as soon as I can get this one out!)Thanks for sharing!
#4
Everything works well for me on iPhone 3Gs with OS 4.1, but on the iPad with OS 4.2.1 the showLeaderboard and showAchievements functions aren't popping up a Game Center view for me.
What's really strange about it is that I put some console print statements between each line of code in the function and everything prints out up until "[window addSubview: leaderboardController.view];". I don't see any output after that, yet my program continues running.
Any idea why the achievement and leaderboard views might not be showing under 4.2.1? Has anyone else experienced that?
11/30/2010 (6:24 am)
First off, thank you for posting this, it's a big help to see a full fledged example.Everything works well for me on iPhone 3Gs with OS 4.1, but on the iPad with OS 4.2.1 the showLeaderboard and showAchievements functions aren't popping up a Game Center view for me.
What's really strange about it is that I put some console print statements between each line of code in the function and everything prints out up until "[window addSubview: leaderboardController.view];". I don't see any output after that, yet my program continues running.
Any idea why the achievement and leaderboard views might not be showing under 4.2.1? Has anyone else experienced that?
#5
11/30/2010 (2:34 pm)
That's weird. I don't think I can help you right now, I haven't tried it on the iPad yet. I am porting War Evolved over to the iPad though and I'll probably get to Game Center mid/late December. If you haven't figured out an answer by then I'll try to help. But if you do figure out an answer please post back so I can update what is wrong.
#6
12/03/2010 (7:18 am)
Just an update: I haven't figured out what the issue is yet, but it is related to OS 4.2.1, not the iPad. Once I updated the phone to 4.2.1 the leaderboard and achievement views didn't show up there either. I suppose it's some problem with my program specifically or lots of apps would have broken with this latest iOS release :(.
#8
12/05/2010 (6:53 pm)
Thank you very much. Truly generous of you to post this.
#9
The old OpenGL template looked like this (worked only in 4.1):
Window
--OpenGL View
--Game Center View
And the new one looks like this (works in 4.1 and 4.2.1):
Window
--View Controller
----OpenGL View
----Game Center View
12/09/2010 (4:31 am)
The issue I had with OS 4.2.1 and the Game Center views not showing was fixed by re-creating the project from XCode's newer OpenGL template that has a view controller in it (the old one did not). The old OpenGL template looked like this (worked only in 4.1):
Window
--OpenGL View
--Game Center View
And the new one looks like this (works in 4.1 and 4.2.1):
Window
--View Controller
----OpenGL View
----Game Center View
#10
- (void)showLeaderboard
{
if(!isAuthenticated)
return;
GKLeaderboardViewController *leaderboardController = [[GKLeaderboardViewController alloc] init];
if (leaderboardController != nil) {
leaderboardController.leaderboardDelegate = self;
[self presentModalViewController: leaderboardController animated: YES];
UIViewController *glView = [[UIViewController alloc] init];
UIWindow* window = [UIApplication sharedApplication].keyWindow;
glView.view.frame = CGRectMake(0.0f, 0.0f, 480.0, 320.0);
[window addSubview: glView.view];
[glView.view addSubview: leaderboardController.view];
// [window addSubview: leaderboardController.view];
}
}
hope, it will be useful for someone
12/23/2010 (8:48 pm)
here is the fix for 4.2.1 about the error of modal-view present:- (void)showLeaderboard
{
if(!isAuthenticated)
return;
GKLeaderboardViewController *leaderboardController = [[GKLeaderboardViewController alloc] init];
if (leaderboardController != nil) {
leaderboardController.leaderboardDelegate = self;
[self presentModalViewController: leaderboardController animated: YES];
UIViewController *glView = [[UIViewController alloc] init];
UIWindow* window = [UIApplication sharedApplication].keyWindow;
glView.view.frame = CGRectMake(0.0f, 0.0f, 480.0, 320.0);
[window addSubview: glView.view];
[glView.view addSubview: leaderboardController.view];
// [window addSubview: leaderboardController.view];
}
}
hope, it will be useful for someone
#11
12/28/2010 (9:19 pm)
huh, now I need advice : ) submitted scores are presented if to launch GameCenter from iphone's desktop icon, but the default leaderboard is empty when I call it from game :(
#12
Thanks, and REALLY appreciated the code post.
12/29/2010 (1:26 am)
Hi, yes, I am experiencing an empty leaderboard too. In the Game Center app, my leaderboard shows up just fine with reported scores and everything. Losing hair on this. :) Anyone have any advice for when the leaderboard in game is empty but just fine in the game center app itself?Thanks, and REALLY appreciated the code post.
#13
- (void)showLeaderboard
{
if(!isAuthenticated)
return;
GKLeaderboardViewController *leaderboardController = [[GKLeaderboardViewController alloc] init];
if (leaderboardController != nil) {
leaderboardController.timeScope = GKLeaderboardTimeScopeAllTime;
leaderboardController.category = @"HighScores";
leaderboardController.leaderboardDelegate = self;
tempGameCenterVC = [[UIViewController alloc] init];
UIWindow* window = [UIApplication sharedApplication].keyWindow;
[window addSubview: tempGameCenterVC.view];
[tempGameCenterVC presentModalViewController:leaderboardController animated:YES];
}
}
- (void)leaderboardViewControllerDidFinish:(GKLeaderboardViewController *)viewController
{
[tempGameCenterVC dismissModalViewControllerAnimated:YES];
[tempGameCenterVC.view.superview removeFromSuperview];
[tempGameCenterVC release];
}
12/29/2010 (3:41 am)
Got it:- (void)showLeaderboard
{
if(!isAuthenticated)
return;
GKLeaderboardViewController *leaderboardController = [[GKLeaderboardViewController alloc] init];
if (leaderboardController != nil) {
leaderboardController.timeScope = GKLeaderboardTimeScopeAllTime;
leaderboardController.category = @"HighScores";
leaderboardController.leaderboardDelegate = self;
tempGameCenterVC = [[UIViewController alloc] init];
UIWindow* window = [UIApplication sharedApplication].keyWindow;
[window addSubview: tempGameCenterVC.view];
[tempGameCenterVC presentModalViewController:leaderboardController animated:YES];
}
}
- (void)leaderboardViewControllerDidFinish:(GKLeaderboardViewController *)viewController
{
[tempGameCenterVC dismissModalViewControllerAnimated:YES];
[tempGameCenterVC.view.superview removeFromSuperview];
[tempGameCenterVC release];
}
#14
'tempGameCenterVC' was not declared in this scope
12/29/2010 (6:32 am)
Lowell, I'm getting this when I try to replicate your fix (I am having the same issue). 'tempGameCenterVC' was not declared in this scope
#15
12/30/2010 (2:17 am)
Nevermind just had to define it in the header.
#16
12/31/2010 (7:29 am)
Keith, where/how did you define it in the header? (Sorry if this should be obvious; I know next to nothing about Obj-C.)
#17
Lowell, your solution will work except your leaking memory every time leaderboardViewControllerDidFinish is called (notice [[GKLeaderboardViewController alloc] init];).
12/31/2010 (3:58 pm)
Sorry for my silence, I just updated my original post to include the view controller. I tested by showing the achievements, not showing the leaderboard so somebody please let me know if that method doesn't work. They are basically the same though so I think it'll work.Lowell, your solution will work except your leaking memory every time leaderboardViewControllerDidFinish is called (notice [[GKLeaderboardViewController alloc] init];).
#18
01/01/2011 (4:43 pm)
This is great Justin. Consider one more War Evolved purchased. Would like to buy it more... well you deserve more than 99 cents for this. Cheers.
#19
01/02/2011 (3:09 am)
Thanks Rennie!
#20
btw I had issues, that after closing leaderboard I wasn't able to click anything in game (probably because something invisible overlaped screen : )
anyway changing this:
[gameCenterViewController dismissModalViewControllerAnimated:YES];
to this:
[self dismissModalViewControllerAnimated:YES];
helped. But it cause not appearing leaderboard anymore - seems its deleting root-obj...hm.. time to research more...
have someone issues that app is freezing when you're closing leaderboard screen ?
01/05/2011 (6:17 pm)
a function how to "get" highscores with players' names from leaderboard (with scripts interaction)? - and we are done : )btw I had issues, that after closing leaderboard I wasn't able to click anything in game (probably because something invisible overlaped screen : )
anyway changing this:
[gameCenterViewController dismissModalViewControllerAnimated:YES];
to this:
[self dismissModalViewControllerAnimated:YES];
helped. But it cause not appearing leaderboard anymore - seems its deleting root-obj...hm.. time to research more...
have someone issues that app is freezing when you're closing leaderboard screen ?
Torque 3D Owner Ronny Bangsund
Torque Cheerleaders