因为项目需要,明年有用到 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$", "wt", 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, 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上。
本文记录了使用cocos2dx3.9创建新项目的步骤,主要分析了main.cpp中的主程序循环,探讨了SimulatorWin单例的作用,包括初始化AppDelegate、OpenGLView和Director。同时提到了glfw处理输入事件,以及libsimulator库在配置管理和系统调用接口中的应用。作者强调,研究cocos2dx主要是为了开发跨平台工具,目标平台为win32和mac。

4948

被折叠的 条评论
为什么被折叠?



