分析cocos2dx 3.3运行流程

前端之家收集整理的这篇文章主要介绍了分析cocos2dx 3.3运行流程前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

<1>不管在哪个平台xode也好,windows下也好,都先进入:

cocos2d::Application *app =Application::getInstance();

app->run();


intApplication::run()

{

if (applicationDidFinishLaunching())

{

[[CCDirectorCallersharedDirectorCaller]startMainLoop];

}

return0;

}


<2>在开始游戏循环之前,先进入,进行分辨率设置

boolAppDelegate::applicationDidFinishLaunching() {

// initialize director

auto director =Director::getInstance();

auto glview = director->getOpenGLView();

if(!glview) {

glview = GLViewImpl::create("Cpp Empty Test");

director->setOpenGLView(glview);

}


director->setOpenGLView(glview);


// Set the design resolution

glview->setDesignResolutionSize(designResolutionSize.width,designResolutionSize.height,ResolutionPolicy::NO_BORDER);


Size frameSize = glview->getFrameSize();

vector<string> searchPath;


// In this demo,we select resource according to the frame's height.

// If the resource size is different from design resolution size,you need to set contentScaleFactor.

// We use the ratio of resource's height to the height of design resolution,

// this can make sure that the resource's height could fit for the height of design resolution.


// if the frame's height is larger than the height of medium resource size,select large resource.

if (frameSize.height >mediumResource.size.height)

{

searchPath.push_back(largeResource.directory);


director->setContentScaleFactor(MIN(largeResource.size.height/designResolutionSize.height,largeResource.size.width/designResolutionSize.width));

}

// if the frame's height is larger than the height of small resource size,select medium resource.

elseif (frameSize.height >smallResource.size.height)

{

searchPath.push_back(mediumResource.directory);

director->setContentScaleFactor(MIN(mediumResource.size.height/designResolutionSize.height,mediumResource.size.width/designResolutionSize.width));

}

// if the frame's height is smaller than the height of medium resource size,select small resource.

else

{

searchPath.push_back(smallResource.directory);


director->setContentScaleFactor(MIN(smallResource.size.height/designResolutionSize.height,smallResource.size.width/designResolutionSize.width));

}

// set searching path

FileUtils::getInstance()->setSearchPaths(searchPath);

// turn on display FPS

director->setDisplayStats(true);


// set FPS. the default value is 1.0/60 if you don't call this

director->setAnimationInterval(1.0 /60);


// create a scene. it's an autorelease object

auto scene =HelloWorld::scene();


// run

director->runWithScene(scene);


returntrue;

}


<3>资源分辨率设置过之后,每一帧调用一次函数doCaller

-(void) startMainLoop

{

// Director::setAnimationInterval() is called,we should invalidate it first

[selfstopMainLoop];

displayLink = [NSClassFromString(@"CADisplayLink")displayLinkWithTarget:selfselector:@selector(doCaller:)];

[displayLinksetFrameInterval:self.interval];

[displayLinkaddToRunLoop:[NSRunLoopcurrentRunLoop]forMode:NSDefaultRunLoopMode];

}



<4>每一帧都进行mainLoop函数

-(void) doCaller: (id) sender

{

cocos2d::Director* director =cocos2d::Director::getInstance();

[EAGLContextsetCurrentContext: [(CCEAGLView*)director->getOpenGLView()->getEAGLView()context]];

director->mainLoop();

}


<5>

voidDisplayLinkDirector::mainLoop()

{

if (_purgeDirectorInNextLoop)

{

_purgeDirectorInNextLoop =false;

purgeDirector();

}

elseif (_restartDirectorInNextLoop)

{

_restartDirectorInNextLoop =false;

restartDirector();

}

elseif (! _invalid)

{

drawScene();

// release the objects

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

}

}


<6>绘制玩每一帧都,都会被刚添加自动管理池AutoReleasePool中的对象进行一次遍历。

void AutoreleasePool::clear()

{

#if defined(COCOS2D_DEBUG) && (COCOS2D_DEBUG > 0)

_isClearing = true;

#endif

std::vector<Ref*> releasings;

releasings.swap(_managedObjectArray);

for (const auto &obj : releasings)

{

obj->release();

}

_isClearing = false;

#endif

}


总结:

std::vector<Ref*> releasings;

