cocos2d-x Maker 笔记(一)

与cocos相伴4年了,从起初的cocos2d到如今的cocos2d-x,静静地看着触控拖沓的前进着。一路沿着cocos的代码一点一点学习游戏开发,对cocos的感情难以言喻,尽管cocos有着这样那样的缺陷,unity有着这样那样的优势,依然抱着cocos不肯撒手。很久很久以前就想自己动手写一个基于cocos的编辑器,但是一会儿我一个小屁程序员怎么搞的定,一会儿想想cocosstudio几百个人的团队做着呢,一会儿想想这么一个没钱途的事情,做了有什么意义,一会儿想想就自己那懒样,哪能做得起那么大一个工程,就硬生生的一直拖着。不过最近呢有些想通了,平时多余的时间拼命想着怎么赚钱压力大而且真的赚不到什么,发发呆又有些浪费,那么就发展一下兴趣爱好吧,正好又看到“红孩儿”博客写的“一个勤奋的人 可以超越一家懒惰的公司”,真的是人生榜样。当然了,我非常的有自知之明,自己绝不是勤奋之人,平时是能省一分力觉不会多浪费一厘。拿起很久很久以前的兴趣,着手自己diy一个cocos的编辑器。(之后文中出现的cocos一般就是指的cocos2d-x)

步入正题,关于编辑器,我选择在mac平台上开发,纯属个人爱好。在实现方式上,我选择重用大部分cocos引擎的代码,在引擎代码之上拦截Events,重新提供一套编辑器使用的mainloop和事件的处理方案。

那么,第一件事,就是重写编辑器专用的GLViewImpl,查看cocos的代码之后,差点吐血,在mac和windows上完全是使用glfw创建了一个不可改变大小的窗口,然后再看看glfw的代码,stop了objc的runloop,自己另起炉灶,然后cocos在代码里写了一个

while(!_exit) {
    mainloop();
    sleep();
}

,这让我只是在mac版本上简单修改扩展的梦想完全破灭。虽然glfw做了很多便捷的处理,但是我是没有办法通过glfw和mac app一起混编。只好自己动手了,一步一步来实现一个GlView。鉴于方便的考虑,我的代码只直接使用cocos2dx 3.8创建了一个空项目,然后在项目生成的ios_mac工程中修改的,那第一件事的第一步就是新建一个editor专用的target,咱要从main.m开始重写了,建好基本的mac应用需要的内容,目录大致如下:

其中CXMMainView将作为编辑器的主窗口(暂时没他什么事),CCGLViewImpl-CXM就是这次的重点,重写的GLView。

重写create方法首当其冲,原本的CCGLViewImple-desktop在create中主要做了3件事,设置glfw窗口需要的参数,设置glfw窗口事件的回调,最后创建opengl窗口,我们要做的呢就是从glfw源码中把相关的代码一点一点挖出来,其实还是很简单的,直接贴上一些代码:

在.h中增加一些属性方法:

bool initWithRect(const std::string& viewName, Rect rect, float frameZoomFactor);

void* _glView;
void* _glPixelFormat;
void* _glContext;

在.mm增加实现:

bool CXMGLViewImpl::initWithRect(const std::string& viewName, Rect rect, float frameZoomFactor)
{
    setViewName(viewName);
    _screenSize = rect.size;
    _designResolutionSize = rect.size;
    _frameZoomFactor = frameZoomFactor;
    _viewPortRect = rect;

    //init view
    _glView = [[NSView alloc] initWithFrame:NSMakeRect(0, 0, _screenSize.width, _screenSize.height)];

    //init pixel format
#define ADD_ATTR(x) { attributes[attributeCount++] = x; }
#define ADD_ATTR2(x, y) { ADD_ATTR(x); ADD_ATTR(y); }
    unsigned int attributeCount = 0;
    NSOpenGLPixelFormatAttribute attributes[40];
    ADD_ATTR(NSOpenGLPFAAccelerated);
    ADD_ATTR(NSOpenGLPFAClosestPolicy);
    ADD_ATTR2(NSOpenGLPFAAuxBuffers, 0);
    ADD_ATTR2(NSOpenGLPFAAccumSize, 0);
    int colorBits = _glContextAttrs.redBits + _glContextAttrs.greenBits + _glContextAttrs.blueBits;
    ADD_ATTR2(NSOpenGLPFAColorSize, colorBits);
    ADD_ATTR2(NSOpenGLPFAAlphaSize, _glContextAttrs.alphaBits);
    ADD_ATTR2(NSOpenGLPFADepthSize, _glContextAttrs.depthBits);
    ADD_ATTR2(NSOpenGLPFAStencilSize, _glContextAttrs.stencilBits);
    ADD_ATTR(NSOpenGLPFADoubleBuffer);
    ADD_ATTR2(NSOpenGLPFASampleBuffers, 4);
    ADD_ATTR(0);
#undef ADD_ATTR
#undef ADD_ATTR2

    _glPixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:attributes];

    if(!_glPixelFormat) {
        MessageBox("Failed to create pixel format.", "error");
        return false;
    }

    //init content
    _glContext = [[NSOpenGLContext alloc] initWithFormat:(NSOpenGLPixelFormat*)_glPixelFormat shareContext:nil];

    [(NSOpenGLContext*)_glContext setView:(NSView*)_glView];
    [(NSOpenGLContext*)_glContext makeCurrentContext];

    // check OpenGL version at first
    const GLubyte* glVersion = glGetString(GL_VERSION);

    if ( utils::atof((const char*)glVersion) < 1.5 )
    {
        char strComplain[256] = {0};
        sprintf(strComplain,
                "OpenGL 1.5 or higher is required (your version is %s). Please upgrade the driver of your video card.",
                glVersion);
        MessageBox(strComplain, "OpenGL version too old");
        return false;
    }

    // Enable point size by default.
    glEnable(GL_VERTEX_PROGRAM_POINT_SIZE);

    return true;
}

