Cocos2d-x Scheduler

本文深入探讨了游戏引擎中的场景渲染流程,从Director类的drawScene方法入手,详细解析了从处理用户交互事件到最终渲染UI的全过程。文章强调了事件处理、Scheduler更新以及渲染前后的事件调度机制,为理解游戏引擎的运行机制提供了清晰的视角。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

// Draw the Scene
void Director::drawScene()
{
    //获取上一帧到此帧的间隔时间
    // calculate "global" dt
    calculateDeltaTime();
    
    if (_openGLView)
    {
        //处理用户交互事件
        _openGLView->pollEvents();
    }

    //tick before glClear: issue #533
    if (! _paused)
    {
        //处理延迟回调事件
        _scheduler->update(_deltaTime);
        _eventDispatcher->dispatchEvent(_eventAfterUpdate);
    }
    
    //绘制UI
    _renderer->clear();

    /* to avoid flickr, nextScene MUST be here: after tick and before draw.
     * FIXME: Which bug is this one. It seems that it can't be reproduced with v0.9
     */
    if (_nextScene)
    {
        setNextScene();
    }

    pushMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);
    
    if (_runningScene)
    {
#if CC_USE_PHYSICS
        auto physicsWorld = _runningScene->getPhysicsWorld();
        if (physicsWorld && physicsWorld->isAutoStep())
        {
            physicsWorld->update(_deltaTime, false);
        }
#endif
        //clear draw stats
        _renderer->clearDrawStats();
        
        //render the scene
        _runningScene->render(_renderer);
        
        _eventDispatcher->dispatchEvent(_eventAfterVisit);
    }

    // draw the notifications node
    if (_notificationNode)
    {
        _notificationNode->visit(_renderer, Mat4::IDENTITY, 0);
    }

    if (_displayStats)
    {
        showStats();
    }
    
    updateFrameRate();
    
    _renderer->render();
    
    //处理在绘制后发生的用户输入事件
    _eventDispatcher->dispatchEvent(_eventAfterDraw);

    popMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);

    _totalFrames++;

    // swap buffers
    if (_openGLView)
    {
        _openGLView->swapBuffers();
    }

    if (_displayStats)
    {
        calculateMPF();
    }
}

 

 

1. 全局范围内Scheduler只有一个 是处于Director下的成员对象

 2. Scheduler的update是通过Director::drawScene(dt)  调用 处于UI线程 所以在UI类内调用 无需考虑线程安全问题

 3. 调用Scheduler::update()之前 首先处理的是GLFW的PullEvents() 所以所有交互类事件都会在此之前被相应

/*! @brief Processes all pending events.
 *       处理所有待处理的事件
 *  This function processes only those events that have already been received
 *  and then returns immediately.  Processing events will cause the window and
 *  input callbacks associated with those events to be called.

        这个方法只会处理那些已经被接收的事件,并且会立即返回。 
        处理事件会调用交互事件的回调
 *
 *  This function is not required for joystick input to work.
        这个事件并不需要遥感才能工作(?)
 *
 *  @par New in GLFW 3
 *  This function is no longer called by @ref glfwSwapBuffers.  You need to call
 *  it or @ref glfwWaitEvents yourself.
        在GLFW 3中 这个方法不再被glfwSwapBuffers调用 
        你需要自行调用这个方法
 *
 *  @remarks On some platforms, a window move, resize or menu operation will
 *  cause event processing to block.  This is due to how event processing is
 *  designed on those platforms.  You can use the
 *  [window refresh callback](@ref GLFWwindowrefreshfun) to redraw the contents
 *  of your window when necessary during the operation.

        在一些特定的平台下,窗口移动/变更大小/菜单栏操作将有可能阻塞事件处理。
        这取决于这些平台如何处理他们内部的事件。
        当你的窗口正在执行以上操作的时候,你可以使用GLFWwindowrefreshfun这个方法来渲染一些必要                                
        的UI
 *
 *  @note This function may only be called from the main thread.
        这个方法应该在主线程内被调用
 *
 *  @note This function may not be called from a callback.
        这个方法最好不要在回调内被调用
 *
 *  @note On some platforms, certain callbacks may be called outside of a call
 *  to one of the event processing functions.
 *      在某些平台,某些回调可能会不会再这个方法内被调用(这个有点看不懂)
 *  @sa glfwWaitEvents
 *      详细查询glfwWaitEvents
 *  @ingroup window
 */     
GLFWAPI void glfwPollEvents(void);

 4. 调用Scheduler::update()之后 才会开始渲染Scene 所以所有交互事件及Scheduler事件会在绘图之前被响应. 

 上一帧的帧内到本帧的帧前收到了点击事件 都应该在绘制UI之前被处理,如果拖到下一帧处理的话 会有延迟感

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值