cocos2d-x (一): 从hello World示例中理解整个游戏框架
来源:互联网 发布:街霸5 网络 编辑:程序博客网 时间:2024/04/29 21:36
<span style="font-family: 微软雅黑; background-color: rgb(255, 255, 255);">首先找到main.cpp,程序由此进入</span>
一个游戏对应一个Application,Application的职责是管理游戏生命周期并设置默认窗口,获取平台及本地化信息。
Application::getInstance()->run() 为整个应用程序的入口。
int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow){ UNREFERENCED_PARAMETER(hPrevInstance); UNREFERENCED_PARAMETER(lpCmdLine); // create the application instance AppDelegate app; return Application::getInstance()->run();}
Application 通常不直接创建一个 Application对象,而是创建一个Appliction的子类:AppDelegate
可以在游戏入口Application::getInstance()->run()看到
if (!applicationDidFinishLaunching()) { return 0; }
在applicationDidFinishLaunching中,首先初始化一个 Director,并为Director创建一个 OpenGL ES窗口,然后创建第一个场景。
一般一些设置工作如 分辨率,帧率,资源搜索目录等都是在applicationDidFinishLaunching完成的。
一个基本的应用程序启动的初始化工作如下:
bool AppDelegate::applicationDidFinishLaunching() { auto director = Director::getInstance(); auto glview = director->getOpenGLView(); if(!glview) { glview = GLViewImpl::create("Cpp Empty Test"); director->setOpenGLView(glview); } director->setAnimationInterval(1.0 / 60); auto scene = HelloWorld::scene(); director->runWithScene(scene); return true;}
现在的操作系统基本都支持多任务,当玩家离开游戏时,应暂停游戏:
void AppDelegate::applicationDidEnterBackground() { Director::getInstance()->stopAnimation();}
当玩家回到游戏中,应恢复游戏:
void AppDelegate::applicationWillEnterForeground() { Director::getInstance()->startAnimation(); // if you use SimpleAudioEngine, it must resume here // SimpleAudioEngine::sharedEngine()->resumeBackgroundMusic();}
在 applicationDidFinishLaunching 中设置了帧率
director->setAnimationInterval(1.0 / 60);
帧率决定了游戏循环以怎样的间隔进行更新。
Application::run 驱动着游戏循环,按照帧率的设置进行游戏的循环逻辑更新,
如下是Application::run的实现
int Application::run(){ PVRFrameEnableControlWindow(false); // Main message loop: LARGE_INTEGER nLast; LARGE_INTEGER nNow; QueryPerformanceCounter(&nLast); initGLContextAttrs(); // Initialize instance and cocos2d. if (!applicationDidFinishLaunching()) { return 0; } auto director = Director::getInstance(); auto glview = director->getOpenGLView(); // Retain glview to avoid glview being released in the while loop glview->retain(); while(!glview->windowShouldClose()) { QueryPerformanceCounter(&nNow); if (nNow.QuadPart - nLast.QuadPart > _animationInterval.QuadPart) { nLast.QuadPart = nNow.QuadPart - (nNow.QuadPart % _animationInterval.QuadPart); director->mainLoop(); glview->pollEvents(); } else { Sleep(1); } } // Director should still do a cleanup if the window was closed manually. if (glview->isOpenGLReady()) { director->end(); director->mainLoop(); director = nullptr; } glview->release(); return true;}
mainLoop定义了一个游戏循环所有的事件和内容
Application::run() 在执行一次循环后,如果距离下一次更新还有空闲时间则休眠,直至下一次循环更新时间。
在applicationDidFinishLaunching 中,可以看到
auto scene = HelloWorld::scene(); director->runWithScene(scene);
auto scene = HelloWorld::scene(); 创建了一个场景
Scene* HelloWorld::scene(){ // 'scene' is an autorelease object auto scene = Scene::create(); // 'layer' is an autorelease object HelloWorld *layer = HelloWorld::create(); // add layer as a child to scene scene->addChild(layer); // return the scene return scene;}
可以看到,创建一个类调用的是 create函数,为什么不直接 new Scene()呢,我们打开create函数
Scene* Scene::create(){ Scene *ret = new (std::nothrow) Scene(); if (ret && ret->init()) { ret->autorelease(); return ret; } else { CC_SAFE_DELETE(ret); return nullptr; }}
可以看到在create函数中,先是new一个对象,然后调用对象的init方法,并把改对象加入cocos2d-x的内存管理中,设置为自动释放。
cocos2d-x中所以对象都是继承自ref基类,Ref基类主要职责就是对对象进行引用技术管理。用autorelease()方法声明一个对象指针为智能指针,但是这些智能指针并不单独关联某个自动变量,而是全部被加入一个AutoreleasePool中,在每一帧结束的时候加入AutoreleasePool中的对象进行清理。所以,在cocos2d-x中,一个智能指针的生命周期从被创建开始,到当前帧结束时结束。
一个类的初始化工作一般都在init中完成
在HelloWorld::init中,所完成的工作有
创建了一个菜单,一个字符标签和一个精灵。
Director::getInstance()->getVisibleSize() 获取窗口大小
Director::getInstance()->getVisibleOrigin() 获取游戏坐标,默认为左下角(0,0)
创建菜单的代码:
auto closeItem = MenuItemImage::create( "CloseNormal.png", "CloseSelected.png", CC_CALLBACK_1(HelloWorld::menuCloseCallback,this)); closeItem->setPosition(origin + Vec2(visibleSize) - Vec2(closeItem->getContentSize() / 2)); // create menu, it's an autorelease object auto menu = Menu::create(closeItem, nullptr); menu->setPosition(Vec2::ZERO); this->addChild(menu, 1);
在这里是使用图片来创建菜单,默认时按钮图片为CloseNormal.png 选中时为CloseSelected.png,并添加了一个监听,菜单被点击时调用menuCloseCallback函数。
使用setPosition 在设置菜单的位置,通过this->addChild(menu, 1) 把菜单放置到场景的层中,1代表显示的优先级
创建字符标签和精灵(背景图片)都是使用类似的方法,先调用create创建,然后用setPosition设置位置,通过addChild加入层中。
场景初始化完毕后,
director->runWithScene(scene);
运行场景。游戏的第一个场景运行使用 runWithScene 方法
后面场景运行都是使用 director->replaceScene(newScene) 替换当前场景。
程序运行效果:
0 0
- cocos2d-x (一): 从hello World示例中理解整个游戏框架
- 【Cocos2d-x 游戏开发】 1 --- Hello World
- 【入门精选】cocos2d-x从Hello World开始
- cocos2d编译运行‘Hello World’示例项目
- Cocos2d-x--"Hello World"深入分析
- cocos2d-x教程1 hello world
- cocos2d-x之浅析Hello World
- cocos2d-x-3.3rc2-001-hello-world
- cocos2d-x 的安装以及hello world
- 【麦可网】Cocos2d-X跨平台游戏开发学习笔记---第五课:Hello World
- Cocos2D-X框架理解
- 【cocos2d-x游戏开发】 从零单排之(一)
- cocos2d 游戏开发:Cocos2d v3 "hello world"+显示飞船
- Irrlicht引擎手册示例(一):Hello,World!
- Irrlicht引擎手册示例(一):Hello,World!
- 从今天开始就要把整个一生交给前端开发了,先打上一句 hello world
- eclispe4.x插件开发一:hello world
- cocos2d-js中Hello World代码分析
- Cocos2dx移植到Android报错问题,原因getIntegerForKey数据存储问题
- poj 2488 暴搜
- Linux那些事儿 之 戏说USB(33)字符串描述符
- visual studio 2013 ultimate 激活码
- 水NOJ Duplicate Removal
- cocos2d-x (一): 从hello World示例中理解整个游戏框架
- Struts2学习笔记(三)之StrutsTypeConversion
- Machine Learning - XIV. Dimensionality Reduction降维 (Week 8)
- Struts之ActionForward详细介绍
- Java基础第十三天--Set, HashSet, TreeSet
- 【Shader】变量定义
- 管理Git的内容4.
- hdu 1203
- hadoop 生态系统1