releasings.swap(_managedObjectArray);

这行代码很有意思,将releasings和_managedObjectArray内容进行交换,交换后,_managedObjectArray就为空了,然后将releasings遍历一遍,将引用计数减去1,为0的就回收内存了。


<7>

// Draw the Scene

voidDirector::drawScene()

{

// calculate "global" dt

calculateDeltaTime();

if (_openGLView)

{

_openGLView->pollEvents();

}


//tick before glClear: issue #533

if (!_paused)

{

_scheduler->update(_deltaTime);

_eventDispatcher->dispatchEvent(_eventAfterUpdate);

}


_renderer->clear();

experimental::FrameBuffer::clearAllFBOs();

/* 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 || (CC_USE_3D_PHYSICS && CC_ENABLE_BULLET_INTEGRATION) || CC_USE_NAVMESH)

_runningScene->stepPhysicsAndNavigation(_deltaTime);

#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();

}

_renderer->render();


_eventDispatcher->dispatchEvent(_eventAfterDraw);


popMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);


_totalFrames++;


// swap buffers

if (_openGLView)

{

_openGLView->swapBuffers();

}


if (_displayStats)

{

calculateMPF();

}

}



<8>在Scene中调用其render方法回执场景。

voidScene::render(Renderer* renderer)

{

auto director =Director::getInstance();

Camera* defaultCamera =nullptr;

constauto& transform =getNodeToParentTransform();


for (constauto& camera :getCameras())

{

if (!camera->isVisible())

continue;

Camera::_visitingCamera = camera;

if (Camera::_visitingCamera->getCameraFlag() == CameraFlag::DEFAULT)

{

defaultCamera = Camera::_visitingCamera;

}

director->pushMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_PROJECTION);

director->loadMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_PROJECTION,Camera::_visitingCamera->getViewProjectionMatrix());

camera->apply();

//clear background with max depth

camera->clearBackground();

//visit the scene

visit(renderer,transform,0);

#if CC_USE_NAVMESH

if (_navMesh &&_navMeshDebugCamera == camera)

{

_navMesh->debugDraw(renderer);

}

#endif

renderer->render();

director->popMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_PROJECTION);

}

#if CC_USE_3D_PHYSICS && CC_ENABLE_BULLET_INTEGRATION

if (_physics3DWorld &&_physics3DWorld->isDebugDrawEnabled())

{

_physics3dDebugCamera !=nullptr ?_physics3dDebugCamera->getViewProjectionMatrix() : defaultCamera->getViewProjectionMatrix());

_physics3DWorld->debugDraw(renderer);

renderer->render();

director->popMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_PROJECTION);

}

#endif


Camera::_visitingCamera =nullptr;

experimental::FrameBuffer::applyDefaultFBO();

}


<9>Scene其实也是一个Node,递归绘制自身及其子节点

voidNode::visit(Renderer* renderer,constMat4 &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,0)"> // but it is deprecated and your code should not rely on it

_director->pushMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);

_director->loadMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW,_modelViewTransform);

bool visibleByCamera =isVisitableByVisitingCamera();


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

if (visibleByCamera)

this->draw(renderer,flags);


for(auto it=_children.cbegin()+i; it != _children.cend(); ++it)

(*it)->visit(renderer,flags);

}

elseif (visibleByCamera)

{

this->draw(renderer,flags);

}


_director->popMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);

// FIX ME: Why need to set _orderOfArrival to 0??

// Please refer tohttps://github.com/cocos2d/cocos2d-x/pull/6920

// reset for next frame

// _orderOfArrival = 0;

}

首先绘制_localZOrder < 0的,其次在for(autoit=_children.cbegin()+i; it !=cend(); ++it)绘制 >=0 的

<10>

voidNode::sortAllChildren()

{

if (_reorderChildDirty)

{

std::sort(std::begin(_children),std::end(_children),nodeComparisonLess);

_reorderChildDirty =false;

}

}


bool nodeComparisonLess(Node* n1,Node* n2)

{

return( n1->getLocalZOrder() < n2->getLocalZOrder() ||

( n1->getLocalZOrder() == n2->getLocalZOrder() && n1->getOrderOfArrival() < n2->getOrderOfArrival() )

);

}

猜你在找的Cocos2d-x相关文章