cocos2d-x 3.2 中的重要类总结
来源:互联网 发布:erp软件推荐 编辑:程序博客网 时间:2024/06/06 13:56
~~~~我的生活,我的点点滴滴!!
基于cocos2dx 3.2版
cocos2d-x引擎中几个主要类做了简单的介绍:Director, Application, Node, Renderer, EventDispatcher, Scheduler等对于这些类简短的介绍,在心里有个大概。
1、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;}
2、Director
主要函数预览:
//openGL Matrix Operate在3.0里面没有,尼吗我用的是3.0蛋疼无比 void 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 Data inline 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 Setter Scheduler* 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 Scenevoid Director::drawScene(){ ... if (! _paused) { _scheduler->update(_deltaTime); //Scheduler 定时器 更新 _eventDispatcher->dispatchEvent(_eventAfterUpdate); //Dispatcher 抛发事件. } glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //glClear if (_nextScene) //取得下一个将要显示的Scene. { setNextScene(); } pushMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW); //将上一次绘制的Context放到堆栈 // draw the scene if (_runningScene) { _runningScene->visit(_renderer, Mat4::IDENTITY, false); _eventDispatcher->dispatchEvent(_eventAfterVisit); } _renderer->render(); //渲染 _eventDispatcher->dispatchEvent(_eventAfterDraw); popMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW); //返回到上一次绘制时的状态. // swap buffers if (_openGLView) { _openGLView->swapBuffers(); //把上面渲染的结果显示到屏幕 } ...}
3、Node
visit()的主要功能就是:
1、调用所有孩子的visit函数
2、调用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 it Director* 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 < 0 for( ; i < _children.size(); i++ ) { auto node = _children.at(i); if ( node && node->_localZOrder < 0 ) node->visit(renderer, _modelViewTransform, flags); else break; } // self draw this->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);}
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的绘制函数:
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怎么构造和执行的。
4、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();
可见它主要由两个功能:
1、对ReanderCommand进行排序和分类管理。
2、进行渲染:render()
渲染函数Renderer::render()
void Renderer::render(){ ... if (_glViewAssigned) { ... //排列渲染队列 for (auto &renderqueue : _renderGroups) { renderqueue.sort(); } //进行渲染 visitRenderQueue(_renderGroups[0]); ... } ...}
5、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的其它大部分方法, 要么
是它的衍生, 为了减少调用参数; 要么是对定时操作的控制, 比如暂停, 恢复, 移除等。
6、EventDispatcher
EventDispatcher,EventListener,Event之间的关系如下:
1、EventDispatcher: 事件分发器, 相当于所有事件的中控中心. 管理着EventListener,当一个Event到来的时候决定CallBack的调用顺序。
2、Event ( EventTouch, EventKeyboard 等), 具体的事件数据等。
3、EventListener ( EventListenerTouch, EventListenerKeyboard 等 ): 建立了Event到CallBack的映射关系, EventDispatcher 根据这种映射关系调用对应的 CallBack。
6.1、Event
enum class Type { TOUCH, KEYBOARD, ACCELERATION, MOUSE, FOCUS, CUSTOM };
Event最重要的属性就是type, 标识了它是那种类型的事件, 也决定了由哪个EventListner来处理它。
6.2、EventListener
enum class Type { UNKNOWN, TOUCH_ONE_BY_ONE, TOUCH_ALL_AT_ONCE, KEYBOARD, MOUSE, ACCELERATION, FOCUS, CUSTOM };
除了UNKNOWN, 跟Event::Type相比,Event::Type::TOUCH会同时被两种类型的EventListener处理: TOUCH_ONE_BY_ONE和TOUCH_ALL_AT_ONCE。这两种EventListener分别
处理单点触摸事件和多点触摸事件。多说几句: 假如一个TouchEvent事件中有多个触摸点, 那么类型为EventListener::Type::TOUCH_ONE_BY_ONE的EventListener会把
这个事件分解成若干个单点触摸事件来处理。而类型为EventListener::Type::TOUCH_ALL_AT_ONCE 的 EventListener 就是来处理多点触摸的, 会一次处理它,其它几
种类型都是一一对应的, 即一种Event::Type的Event会被对应类型的EventListener接受。
6.3、存放 EventListener 的地方
在EventDispatcher中, 它把以上7种 EventListener::Type 类型的 EventListner 放到7个队列中. 也就是在这样一个字段中:
std::unordered_map<EventListener::ListenerID, EventListenerVector*> _listenerMap;
1、EventListener::ListenerID : 每一种EventListener::Type有唯一的 EventListener::ListenerID. 其实通过这段代码typedef std::string ListenerID; 可
知: EventListener::ListenerID 就是简单 string, 就是一个名称而已。
2、EventListenerVector: 顾名思义, 就是一个 EventListener 的向量容器. 相对于普通的向量容器, 它增加了priority管理功能。
6.4、EventListener的fixedPriority
6.5、EventListener的遍历顺序
EventListener 处理之后, 会停止遍历其它的 EventListener。反映到实战中就是: 你监听了某种事件, 这种事件也出发了, 但是对应的回调函数并没有被调用, 也就是
被优先级更高的 EventListener 截获了。
如果 fixedPriority 一样呢? 按照什么顺序?
1、fixedPriority 为0, 这个值是专门为 Scene Object 预留的。即默认情况下, 绝大多数继承自 Node 的对象添加的普通事件监听器,其 fixedPriority 都为0。此
时, Node 的 globalZOrder 决定了优先级, 值越大, 越先被遍历到, 即在显示层中层级越高, 越先接受事件,这在ui响应逻辑中也是合理的。
2、fixedPriority 不为0, 那就按添加顺序。
6.6、Event在什么条件下会被优先级更高的EventListener截获?
可以用 EventListenerTouchOneByOne::setSwallowTouches(bool needSwallow) 来改变它。
2、对于其它类型的 EventLIstener, 只有在显示调用了 Event::stopPropagation() 的时候, 才会中断遍历。
6.7、EventDispatcher::dispatchEvent()
void EventDispatcher::dispatchEvent(Event* event);
当有响应的事件到来的时候, 都会调用这个函数来通知监听了此事件的对象。
其实上面的介绍, 已经把这个函数里绝大部分逻辑都描述了,这里做一个最后的总结。
事件抛发的简要流程如下:
1、检查 _listenerMap 中所有的 EventListnerVector, 如果哪个容器的 EventListener 优先级顺序需要更新, 则重新排序。
2、对于类型为 Event::Type::TOUCH 的事件, 则按照 EventListener 的遍历顺序遍历所有的 EventListener。只有接受了 EventTouch::EventCode::BEGAN 事件的 EventListener,
才会收到其他类型的 EventTouch 事件。
3、对于其他类型的事件, 也按照EventListener的遍历顺序的顺序遍历对应的EventListener。
6.8、总结
总的来说, Eventdispatcher 是一个中转器:
1、事件的产生模块儿, 只关心自己构造正确的 Event, 调用 EventDispatcher::dispatchEvent(Event* event) 交给 EventDispatcher。
2、需要监听事件的模块儿, 只需调用 EventDispatcher::addEventListener(EventListener* listener) (或者它的其它变种)来注册自己作为监听者。
3、EventDispatcher 的作用是:
3.1、把特定类型的 Event 送给对应类型的 EventListener。
3.2、对于同一种 Event, 规定了事件送达的优先级。
- cocos2d-x 3.2 中的重要类总结
- Cocos2d-x 3.2中重要类的总结
- cocos2d-x中的几个重要概念
- cocos2d-x中的导演类
- Cocos2d-x中的Vec类
- cocos2d-x中的精灵类
- Cocos2D-x 中的核心类
- cocos2d-x游戏开发(九)重要的基类CCNode
- cocos2d-x游戏开发(九)重要的基类CCNode
- cocos2d-x游戏开发(九)重要的基类CCNode
- cocos2d-x游戏开发(九)重要的基类CCNode
- Cocos2d-x 3.2节点类Node详细总结
- Cocos2d-x 3.2 -- 总结数学类Vec2/Size/Rect
- Cocos2d-x 3.2节点类Node详细总结
- Cocos2d-x 3.2 -- 总结数学类Vec2/Size/Rect
- Cocos2d中的五个重要协议
- Cocos2d-x 3.2中的三种缓存类
- Cocos2d-x 3.2中的三种缓存类
- PPT制作技巧
- C++中的main函数及其参数
- Cancel PO修复
- jvm内存区域
- SoapUI中使用Groovy脚本操作数据库
- cocos2d-x 3.2 中的重要类总结
- WebService CXF 如何设置 timeout
- 华夏快线许建:Testin云测不仅提供测试报告 还有完好产品
- linux 编程SOCKET(经典)
- 图片上传代码
- PB的关键字Create
- NGUI UISprite Tiled平铺方式出现缝隙的原因和暂时的解决方案
- java常用代码
- Eclipse提示功能设置