Cocos2dx与UIKit的混编

来源:互联网 发布:java gbk中文转utf-8 编辑:程序博客网 时间:2024/05/18 08:50

公司要求做一个Cocos2dx与原生iOS混合的Demo,所以又重新拾起了很久没用过的Cocos2dx

几年没有关注Cocos2dx了,发现它已经是一个很热门的游戏引擎了,而且社区也是欣欣向荣,要是之前坚持研究下去,说不定现在我也写出了排行榜第一的游戏了


YY到此结束,开始今天的正题吧

我使用的cocos版本是3.3rc,Xcode 6.1

之前的cocos2dx虽然也能够跨平台开发,但是各个开发环境都需要自己配置,相当的麻烦。而现在创建项目已经很方便了,只要在终端使用cocos new xxx -p xxx -l xxx -d xxx命令便能自动生成各个平台的项目,对游戏开发者来说的确是大福利

创建好项目之后,选择proj.ios_mac文件夹,就可以看到Xcode的工程文件了(在cocos2.x中,proj.ios和proj.mac是分开的)


打开Xcode,可以看到这样的目录结构

其中cocos2dx的代码在Classes中,iOS的代码在iOS中



首先我们要添加一个Storyboard,然后通过Storyboard进行界面的初始化,而不是直接加载cocos场景

添加完之后可以根据自己的喜好配置ViewController,我在VC中加入了一个MapView,用来显示地图

打开AppController.h,为其添加一个属性UIWindow *window

#import <UIKit/UIKit.h>@class RootViewController;@interface AppController : NSObject <UIApplicationDelegate> {    UIWindow *window;}@property(nonatomic, readonly) RootViewController* viewController;@property(nonatomic, strong) UIWindow *window;@end

然后我们打开AppController.mm,将

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

中的代码全部注销,这部分代码是创建EAGLView并加载cocos场景的,我们将在自己创建的ViewController中实现这些功能

最后不要忘了在设置中将Main Interface设置为我们新建的Storyboard,运行,这样就能看到我们的VC了



下一步,在ViewController中显示cocos场景

我们首先创建一个MainViewController的类,并将.m文件改为.mm,这样就能处理c++代码了

在mm文件中,加入如下代码

- (void)initGLView{    eaglView = [CCEAGLView viewWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)                                     pixelFormat: kEAGLColorFormatRGBA8                                     depthFormat: GL_DEPTH_COMPONENT16                              preserveBackbuffer: NO                                      sharegroup: nil                                   multiSampling: NO                                 numberOfSamples:0 ];    glClearColor(0, 0, 0, 0);    [eaglView setBackgroundColor:[UIColor clearColor]];    eaglView.opaque = NO;    [self.view addSubview:eaglView];    [self addMenuScene];}

这里我们创建了一个CCEAGLView,这是用来加载场景的view,所有的cocos场景都在这个view中显示


- (void)addMenuScene{    cocos2d::Application *app = cocos2d::Application::getInstance();    app->initGLContextAttrs();    cocos2d::GLViewImpl::convertAttrs();    cocos2d::GLView *glview = cocos2d::GLViewImpl::createWithEAGLView(eaglView);    cocos2d::Director::getInstance()->setOpenGLView(glview);    app->run();    pScene = HelloWorld::createScene();    cocos2d::Director *pDirector = cocos2d::Director::getInstance();    pDirector->runWithScene(pScene);}

addMenuScene方法中我们把HelloWorld这个场景加载进来,运行之后应该可以看到cocos2dx经典的hello world了



我将HelloWorldScene的界面做了一些修改,并将CCDirector中setGLDefaultValues()函数中的

glClearColor(0.0f,0.0f,0.0f,1.0f)改成了四个0,这样cocos的背景便变成了透明背景

运行之后可以看到以下效果


其中蓝色部分和Cocos2dxDemo字样都是cocos中的Sprite和Label


这时尝试操作map,会发现map不响应,因为mapView其实是在eaglView的下面,eaglView将触摸操作截断了,所以我们现在要给它加上hitTest,将触摸操作传递给mapView

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event{    if (!CGRectContainsPoint(kIgnoreRect, point)) {        return nil;    }    return [super hitTest:point withEvent:event];}
如果触摸位置在非蓝色区域,那么eaglView将不响应触摸事件

运行,在蓝色区域触摸,map不会响应,而其他区域,map可以正常缩放和滚动











0 0