因为项目需要,明年有用到 cocos2dx 3.x, 下了个最新版3.9打算系统的研究一番,写一些笔记算是加深一些印象把~
1.用cocos 控制台 new 一个项目(一个lua项目)
2.开始分析cocos代码:
main.cpp
int APIENTRY _tWinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPTSTR lpCmdLine,int nCmdShow) { UNREFERENCED_PARAMETER(hPrevInstance); UNREFERENCED_PARAMETER(lpCmdLine); auto simulator = SimulatorWin::getInstance(); return simulator->run(); }3.9版本的PC代码用 SimulatorWin 类对应用程序进行了封装
在run里面执行了主程序的循环
SimulatorWin 为一个单例,属性如下:
static SimulatorWin *_instance; ProjectConfig _project; HWND _hwnd; HWND _hwndConsole; AppDelegate *_app; FILE *_writeDebugLogFile;
其核心方法为 run,大概归纳下其作用(用处不大不不必深究)
<span style="font-size:14px;">int SimulatorWin::run() {</span>
<span style="font-size:14px;"> //解析项目的config.txt文件 parseCocosProjectConfig(_project); <span style="white-space:pre"> </span> // load project config from command line args vector<string> args; for (int i = 0; i < __argc; ++i) { wstring ws(__wargv[i]); string s; s.assign(ws.begin(),ws.end()); args.push_back(s); } _project.parseCommandLine(args); if (_project.getProjectDir().empty()) { if (args.size() == 2) { // for Code IDE before RC2 _project.setProjectDir(args.at(1)); _project.setDebuggerType(kCCRuntimeDebuggerCodeIDE); } } // create the application instance _app = new AppDelegate(); <span style="white-space:pre"> </span> // create console window if (_project.isShowConsole()) { AllocConsole(); _hwndConsole = GetConsoleWindow(); if (_hwndConsole != NULL) { ShowWindow(_hwndConsole,SW_SHOW); BringWindowToTop(_hwndConsole); freopen("CONOUT$","wt",stdout); freopen("CONOUT$",stderr); HMENU hmenu = GetSystemMenu(_hwndConsole,FALSE); if (hmenu != NULL) { DeleteMenu(hmenu,SC_CLOSE,MF_BYCOMMAND); } } }</span>
<span style="font-size:14px;"><span style="white-space: pre;"> </span> // set environments SetCurrentDirectoryA(_project.getProjectDir().c_str()); FileUtils::getInstance()->setDefaultResourceRootPath(_project.getProjectDir()); FileUtils::getInstance()->setWritablePath(_project.getWritableRealPath().c_str()); // check screen DPI HDC screen = GetDC(0); int dpi = GetDeviceCaps(screen,LOGPIXELSX); ReleaseDC(0,screen); // set scale with DPI // 96 DPI = 100 % scaling // 120 DPI = 125 % scaling // 144 DPI = 150 % scaling // 192 DPI = 200 % scaling // http://msdn.microsoft.com/en-us/library/windows/desktop/dn469266%28v=vs.85%29.aspx#dpi_and_the_desktop_scaling_factor // // enable DPI-Aware with DeclareDPIAware.manifest // http://msdn.microsoft.com/en-us/library/windows/desktop/dn469266%28v=vs.85%29.aspx#declaring_dpi_awareness float screenScale = 1.0f; if (dpi >= 120 && dpi < 144) { screenScale = 1.25f; } else if (dpi >= 144 && dpi < 192) { screenScale = 1.5f; } else if (dpi >= 192) { screenScale = 2.0f; } CCLOG("SCREEN DPI = %d,SCREEN SCALE = %0.2f",dpi,screenScale); // create opengl view Size frameSize = _project.getFrameSize(); float frameScale = 1.0f; if (_project.isRetinaDisplay()) { frameSize.width *= screenScale; frameSize.height *= screenScale; } else { frameScale = screenScale; } const Rect frameRect = Rect(0,frameSize.width,frameSize.height); ConfigParser::getInstance()->setInitViewSize(frameSize); const bool isResize = _project.isResizeWindow(); std::stringstream title; title << "Cocos Simulator - " << ConfigParser::getInstance()->getInitViewName(); initGLContextAttrs(); auto glview = GLViewImpl::createWithRect(title.str(),frameRect,frameScale); _hwnd = glview->getWin32Window(); player::PlayerWin::createWithHwnd(_hwnd); auto director = Director::getInstance(); director->setOpenGLView(glview); director->setAnimationInterval(1.0 / 60.0); // set window position if (_project.getProjectDir().length()) { setZoom(_project.getFrameScale()); } Vec2 pos = _project.getWindowOffset(); if (pos.x != 0 && pos.y != 0) { RECT rect; GetWindowRect(_hwnd,&rect); MoveWindow(_hwnd,pos.x,pos.y,rect.right - rect.left,rect.bottom - rect.top,FALSE); } // path for looking Lang file,Studio Default images FileUtils::getInstance()->addSearchPath(getApplicationPath().c_str()); // prepare FileUtils::getInstance()->setPopupNotify(false); _project.dump(); auto app = Application::getInstance(); g_oldWindowProc = (WNDPROC)SetWindowLong(_hwnd,GWL_WNDPROC,(LONG)SimulatorWin::windowProc); // startup message loop return app->run(); }</span>
这个代码删掉了大概无用的代码段以适合自己的需要,这里大概初始化了AppDelegate、OpenglView、Director 后进入主消息循环,
在 SimulatorWin::windowProc 里面处理的是simulator 所需的App事件,例如系统菜单按下、系统拖拽事件等。
不像2.x版本 处理触摸、字符输入时间在窗口回调里面处理,3.x用了glfw 一个跨平台库弄出来的回调里面处理的,具体的流程也没必要深究了。
在新增的libsimulator库里面,有2个地方有用:
1.config相关的代码 处理 命令行参数以及config.txt 用他来快速进行简单的相关程序配置,能用现成的就用现成的呵呵。
2.service 支持跨平台的系统调用接口 例如菜单、进程管理、FileDialog、EditBox等,对于工具的开发将有很大的作用、依据需求可能以后可能对这个service进行扩展。
OK,大概记录这么多,下一篇整理 lua engine、 lua stack 整合 自己的lua开发架构。
ps、入手这个不是为了做游戏,而是为了做工具、目标能够跑在 win32 和 mac上。
原文链接:https://www.f2er.com/cocos2dx/340696.html