cocos2dx中onExitTransitionDidStart、onExit和onEnter、onEnterTransitionDidFinish处理机制

进入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);

}

时间: 2024-12-13 14:35:09

cocos2dx中onExitTransitionDidStart、onExit和onEnter、onEnterTransitionDidFinish处理机制的相关文章

关于Cocos2d-x中init方法和onEnter方法的区别

init()和onEnter()这两个方法都是写实例化对象的类(比如继承自Node的一些类等等)的时候用到的方法. 一般都是public类型下面的 bool init(); void onEnter(); 两个方法在实现的时候都要先执行父类方法,比如 Node::init(); Node::onEnter(); 注意: 1.init()在类的初始化时只会调用一次. 2.onEnter在该类被载入场景的时候被调用,可能会发生多次. 3.Node* nd = new Node(); 这种情况下,只会

Cocos2d-x中停止播放背景音乐

停止背景音乐播放代码放置到什么地方比较适合呢?例如:在HelloWorld场景中,主要代码如下: [html] view plaincopy bool HelloWorld::init() { return true; } void HelloWorld::onEnter() { Layer::onEnter(); log("HelloWorldonEnter"); } voidHelloWorld::onEnterTransitionDidFinish() { Layer::onEn

cocos2dx 中切换场景内存占用过高的处理

cocos2dx 中切换场景内存占用过高的处理 1.运行场景: CCScene *pScene = HelloWorld::scene(); pDirector->runWithScene(pScene); 2.替换场景: (1) CCScene *pScene=SceneTestScene::scene(); CCDirector::sharedDirector()->replaceScene(pScene); (2) CCScene *pScene=SceneTestScene::scen

cocos2dx中的设计分辨率与屏幕适配策略

1.首先明确几个概念: 设计分辨率:designResolution,即资源图片的设计尺寸,即美工给你的资源图片的大小,比如(641*964) 屏幕分辨率:又叫帧的大小,glview->setFrameSize(480,640); 这是指你的设备的屏幕的大小,通常手机的屏幕分辨率也就那么几种固定的大小,如480*320,1024*768,等等,在win32模拟器,或其他模拟器中,也指模拟器屏幕的大小. 2.疑问,既然图片是为手机屏幕服务的,干嘛搞这么多概念,直接一切以屏幕为中心不就得了,所有资源

在Cocos2d-x中使用SQLlite数据库

SQLite,是一款轻型的数据库,是遵守ACID的关系型数据库管理系统,它的设计目标是嵌入式的,而且目前已经在很多嵌入式产品中使用了它,它占用资源非常的低,在嵌入式设备中,可能只需要几百K的内存就够了.它能够支持Windows/Linux/Unix等等主流的操作系统,同时能够跟很多程序语言相结合,比如 Tcl.C#.PHP.Java等,还有ODBC接口' 在Cocos2d-X中使用SQLlite数据库 首先下载SQLlite数据库,SQLlite数据库的下载地址:http://download.

Cocos2d-X中的菜单

在Cocos2d-X实现显示菜单的方式比较特殊,首先需要使用CCMenu创建一个菜单,然后使用CCMenuItem创建一个菜单项,实际上程序中显示的菜单是使用CCMenu和CCMenuItemFont共同作用的结果,在Cocos2d-X中CCMenu只是一个容器,需要使用CCMenuItemFont才能实现创建菜单 程序示例:创建一个简单的菜单 程序代码: #include "Menu.h" CCScene* Menu::scene() { CCScene* scene = CCSce

Cocos2d-x中Socket的简单使用

今天总结一下Socket的使用方法吧,有在百度..上面找到的(下面有百度的链接,写的不全的地方,大家可以看一下链接,)...如果哪位大神有更换的demo,求分享!!! Cocos2d-x中有关网络请求的:get post put delete(后两者我在开发中很少用),还有就是 Socket(用于及时通讯,网络游戏中的队友通话). 在vs下面新建一个一个工程(记住不是Cocos项目!!!)C++文件.作为Server 百度上面的相关解释:http://baike.baidu.com/view/2

cocos2d-x中的简单的数据存储

Cocos2d-x中的数据存储方式很多,下面我来简单的介绍几种,有说的不准确的地方,大家指出来吧,共同学习进步.谢谢! 首先介绍的是  UserDefault 这个类: //用userdefault进行数据存储 UserDefault::getInstance()->setStringForKey("testKey","testValue");//将String类型的数据存储起来 //读取上面写入的数据 std::string val = UserDefaul

关于COCOS2D-X 中的CCRectMake参数小注

在使用CocoStudio和Cocos2d-x混合编程过程中,坐标转换是不可避免的.因此,要随时注意,当然坐标.Rect是全局性的还是局部性的.时间长了,许多基础内容易于忘记,这不---小小的宏函数CCRectMake的参数各自函数就忘记了!故备注于此. 在编码时,当忘记相应参数含义时,我常常按下快捷键F12,转换相应的头文件去分析一下.可怜的是,宏函数CCRectMake各个参数就没有很好的注解. 格式:CCRectMake(x,y,width,height) 对于Widget控件,一般情况下