[cocos2d-x]深入--几个代表性的类
摘要: 此文对cocos2d-x
引擎中最具代表性,最能体现框架结构的几个类做了简单的介绍, 包括Director
,Application
, Renderer
, EventDispatcher
, Scheduler
. 对于这些类, 也只对关系主要流程的方法做了介绍, 略过了容错代码和其它细节. 主要目的是让大家快速的对cocos2d-x
引擎有一个全面笼统的认识, 也方便快速定位问题.
- 博客: http://www.cnblogs.com/jhzhu
- 邮箱: jhzhuustc@gmail.com
- 作者: 知明所以
- 时间: 2014-07-21
- GLView
- openGL
- 一段简单的例子
- OpenGL Command Syntax
- OpenGL as a State Machine
- openGL
- Application
- 主要方法:
- run()函数
- Director
- 主要函数预览
- drawScene(): 主要绘制函数
- Node::visit() 函数
- 预览
- Node::draw()
- Label::draw
- Renderer 渲染器
- 主要函数预览
- 渲染函数Renderer::render()
- Renderer::visitRenderQueue
- openGL VAO, VBO 介绍.
- Schelduler介绍
- EventDispatcher
GLView
cocos2d-x
对openGL
的封装. 不同平台下, openGL
有一些差别.
openGL
一段简单的例子
以下内容引用自Introduction to OpenGL. 需要更具体的介绍也可参考这个链接.
#include <whateverYouNeed.h>
main() {InitializeAWindowPlease();glClearColor (0.0, 0.0, 0.0, 0.0);glClear (GL_COLOR_BUFFER_BIT);glColor3f (1.0, 1.0, 1.0);glOrtho(0.0, 1.0, 0.0, 1.0, -1.0, 1.0);glBegin(GL_POLYGON);glVertex3f (0.25, 0.25, 0.0);glVertex3f (0.75, 0.25, 0.0);glVertex3f (0.75, 0.75, 0.0);glVertex3f (0.25, 0.75, 0.0);glEnd();glFlush();UpdateTheWindowAndCheckForEvents();
}
OpenGL Command Syntax
- OpenGL commands use the prefix
gl
and initial capital letters for each word making up the command name - some seemingly extraneous letters appended to some command names (for example, the
3f
inglColor3f()
andglVertex3f()
)
OpenGL as a State Machine
OpenGL is a state machine. You put it into various states (or modes) that then remain in effect until you change them.
Application
主要方法:
virtual const char * getCurrentLanguage();
virtual Platform getTargetPlatform();
virtual void setAnimationInterval(double interval);
int run();//启动主循环
run()函数
int Application::run()
{...while(!glview->windowShouldClose()){QueryPerformanceCounter(&nNow);if (nNow.QuadPart - nLast.QuadPart > _animationInterval.QuadPart){nLast.QuadPart = nNow.QuadPart;director->mainLoop(); //Director进行这一帧的渲染glview->pollEvents(); // This function processes only those events that have already been received and then returns immediately.}else{Sleep(0);}}...return true;
}
Director
主要函数预览
//openGL Matrix Operatevoid pushMatrix(MATRIX_STACK_TYPE type);void popMatrix(MATRIX_STACK_TYPE type);void loadIdentityMatrix(MATRIX_STACK_TYPE type);void loadMatrix(MATRIX_STACK_TYPE type, const Mat4& mat);void multiplyMatrix(MATRIX_STACK_TYPE type, const Mat4& mat);Mat4 getMatrix(MATRIX_STACK_TYPE type);void resetMatrixStack();//View Datainline double getAnimationInterval();inline bool isDisplayStats();inline GLView* getOpenGLView();inline Projection getProjection();Size getVisibleSize() const;Vec2 getVisibleOrigin() const;Vec2 convertToGL(const Vec2& point);Vec2 convertToUI(const Vec2& point);float getZEye() const;// Scene 场景管理inline Scene* getRunningScene();void runWithScene(Scene *scene);void pushScene(Scene *scene);// 控制绘制的暂停和恢复void end();void pause();void resume();//绘制图形(界面展示最重要的函数)void drawScene();//Getter and SetterScheduler* getScheduler() const { return _scheduler; }void setScheduler(Scheduler* scheduler);ActionManager* getActionManager() const { return _actionManager; }void setActionManager(ActionManager* actionManager);EventDispatcher* getEventDispatcher() const { return _eventDispatcher; }void setEventDispatcher(EventDispatcher* dispatcher);Renderer* getRenderer() const { return _renderer; }
drawScene(): 主要绘制函数
// Draw the Scene
void Director::drawScene()
{...if (! _paused){_scheduler->update(_deltaTime); //Scheduler 定时器 更新_eventDispatcher->dispatchEvent(_eventAfterUpdate); //Dispatcher 抛发事件.}glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //glClearif (_nextScene) //取得下一个将要显示的Scene.{setNextScene();}pushMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW); //将上一次绘制的Context放到堆栈// draw the sceneif (_runningScene){_runningScene->visit(_renderer, Mat4::IDENTITY, false);_eventDispatcher->dispatchEvent(_eventAfterVisit);}_renderer->render(); //渲染_eventDispatcher->dispatchEvent(_eventAfterDraw);popMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW); //返回到上一次绘制时的状态.// swap buffersif (_openGLView){_openGLView->swapBuffers(); //把上面渲染的结果显示到屏幕}...
}
Node::visit() 函数
预览
Node::visit() 的主要功能就是
- 调用所有孩子的
visit
函数 - 调用
self->draw()
函数
void Node::visit(Renderer* renderer, const Mat4 &parentTransform, uint32_t parentFlags)
{// quick return if not visible. children won't be drawn.if (!_visible){return;}uint32_t flags = processParentFlags(parentTransform, parentFlags);// IMPORTANT:// To ease the migration to v3.0, we still support the Mat4 stack,// but it is deprecated and your code should not rely on itDirector* director = Director::getInstance();director->pushMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);director->loadMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW, _modelViewTransform);int i = 0;if(!_children.empty()){sortAllChildren();// draw children zOrder < 0for( ; i < _children.size(); i++ ){auto node = _children.at(i);if ( node && node->_localZOrder < 0 )node->visit(renderer, _modelViewTransform, flags);elsebreak;}// self drawthis->draw(renderer, _modelViewTransform, flags);for(auto it=_children.cbegin()+i; it != _children.cend(); ++it)(*it)->visit(renderer, _modelViewTransform, flags);}else{this->draw(renderer, _modelViewTransform, flags);}director->popMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);
}
Node::draw()
因为Node
是所有可显示对象的父类, 没有任何显示内容, 所以draw
函数为空.
这里我们以Sprite::draw
函数为例简单介绍下draw
的作用.
void Sprite::draw(Renderer *renderer, const Mat4 &transform, uint32_t flags)
{// Don't do calculate the culling if the transform was not updated_insideBounds = (flags & FLAGS_TRANSFORM_DIRTY) ? renderer->checkVisibility(transform, _contentSize) : _insideBounds;if(_insideBounds){_quadCommand.init(_globalZOrder, _texture->getName(), getGLProgramState(), _blendFunc, &_quad, 1, transform);renderer->addCommand(&_quadCommand);}
}
我们看到, Sprite::draw
函数主要实现了[添加一个QuadCommand
到Render
中去]的功能.
再看看Label
的绘制函数.
Label::draw
void Label::draw(Renderer *renderer, const Mat4 &transform, uint32_t flags)
{// Don't do calculate the culling if the transform was not updated_insideBounds = (flags & FLAGS_TRANSFORM_DIRTY) ? renderer->checkVisibility(transform, _contentSize) : _insideBounds;if(_insideBounds) {_customCommand.init(_globalZOrder);_customCommand.func = CC_CALLBACK_0(Label::onDraw, this, transform, flags);renderer->addCommand(&_customCommand);}
}
其实, 跟Sprite::draw
也差不多. 关键在于这个RenderCommand
怎么构造和执行的.
Renderer 渲染器
主要函数预览
void initGLView();/** Adds a `RenderComamnd` into the renderer */void addCommand(RenderCommand* command);/** Adds a `RenderComamnd` into the renderer specifying a particular render queue ID */void addCommand(RenderCommand* command, int renderQueue);/** Pushes a group into the render queue */void pushGroup(int renderQueueID);/** Pops a group from the render queue */void popGroup();/** Creates a render queue and returns its Id */int createRenderQueue();/** Renders into the GLView all the queued `RenderCommand` objects */void render();
可见它主要由两个功能:
- 对
ReanderCommand
进行排序和分类管理 - 进行渲染:
render()
渲染函数Renderer::render()
void Renderer::render()
{...if (_glViewAssigned){...//排列渲染队列for (auto &renderqueue : _renderGroups){renderqueue.sort();} //进行渲染visitRenderQueue(_renderGroups[0]);...}...
}
Renderer::visitRenderQueue
按照顺序执行所有的 RenderCommand
void Renderer::visitRenderQueue(const RenderQueue& queue)
{ssize_t size = queue.size();for (ssize_t index = 0; index < size; ++index){auto command = queue[index];auto commandType = command->getType();if(RenderCommand::Type::QUAD_COMMAND == commandType){auto cmd = static_cast<QuadCommand*>(command);//Batch quadsif(_numQuads + cmd->getQuadCount() > VBO_SIZE){drawBatchedQuads();}_batchedQuadCommands.push_back(cmd);memcpy(_quads + _numQuads, cmd->getQuads(), sizeof(V3F_C4B_T2F_Quad) * cmd->getQuadCount());convertToWorldCoordinates(_quads + _numQuads, cmd->getQuadCount(), cmd->getModelView());_numQuads += cmd->getQuadCount();}else if(RenderCommand::Type::GROUP_COMMAND == commandType){flush();int renderQueueID = ((GroupCommand*) command)->getRenderQueueID();visitRenderQueue(_renderGroups[renderQueueID]);}else if(RenderCommand::Type::CUSTOM_COMMAND == commandType){...}...}
}
openGL VAO, VBO 介绍.
GLSL渲染语言入门与VBO、VAO使用:绘制一个三角形
OpenGL 4.0 VAO VBO 理解
Schelduler介绍
Schelduler
是cocos2d-x
中实现延迟调用,定时调用时最重要的功能. 类似于其他语言中的Timer
他最核心的函数就是:
void schedule(const ccSchedulerFunc& callback, void *target, float interval, unsigned int repeat, float delay, bool paused, const std::string& key);
用来启动一个定时操作: 在延迟delay
时间后, 每隔repeat
时间, 调用一次callback
. target
用来标记这个操作属于谁, 方便管理, 比如在析构的时候调用void unschedule(void *target)
即可移除当前对象的所有定时操作
.
Schelduler
的其它大部分方法, 要么是它的衍生, 为了减少调用参数; 要么是对定时操作
的控制, 比如暂停, 恢复, 移除等. 如果只对想对框架的各个模块有大概的了解, 可以不做深入.
EventDispatcher
(后续添加)
Written with StackEdit.
转载于:https://www.cnblogs.com/jhzhu/p/3859964.html
[cocos2d-x]深入--几个代表性的类相关推荐
- Cocos2d 3.0继承自Sprite的类在addChild后出现故障
当继承自Sprite的类被addChild到其它的Node里后出现例如以下图问题,说明没有调用父类Sprite::init()的方法.由于父类Sprite里的_textureAtlas须要初始化为nu ...
- 添加类iOS cocos2d 2游戏开发实战(第3版)
这两天一直在学习添加类之类的问题,现在正好有机会和大家讨论一下. 第1章 简介 1 1.1 第3版中的新增内容 2 1.2 选择ios版cocos2d的来由 3 1.2.1 收费 3 1.2.2 开源 ...
- cocos2D(四)---- CCSprite
在介绍CCSprite之前,先要理解游戏开发中的一个核心概念:精灵.精灵也称为游戏对象,它能够用来表示游戏中的不论什么物体,比方敌人.子弹.甚至是一个背景图片.一段文字.CCSprite能够说是在co ...
- 初探使用iOS 7 Sprite Kit与Cocos2d开发游戏的对比(一家之言)
初探使用iOS 7 Sprite Kit与Cocos2d开发游戏的对比 初探使用iOS 7 Sprite Kit与Cocos2d开发游戏的对比 发布于:2013-07-18 11:00阅读数:1984 ...
- Cocos2d使用TexturePacker工具打包生成plist和pvr.ccz文件方法总结
我们用TexturePacker工具打包生成了plist和pvr.ccz文件,那么下一步,我们就该获取plist中的信息了. Cocos2d中SpriteFrameCache通常用来处理plist文件 ...
- iOS cocos2d 2游戏开发实战(第3版)
<iOS cocos2d 2游戏开发实战(第3版)> 基本信息 原书名:Learn cocos2d 2: Game Development for iOS 作者: (美)Steffen I ...
- Cocos2d游戏开发学习记录——4.开发《植物大战僵尸》
文章目录 1.植物大战僵尸 2.开发前导 3.载入页面 4.菜单页面 & 预备战斗页面 5.植物准备页面 6.正式战斗页面 7.战斗逻辑 8.向日葵逻辑 9.进度条逻辑 10.音乐逻辑 11. ...
- 初探使用iOS 7 Sprite Kit与Cocos2d开发游戏的对比
前言 iOS7 beta发布后,大部分开发者和用户的注意力都集中在了iOS 7的全新UI交互设计界面上.一直负责硬件工业设计的Jony Ive首次全面负责苹果的软件和硬件设计工作,自然要把他自己的设计 ...
- cocos2d中的Color3B、Color4B、Color4F的使用
首先给出cocos2d标准库中的三个类的构造函数和定义,他们也是可以互相转换的 cocos2d中表示颜色有三种对象: Color3B 用三个 0-255 的整数描述颜色. Color4B 用四个 ...
最新文章
- OKR落地,实践经验总结两个点比较重要
- python 字符串部分总结
- php增删改查心得体会,php增删改查入门示例
- vb.net 功能f8键事件_笔记本电脑功能键介绍
- 对话高博(一)| 机器码、Pascal,以及计算机学习的分形
- 太阳能发电板的规格尺寸_新疆深山藏着一个村庄,至今未通水电,村民买太阳能板自行发电...
- 简单分析ComponentScan
- springboot 整合 kafka demo 顺便看一下源码
- html代码大全贴音乐,网页音乐代码大全
- 爪哇国新游记之二十六----迷宫寻路
- APUE读书笔记-04文件和目录(5)
- matlab 连通域数量,【Matlab】找到矩阵中每个连通域的最小值
- windwo下载完nvm无法执行node
- mysql 嵌套查询优化_MySQL——优化嵌套查询和分页查询
- 基于X86汇编语言的简易打字游戏实现
- ldc java_java – LDC指令代码的负值是什么意思?
- HDOJ 5296 Annoying problem LCA+数据结构
- 【PC工具】压缩包密码破解工具,暴力破解压缩包密码,zip密码获取
- 简单暴力的排序方式:直接排序
- 助力武汉抗击疫情,湖北科研资料共享