Where do I create a new view controller for game center achievement list?

All online tutorials say to make this function but I dont know where to put it and it gets a lot of errors.

void showAchievements()
{
    //if (hasGameCenter)
    GKAchievementViewController *achievements = [[GKAchievementViewController alloc] init];
    if (achievements != nil)
    {
        achievements.achievementDelegate = self;

        // Create an additional UIViewController to attach the GKAchievementViewController to
        UIViewController *myViewController = [[UIViewController alloc] init];

        // Add the temporary UIViewController to the main OpenGL view
        [[[CCDirector sharedDirector] openGLView] addSubview:myViewController.view];

        [myViewController presentModalViewController:achievements animated:YES];
    }
    [achievements release];
}

It doesn’t like the part about ‘self’. Sorry I’m new to obj-c so I’m having a hard time. I’m already authenticating the player properly and giving achievements I just cant get the achievement view to work. Thanks everyone.

Did you use cocos2d-x?

Yes I am using cocos2d-x

// Add the temporary UIViewController to the main OpenGL view
[[[CCDirector sharedDirector] openGLView] addSubview:myViewController.view];

In cocos2d-x you can not use it like this, because CCDirector is a c*+ class.
May be you should learn how to mix use c*+ and object-c first.

I’m already mixing c++ and obj-c using a .mm file but I don’t fully understand obj-c. Do you mind showing me how this code should be so I can learn from you? Thank you.

You can refer CocosDenshion/iphone/SimpleAudioEngine.mm and CocosDenshion/include/SimpleAudionEngine.h.

SimpleAudioEngine shows how to mix c++ and obj-c which I’m already doing fine. My issue is with the function listed in my original post. How can I rewrite the above function to work with cocos2d-x director?

I put this in AppController.mm, and it seems to work. Is this a bad way to do it?

+ (void) ShowAchievements
{
    GKAchievementViewController *achievements = [[GKAchievementViewController alloc] init];

    if (achievements != nil)
    {
        //bool test = true;
        achievements.achievementDelegate = self;

        // Create an additional UIViewController to attach the GKAchievementViewController to
        myViewController = [[UIViewController alloc] init];

        cocos2d::CCDirector::sharedDirector()->purgeCachedData();

        // Add the temporary UIViewController to the main OpenGL view
        //[[[CCDirector sharedDirector] openGLView] addSubview:myViewController.view];
        EAGLView *view = [EAGLView sharedEGLView];
        [view addSubview:(myViewController.view)];

        [myViewController presentModalViewController:achievements animated:YES];
    }
    [achievements release];
}

+ (void)achievementViewControllerDidFinish:(GKAchievementViewController *)viewController
{
    [myViewController dismissModalViewControllerAnimated:YES];
    [myViewController release];
}

This works, however while in the achievement view page if I tap around on the screen then close the window when my game returns to view the iPhone keyboard will pop up and wont go away. I have to restart the app to get rid of the keyboard. Does anyone know why this might be happening? Thanks a million!

1 Like

this is how I did for leaderboard
First a OpenFeintCppBridge.m file with

#include 
#import 
#import "AppController.h"

void displayLeaderBoard(void)    
{    
    UIViewController    *tempVC;
    tempVC=[[UIViewController alloc] init];
    GKLeaderboardViewController *leaderboardController = [[[GKLeaderboardViewController alloc] init] autorelease];
    if (leaderboardController != nil)
    {
        UIApplication* clientApp = [UIApplication sharedApplication];
        UIWindow* topWindow = [clientApp keyWindow];
        if (!topWindow)
        {
            topWindow = [[clientApp windows] objectAtIndex:0];
        }
        [topWindow addSubview:tempVC.view];
        leaderboardController.leaderboardDelegate = (AppController *)[UIApplication sharedApplication].delegate;
        [tempVC presentModalViewController:leaderboardController animated: YES];
    }
}   

OpenFeint-C-interface.h

#ifndef flying_panda_OpenFeint_C_interface_h
#define flying_panda_OpenFeint_C_interface_h
extern "C"
{
    void displayLeaderBoard(void);
}
#endif

in AppController.mm
add

- (void)leaderboardViewControllerDidFinish:(GKLeaderboardViewController *)LeaderboardViewController
{
    [LeaderboardViewController dismissModalViewControllerAnimated:YES];
}

in AppController.h
add the GKLeaderboardViewControllerDelegate protocole

When you want to popup leaderboard in your cpp files
#include “OpenFeint-C-interface.h”
displayLeaderBoard();

Got this inside OpenFeint last sdk
Using EAGLview missplace the view in my case

Hmm, on the line where you set the .leaderboardDelegate I get an error…

Assigning to ‘id’ from incompatible type ‘AppController *’

you probably forget to

in AppController.h
add the GKLeaderboardViewControllerDelegate protocole

well after that you lose all touch event

Fixed much simpler

void displayLeaderBoard(void)    
{    
    GKLeaderboardViewController *leaderboardController = [[[GKLeaderboardViewController alloc] init] autorelease];
    if (leaderboardController != nil)
    {
        UIApplication* clientApp = [UIApplication sharedApplication];


        UIWindow* topWindow = [clientApp keyWindow];
        if (!topWindow)
        {

            topWindow = [[clientApp windows] objectAtIndex:0];
        }
        leaderboardController.leaderboardDelegate = (AppController *)clientApp.delegate;
        [((AppController *)clientApp.delegate).getViewController presentModalViewController:leaderboardController animated: YES];
    }
}  

and adding getViewController method to AppController.mm

-(RootViewController*)getViewController
{
    return viewController;
}
- (void)leaderboardViewControllerDidFinish:(GKLeaderboardViewController *)LeaderboardViewController
{
    [LeaderboardViewController dismissModalViewControllerAnimated:YES];
    [LeaderboardViewController becomeFirstResponder];
}

And in AppController.h

-(RootViewController*)getViewController;

I still get Assigning to ‘id’ from incompatible type ‘AppController *’ error on this line:

leaderboardController.leaderboardDelegate = (AppController *)clientApp.delegate;

Weird thing is, I don’t even have any text boxes in my project so I have no idea why the keyboard even thinks it’s supposed to pop up in the first place.

The only thing that comme to my mind is that you are missing GKLeaderboardViewControllerDelegate in
AppController.h

@class RootViewController;
#import 
#import 
@interface AppController : NSObject  {
    UIWindow *window;
    RootViewController  *viewController;
}
-(RootViewController*)getViewController;
@end

Joseph - thanks for the help, you’ve solved my problem!

One thing though, what is the difference between putting a + or - before the function names? I’ve noticed that you get different results using each, and sometimes even errors, or callbacks that don’t get called. Is it a private/public type of identifier or something?

  • is for normal method for a class
  • is for static method like in c++