游戏中心身份验证仅适用于iOS 6的CCLayer Cocos2d

时间:2013-01-10 19:53:06

标签: iphone ios objective-c ios6 cocos2d-iphone

我遇到了一个相当常见的问题,但我的搜索和解决方案的实施还没有解决。

我已经构建了一个Cocos2d游戏,该游戏仅用于横向,但需要访问Gamecenter。 Gamecenter正在运行,启用了纵向模式,但它也允许游戏翻转到纵向模式。

我尝试了以下修复:

Game center login lock in landscape only in i OS 6

GameCenter authentication in landscape-only app throws UIApplicationInvalidInterfaceOrientation

Error in iOS 6 after adding GameCenter to a landscape-only cocos2d app

Cocos 2d 2.0 shouldAutorotate not working?

我认为问题在于我使用CCLayers而不是UIViewControllers构建了游戏

实施例: MenuLayer.h

@interface MenuLayer : CCLayer <GKAchievementViewControllerDelegate, GKLeaderboardViewControllerDelegate, UINavigationControllerDelegate>{
   ..my header info..
}

MenuLayer.m

...
-(NSUInteger)supportedInterfaceOrientations {
    return UIInterfaceOrientationMaskLandscape;
}
-(BOOL)shouldAutorotate {
    return [[UIDevice currentDevice] orientation] != UIInterfaceOrientationPortrait;
}

-(void)authenticateLocalPlayer
{

    GKLocalPlayer * localPlayer= [GKLocalPlayer localPlayer];

    if(localPlayer.authenticated == NO)
    {
        NSString *reqSysVer = @"6.0";
        NSString *currSysVer = [[UIDevice currentDevice] systemVersion];
        if ([currSysVer compare:reqSysVer options:NSNumericSearch] != NSOrderedAscending)
        {
            [[GKLocalPlayer localPlayer] setAuthenticateHandler:(^(UIViewController* viewcontroller, NSError *error) {
                if (viewcontroller != nil) {
                    AppController *app = (AppController*) [[UIApplication sharedApplication] delegate];
                    [[app navController] presentModalViewController:viewcontroller animated:YES];
                }else if ([GKLocalPlayer localPlayer].authenticated)
                {
                    //do some stuff
                }
            })];
        }
        else
        {
            [localPlayer authenticateWithCompletionHandler:^(NSError *error){
                if(localPlayer.isAuthenticated)
                {
                    //Peform Additionl Tasks for the authenticated player.
                }
            }];
        }
    }

}
...

由于我使用CCLayers而不是UIViewControllers构建游戏,我有哪些替代方案?假设CCLayers没有调用使用supportedInterfaceOrientations或者应该是否可以使用,我是否正确?

或者我应该以某种方式更改此代码以解决问题:

// Create a Navigation Controller with the Director
navController_ = [[UINavigationController alloc] initWithRootViewController:director_];
navController_.navigationBarHidden = YES;

1 个答案:

答案 0 :(得分:5)

这让我感到沮丧了一段时间。在'Net上挖了一段时间之后,我找到了几个来源,有些使用iOS 6,有些使用iOS5,但我不得不进行一些修改,以便它在iOS5和iOS6上按照我想要的方式工作。这是我正在使用的代码,它使用5.1和6在我的iPhone上运行。请注意,Game Center登录仍然以纵向方式显示,似乎没有任何关于它的操作。但游戏的其余部分将保持横向模式。

  1. 在构建设置(info.plist)中启用纵向模式作为支持的方向。
  2. 创建UINavigationController的新子类。将这个类命名为对你有意义的。
  3. 在AppDelegate中,包含新的自定义UINavigationController头文件。
  4. 在您的应用代表中,注释掉原始呼叫,然后呼叫您的自定义类。
  5. 这应该可以解决问题。以下是我的自定义类的代码:

    #import <UIKit/UIKit.h>
    
    @interface CustomNavigationViewController : UINavigationController
    
    -(UIInterfaceOrientation) getCurrentOrientation;
    
    @end
    

    执行文件:

    #import "CustomNavigationViewController.h"
    
    @interface CustomNavigationViewController ()
    
    @end
    
    @implementation CustomNavigationViewController
    
    - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
    {
        self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
        if (self) {
            // Custom initialization
        }
        return self;
    }
    
    - (void)viewDidLoad
    {
        [super viewDidLoad];
        // Do any additional setup after loading the view.
    }
    
    - (void)didReceiveMemoryWarning
    {
        [super didReceiveMemoryWarning];
        // Dispose of any resources that can be recreated.
    }
    
    // This is required to allow GameCenter to login in portrait mode, but only allow landscape mode for the rest of the game play/
    // Arrrgg!
    
    -(BOOL) shouldAutorotate {
        return YES;
    }
    
    -(NSUInteger) supportedInterfaceOrientations {
        return UIInterfaceOrientationMaskLandscape;
    }
    
    -(UIInterfaceOrientation) preferredInterfaceOrientationForPresentation {
        return UIInterfaceOrientationLandscapeRight; // or left if you prefer
    }
    
    -(NSUInteger) application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window {
        if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
            return UIInterfaceOrientationMaskLandscape;
        else {
            return UIInterfaceOrientationMaskAllButUpsideDown;
        }
    }
    
    -(BOOL) shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
        return [[UIDevice currentDevice] orientation] != UIInterfaceOrientationPortrait;
    }
    
    -(UIInterfaceOrientation) getCurrentOrientation {
        return [[UIDevice currentDevice] orientation];
    }
    
    @end
    

    请注意,上一个方法getCurrentOrientation不是必需的我只是把它放在那里,以防我想确定当前的方向是什么。

    在AppDelegate.m中调用自定义类,如下所示:(注释掉原始代码)

    navController = [[CustomNavigationViewController alloc] initWithRootViewController:director];
    window.rootViewController = navController;
    navController.navigationBarHidden = YES;
    [window makeKeyAndVisible];
    

    希望这有帮助。