其中大多数的代码都是搬来搬去复制过来的,请叫我大自然的搬运工。剩下还有一些简单重写的方法,比如isOpenGLReady、swapBuffers等等就不贴出来了。

未完待续,还有关于frameSize, viewport和坐标转换部分。

时间: 2024-10-23 17:57:58

cocos2d-x Maker 笔记(一)的相关文章

cocos2d基础篇笔记四

1.//有两种集合 //第一种是array 特点:插入,删除效率低,可是查找效率高 //另外一种是list  特点:插入,删除效率高,可是查找效率低 //分析这个游戏: 插入的时候:怪物,射弹出现时,删除的时候:碰撞时,怪物.射弹出界时. //遍历:fps(每秒中填充图像的帧数(帧/秒)相应的时间,怪物是2秒出现一次,而遍历是60次每秒,可见遍历用的较多,所以我们选择array. CCArray*_targets;//定义怪物集合,3.0一般用vector定义集合 CCArray*_projs;

[cocos2dx笔记008]cocos2d 用luabridge手动绑定类

基于cocos2dx 2.2.2版本.这几天使用了cocostudio实现了,动画,骨骼动画,UI编辑,粒子效果,虽然有些不足,但已经算是非常好了.今天尝试用lua,这个非常简单,创建的时候,设置语言为lua,那就可以创建lua工程. 在cocos2d-x-2.2.2\tools\project-creator下运行: python create_project.py -project test_lua -package com.android.zdhsoft -language lua xco

[ios5 cocos2d游戏开发实战] 笔记3-FileUtils, notificationCenter

FileUtils //文件管理工具 FileUtils::getInstance() std::string getStringFromFile(const std::string& filename);//读取文件中的字符串 Data getDataFromFile(const std::string& filename);//获取文件数据 void setSearchPaths(const std::vector<std::string>& searchPaths

Cocos2D学习笔记(1)- 常用的类

1.坐标系 >屏幕坐标系(UIKit):原点在左上角! >OpenGl坐标系:原点在屏幕的左下角! 2.游戏设计:Director--Scene--Layer--Sprite. >CCDirector:导演类,相当于是游戏策划,负责整个游戏的布局和运行规则的制定. >CCScene:场景类,每个场景可以是一个界面或一个关卡. >CCLayer:图层类,为了方便游戏界面的渲染管理. >CCSprite:精灵类, 小结:一个导演类(CCDirector)可以指挥多个场景类(

COCOS2D 学习笔记

cc.Node.scheduleUpdate:function () * schedules the "update" method. * It will use the order number 0. This method will be called every frame. * Scheduled methods with a lower order value will be called before the ones that have a higher order va

Cocos2d-x 3.x学习笔记(一):开始Cocos2d之旅

首先,进入官网下载cocos2d-x:http://www.cocos.com/download/,当然你需要注册一个账号才可以下载. 接下来需要跟着官网的配置文档配置一下开发环境,不得不说,Cocos的官方文档非常强大,赞一个! 全新的Cocos2d-x 3.0 回归C++风格 在2.x的时代,Cocos2d-x团队是完全使用Cocos2d-iPhone的Objective-C代码风格,诸如类名的“CC”前缀(比如“CCNode”.“CCSprite”等)和单例的“sharedXXX()”命名

《黑马程序猿》 cocos2d游戏引擎复习笔记一

/** ----------------------------游戏场景的搭建-------------------------------- 1首先创建一个surfaceview ,它能够在子线程中更新UI(全局的) 2然后在oncreate方法中对这个surfaceview进行实例化 3使用setcontentview方法将这个surfaceview对象给设置到界面上显示出来 4获取一个导演 5告诉导演将画面现到surfaceview上 即让cocos2d和surfaceview对象产生关系

cocos2d-x学习笔记(三)解决cocos2d::Director没有成员getTouchDispatcher问题

初学者在学习代码阶段偶尔会把项目代码拿过来编译,然后看下运行结果再研究代码.如果别人的项目代码是用cocos2d-x 3.0之前的版本编写的,而自己用的cocos2d-x是3.0以后的,编译的时候经常会碰到如下问题: Error:class "cocos2d::Director"没有成员"getTouchDispatcher" 在3.0版本以前,之前所用的 CCTouchBegan.CCTouchMoved.CCTouchEnd这些都已经不能再用了,现在是让监听器自

[ios5 cocos2d游戏开发实战] 笔记4 socket

socket 连接 SOCKET sock_client; sock_client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (INVALID_SOCKET == sock_client) { std::cout << "Invalid socket." << std::endl; WSACleanup(); return 0; } sockaddr_in addr_sev; addr_sev.sin_fam