This post is a code review of the game loop of Cocos2d-x (v3.10). The game loop is the heart of a game. It keeps the game running.

In the game loop of Cocos2d-x, there are two phases: 1. Drawing the current scene; 2. Cleaning up objects in the auto-release pool. In the DisplayLinkDirector::mainLoop():

drawScene();
PoolManager::getInstance()->getCurrentPool()->clear();

What jobs done in the drawScene method?

  • Handle input events.

      if (_openGLView)
      {
          _openGLView->pollEvents();
      }
    

    However, the pollEvents of GLView is an empty implementation. I have find only one actual implementation which calls the glfwPollEvents method in the CCGLViewImpl-desktop file.

  • Tick the scheduler.

      if (! _paused)
      {
          _eventDispatcher->dispatchEvent(_eventBeforeUpdate);
          _scheduler->update(_deltaTime);
          _eventDispatcher->dispatchEvent(_eventAfterUpdate);
      }
    
  • Clear GL buffers and all FBOs.

      _renderer->clear();
      experimental::FrameBuffer::clearAllFBOs();
    
  • Set the next scene, i.e. if the _nextScene is not null, assign it to the _runningScene.

      if (_nextScene)
      {
          setNextScene();
      }
    

    This code fragment prompts that if we write a statement to switch scene, it will take effect only in the next frame.

  • Push matrix.

      pushMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);
    

    ???

  • Update the physics world if there is.

      #if (CC_USE_PHYSICS || (CC_USE_3D_PHYSICS && CC_ENABLE_BULLET_INTEGRATION) || CC_USE_NAVMESH)
          _runningScene->stepPhysicsAndNavigation(_deltaTime);
      #endif
    
  • Render the scene (the actual work of “draw scene”).

      _renderer->clearDrawStats();
      _runningScene->render(_renderer);
    
  • If there is a notification node, draw it.

      if (_notificationNode)
      {
          _notificationNode->visit(_renderer, Mat4::IDENTITY, 0);
      }
      _renderer->render();
    
  • Pop matrix.

      popMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);
    

    ???

  • Swap buffers

      if (_openGLView)
      {
          _openGLView->swapBuffers();
      }