加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

cocos2dx内嵌gamecenter时的解决方案

发布时间:2020-12-14 16:49:07 所属栏目:百科 来源:网络整理
导读:相信不少开发者特别是手游开发者都遇到过类似的问题。2dx使用的是带内存控制的C++语法,而gamecenter这样的apple系统组件使用的是OC语法。在程序之中要让两者兼容着实让人头疼。笔者昨天第一次尝试在2dx项目中插入gamecenter,在网上搜索了许多帖子,都不尽

相信不少开发者特别是手游开发者都遇到过类似的问题。2dx使用的是带内存控制的C++语法,而gamecenter这样的apple系统组件使用的是OC语法。在程序之中要让两者兼容着实让人头疼。笔者昨天第一次尝试在2dx项目中插入gamecenter,在网上搜索了许多帖子,都不尽如人意。后来自己摸索出一套解决方案。希望对各位有参考价值。


首先,我们需要先知悉以下几个小细节。

1.xcode编译器识别混编类时,需要将后缀改为“.mm”;
2.更改类的编译语法,可选中该类,在右侧“Type”下拉选项卡中进行选择。
3.gamecenter的使用,需要先在开发者中心设置相应的 identifier。类似于我们的身份id。

如图所示:

(图-1)

(图-2)



OK,下面开始正式说明如何具体插入gamecenter到2dx项目之中。

第一步 新建OC类,在其中插入gamecenter常用函数

为了方便,可以使用 New Group 新建一个虚拟文件夹来管理这些gamecenter逻辑类。
在文件夹下右键,新建一个OC类。


之后,再新建一个头文件与之匹配。
关键点:

*头文件需要引入以下文件:

#import <UIKit/UIKit.h>

#import <Foundation/Foundation.h>

#import <GameKit/GameKit.h>


同时,在target文件中,为项目文件导入相应的框架:



接下来,我们在头文件要至少声明这几个函数:

+ (GameKitHelper *)sharedGameKitHelper;

- (void) authenticateLocalUser;

- (void) showLeaderboard;

- (void)leaderboardViewControllerDidFinish:(GKLeaderboardViewController *)viewController;


为了方便,把最重要的显示排行榜的代码贴上来,其它的都比较简单,就不贴冗长的代码了。
- (void) showLeaderboard
{
    if (!gameCenterAvailable) return;
    GKLeaderboardViewController *leaderboardController = [[GKLeaderboardViewController alloc] init];
    if (leaderboardController != nil) {
        leaderboardController.leaderboardDelegate = self;
        UIWindow *window = [[UIApplication sharedApplication] keyWindow];
        currentModalViewController = [[UIViewController alloc] init];
        [window addSubview:currentModalViewController.view];
        [currentModalViewController presentModalViewController:leaderboardController animated:YES];
    }
}

第二步 在AppDelegate文件中预先登陆gamecenter。使用混编语法

在以上步骤提到的,我们先把AppDelegate类的后缀改为".mm"。
接着,我们在其头文件中引入第一步新建的类名 比如: #import "MyGameHelper.h"

然后,我们在

bool AppDelegate::applicationDidFinishLaunching()

这个方法中,插入登陆语句。其实就是去调用我们第一步写好的类的函数。

[[MyGameHelper sharedGameKitHelper] authenticateLocalUser];

注意,如果在第一步你新建的类中有相应的方法来实例化gamecenter,或认证gamecenter,就用你写的方法名。这里并不唯一。



第三步 新建中间类,并在需要使用gc的其它类中上传分数 (显示排行榜)


这一步比较关键,也是整个思维过程的重点。

我们再次新建一个OC类。不妨将其命名为和我一样的connect 。取意“连接”。


头文件:

//
//  connect.hpp
//  developer @fengzhengfang
//
//  Created by lanshubao on 15/12/30.
//
//

#ifndef connect_h
#define connect_h

#include <stdio.h>
class connect
{
public:
    static void showLeaderB();
    static void reportTime(int64_t score,const char* identifier);
    static void openURL();
};

#endif /* connect_hpp */

可以看到,我们在这个类声明了重要的两个方法。一是显示排行榜 showLeadB 二是上传分数reportTime


注意,我们也需要把这个类的后缀换为.mm


接着,我们在这个类的实现中导入第一步写好的gc的头文件

然后调用它。

void connect::showLeaderB(){
    //gamecenter
    [[MyGameHelper sharedGameKitHelper] showLeaderboard];
    
}
void connect::reportTime(int64_t score,const char* identifier){
    //const char *id=identifier.c_str();
    //NSString *str= [NSString stringWithCString:identifier.c_str()encoding:[NSString defaultCStringEncoding]];
    NSString * string = [NSString stringWithFormat:@"%s",identifier];
    [[MyGameHelper sharedGameKitHelper] reportScore:score forLeaderboardID:string];
   
}

现在有没有发现,我们又在c++语法函数中调用了oc呢?而且再也不会报错了。

*大家可根据自己的需要来决定传递的参数。注释部分提供了将char转化为nsstring的方法。


好啦。接下来,我们来看看上传分数的具体实现吧:


我们在要上传分数的类中只需要引入“connect.h”这个文件即可,不再需要像其他帖子中使用的多个类,而导致编译报错。


有多简单?就这么两句话:

//将记录直接上传gamecenter
    std::string cc="chapter1";
    const char *kk=cc.c_str();
    connect::reportTime(totaltime,kk);

现在调用这个函数就能像使用其它c++函数一样快捷的传递参数了。


显示呢?更简单了:

 connect::showLeaderB();


现在不仅代码耦合性下降了,而且更清晰直观。可见,使用巧妙的中间类"connect"串联起了oc和c++类,这就像两个国度的人各说各话,需要沟通时都去找翻译,这样就不会出糗了。


本文提供的中间类思路希望对大家有参考意义。希望我们早日做出牛逼的应用。

需要源码的朋友可在下面留言。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读