您好,登錄后才能下訂單哦!
進入Node::addChildHelper定義發現如下代碼
if( _running )
{
child->onEnter();
// prevent onEnterTransitionDidFinish to be called twice when a node is added in onEnter
if (_isTransitionFinished) {
child->onEnterTransitionDidFinish();
}
}
也就是說,只有父節點已經在running的情況下,添加子節點時才會調用子節點的onEnter,由此可見,在scene中的添加的子節點,如果scene沒有被渲染,那么之前在scene中添加的子節點(包括layer,sprite)時不會立刻調用子節點的onEnter。那么scene的onEnter()在什么時候調用呢?查看Director中的DrawScene()定義,發現如下代碼:
/* to avoid flickr, nextScene MUST be here: after tick and before draw.
XXX: Which bug is this one. It seems that it can't be reproduced with v0.9 */
if (_nextScene)
{
setNextScene();
}
查看setNextScene定義發現
void Director::setNextScene()
{
bool runningIsTransition = dynamic_cast<TransitionScene*>(_runningScene) != nullptr;
bool newIsTransition = dynamic_cast<TransitionScene*>(_nextScene) != nullptr;
// If it is not a transition, call onExit/cleanup
if (! newIsTransition)
{
if (_runningScene)
{
_runningScene->onExitTransitionDidStart();
_runningScene->onExit();
}
// issue #709. the root node (scene) should receive the cleanup message too
// otherwise it might be leaked.
if (_sendCleanupToScene && _runningScene)
{
_runningScene->cleanup();
}
}
if (_runningScene)
{
_runningScene->release();
}
_runningScene = _nextScene;
_nextScene->retain();
_nextScene = nullptr;
if ((! runningIsTransition) && _runningScene)
{
_runningScene->onEnter();
_runningScene->onEnterTransitionDidFinish();
}
}
在場景類型不是TransitionScene類型時,當當前場景不為null時,先退出當前場景,先調用當前場景的onExitTransitionDidStart、onExit并釋放當前場景,接著講下一個場景賦值給當前場景_runningScene = _nextScene;接著調用當前場景的onEnter()、onEnterTransitionDidFinish(),進行自身以及已添加子節點的onEnter調用,每個節點會在自身的onEnter中設置_running = true;這樣后續在已有場景中添加子節點時,會直接調用子節點的onEnter。
在已渲染場景中,子節點動態從父類中移除時,會調用onExitTransitionDidStart以及onExit
void Node::detachChild(Node *child, ssize_t childIndex, bool doCleanup)
{
// IMPORTANT:
// -1st do onExit
// -2nd cleanup
if (_running)
{
child->onExitTransitionDidStart();
child->onExit();
}
#if CC_USE_PHYSICS
child->removeFromPhysicsWorld();
#endif
// If you don't do cleanup, the child's actions will not get removed and the
// its scheduledSelectors_ dict will not get released!
if (doCleanup)
{
child->cleanup();
}
// set parent nil at the end
child->setParent(nullptr);
_children.erase(childIndex);
}
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。