分析cocos2dx 3.3运行流程

分析cocos2dx 3.3运行流程,第1张

概述<1>不管在哪个平台xode也好,windows下也好,都先进入: cocos2d::Application *app =cocos2d::Application::getInstance(); app->run(); intApplication::run() {     if (applicationDidFinishLaunching())      {         [[CCDirect

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

);

}

总结

以上是内存溢出为你收集整理的分析cocos2dx 3.3运行流程全部内容,希望文章能够帮你解决分析cocos2dx 3.3运行流程所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1080850.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-27
下一篇 2022-05-27

发表评论

登录后才能评论

评论列表(0条)

保存