场景切换应该flash怎么切换场景弄

flash按钮代码,请问:如何实现同一场景不同页面的转换,按钮代码是什么?有多少种?谢谢_好搜问答
|注册&您有新任务,
flash按钮代码,请问:如何实现同一场景不同页面的转换,按钮代码是什么?有多少种?谢谢
被浏览589次
采纳率:45%
FLASH中场景及各帧之间的转换有以下几个代码:
1.play() 播放当前动画.
2.stop() 暂停播放动画.
3gotoAndPlay([scene,] frame) 该动作意思为从某个帧开始播放动画,参数&scene&是设置开始播放帧所在场景,该参数可以省略,省略后则从当前场景播放指定帧,参数&frame&是指定播放的帧.例如想从当前场景第3帧开始播放,则动作为:gotoAndPlay(3);
4.gotoAndStop[scene,] frame) 该动作意思为将播放头跳于某帧上并且停在该帧上.其具体参数与上一动作相同.
5.nextFrame() 该动作功能为播放下一帧,并停在下一帧.没有参数.
6.revFrame() 该动作功能为播放前一帧,并停在前一帧.也没有参数.
7nextScene() 动画进入下一场景.没有参数.
8.revScene() 动画进入前一场景.没有参数.
以上便是FLASH中用于控制场景及帧之间转换的几个动作.下面回答你按钮问题:
在影片中按钮的作用是为了让影片观看者能与影片发生互动,但是如果仅仅放一个按纽在影片中是什么作用也没有的,原因是按纽中什么动作也没有.当按纽被按下之后按纽本身不知道该做什么,这就是为什么要在按纽中添加动作的原因.
按纽的动作在FLASH中是很多很多的,我这里不能穷举出来.比如上面告诉你的6个动作就可以做为按纽中的动作,用来控制影片的播放.按纽中的具体动作是作者本人写的,作者希望该按纽的功能如何,然后自己组织脚本将其写入按纽中,例如我想通过一个按钮来播放当前的动画,那么我就要在按钮中加如以下的代码:
on(press){
代码中play()是具体动作,动作可替换为其他的,因功能不同而不同.另一个值得注意的东西是按钮事件处理函数就是以上代码中的&on(press)&地方,该函数是用来判断什么时候触发动作的,共有以下几种:
on(press){} 当鼠标按下时触发
on(release){} 当鼠标在剪辑上释放时触发
on(releaseOutside){} 当用户在剪辑上点击鼠标,后将鼠标拖出剪辑,然后释放时触发
on(dragOut){} 当用户在剪辑上点击鼠标,然后将鼠标拖出剪辑时触发
on(dragOver){} 当用户在剪辑上点击鼠标,将鼠标移出剪辑,然后再将鼠标移回剪辑区域时触发
on(rollOver){}未点击鼠标的情况下,鼠标滑过剪辑时触发
on(rollOut){} 未点击鼠标情况下,鼠标滑过剪辑并移出剪辑时触发
由以上来看上面我给的那个动作,意思就为,当我在该按钮上点击鼠标时,播放动画.
以上是按钮中鼠标事件处理函数,另外还有键盘处理的函数……但是……怕写不下了-_-i
如要制作一个简单的按钮我认为以上这些东西已经足够了.但是自FLASH MX2004后FLASH中又引入了另一种按钮,就是用影片剪辑来做的按钮,这种按钮做起来相对要复杂好多,但是做出的按钮也要漂亮很多,这是题外话,这里就不说了……
看了下上面,写的蛮乱的,不知你看不看的懂,如果我哪里没写清楚导致你看不懂的可以加我QQ: 我会在QQ上为你解答. 用微信扫描二维码分享至好友和朋友圈分享到:
下面是答答童鞋给您的小建议,您看靠谱吗?初来乍到,弄错了您不要生气哦(*^__^*)答答小贴士
等您帮助的附近的朋友换一换
大家都在搜好搜APP下载好搜摸字APP 随时随地随心搜索 用好搜, 特顺手!
第9天生活就像海洋,只有意志坚强的人才能达到生命的彼岸。知道了Cocos2d-x场景切换有关函数介绍_Cocos2d-x场景性命周期函数介绍_pl/sql配置连接远程数据库oracle,当地没有安装oracle数据库的情况下__脚本百事通
稍等,加载中……
^_^请注意,有可能下面的2篇文章才是您想要的内容:
Cocos2d-x场景切换有关函数介绍
Cocos2d-x场景性命周期函数介绍
pl/sql配置连接远程数据库oracle,当地没有安装oracle数据库的情况下
Cocos2d-x场景切换有关函数介绍
Cocos2d-x场景切换相关函数介绍场景切换是通过导演类Director实现的,其中的相关函数如下:
runWithScene(Scene* scene)。该函数可以运行场景。只能在启动第一个场景时候调用该函数。如果已经有一个场景运行情况下则不能调用该函数。
replaceScene(Scene* scene)。切换到下一个场景。用一个新的场景替换当前场景,当前场景被终端释放。
pushScene(Scene* scene)。切换到下一个场景。将当前场景挂起放入到场景堆栈中,然后再切换到下一个场景中。
void popScene()。与pushScene配合使用,可以回到上一个场景。
void popToRootScene()。与pushScene配合使用,可以回到根场景。
我们需要注意replaceScene和pushScene使用的区别。replaceScene会释放和销毁场景,如果需要保持原来场景的状态,replaceScene函数不适合。pushScene并不会释放和销毁场景,原来场景的状态可以保持,但是场景不能放太多的场景对象。
使用replaceScene代码如下:
auto sc = Setting::createScene();
Director::getInstance()-&replaceScene(sc);
其中的Setting是下一个要切换的场景。使用pushScene代码如下:
auto sc = Setting::createScene();
Director::getInstance()-&pushScene(sc);
从Setting场景回到上一个场景使用代码如下:
Director::getInstance()-&popScene();
下面我们通过一个实例场景切换相关函数,如下图所示有两个场景:HelloWorld和Setting(设置)。在HelloWorld场景点击“游戏设置”菜单可以切换到Setting场景,在Setting场景中点击“OK”菜单可以返回到HelloWorld场景。
我们首先需要在工程中添加一个Setting场景(SettingScene.cpp和SettingScene.h),如下图所示,右键点击HelloWorld工程中Classes文件夹,在弹出菜单中选择“添加”→“新建项”:
弹出对话框如下图所示,在名称中输入“SettingScene.cpp”,并选择保存文件位置,然后点击“添加”按钮创建SettingScene.cpp。使用同样的方法创建SettingScene.h。
下面我们看看代码部分,HelloWorldScene.cpp中的重要代码如下:
bool HelloWorld::init()
if ( !Layer::init() )
Size visibleSize = Director::getInstance()-&getVisibleSize();
Point origin = Director::getInstance()-&getVisibleOrigin();
Sprite *bg = Sprite::create("background.png");
bg-&setPosition(Point(origin.x + visibleSize.width/2,
origin.y +visibleSize.height /2));
this-&addChild(bg);
//开始精灵
Sprite *startSpriteNormal = Sprite::create("start-up.png");
Sprite *startSpriteSelected =Sprite::create("start-down.png");
MenuItemSprite*startMenuItem = MenuItemSprite::create(startSpriteNormal,
startSpriteSelected,
CC_CALLBACK_1(HelloWorld::menuItemStartCallback,this));
startMenuItem-&setPosition(Director::getInstance()-&convertToGL(Point(700,170)));
//设置图片菜单
MenuItemImage *settingMenuItem = MenuItemImage::create(
"setting-up.png",
"setting-down.png",
CC_CALLBACK_1(HelloWorld::menuItemSettingCallback,this));
settingMenuItem-&setPosition(Director::getInstance()-&convertToGL(Point(480,400)));
//帮助图片菜单
MenuItemImage *helpMenuItem = MenuItemImage::create(
"help-up.png",
"help-down.png",
CC_CALLBACK_1(HelloWorld::menuItemHelpCallback,this));
helpMenuItem-&setPosition(Director::getInstance()-&convertToGL(Point(860,480)));
Menu*mu = Menu::create(startMenuItem, settingMenuItem, helpMenuItem, NULL);
mu-&setPosition(Point::ZERO);
this-&addChild(mu);
voidHelloWorld::menuItemSettingCallback(Ref* pSender)
autosc = Setting::createScene();
//Director::getInstance()-&replaceScene(sc);
Director::getInstance()-&pushScene(sc);
void HelloWorld::menuItemHelpCallback(Ref*pSender)
MenuItem* item = (MenuItem*)pS
log("TouchHelp %p", item);
void HelloWorld::menuItemStartCallback(Ref*pSender)
MenuItem* item = (MenuItem*)pS
log("TouchStart %p", item);
上述代码中的第①行定义的函数menuItemSettingCallback,是在用户点击“游戏设置”菜单时候回调。第②行代码是创建设置创建对象。第③行是使用replaceScene函数进行场景切换。第④行代码是pushScene函数进行场景切换。
HelloWorldScene.cpp中的重要代码如下:
bool Setting::init()
if ( !Layer::init() )
Size visibleSize = Director::getInstance()-&getVisibleSize();
Point origin = Director::getInstance()-&getVisibleOrigin();
Sprite *bg = Sprite::create("setting-back.png");
bg-&setPosition(Point(origin.x + visibleSize.width/2,
origin.y +visibleSize.height /2));
this-&addChild(bg);
auto soundOnMenuItem = MenuItemImage::create(
"on.png");
auto soundOffMenuItem = MenuItemImage::create(
"off.png",
"off.png");
auto soundToggleMenuItem = MenuItemToggle::createWithCallback(
CC_CALLBACK_1(Setting::menuSoundToggleCallback,this),
soundOnMenuItem,
soundOffMenuItem,
soundToggleMenuItem-&setPosition(Director::getInstance()-&convertToGL(Point(818,220)));
auto musicOnMenuItem
=MenuItemImage::create(
"on.png");
automusicOffMenuItem
=MenuItemImage::create(
"off.png",
"off.png");
auto musicToggleMenuItem = MenuItemToggle::createWithCallback(
CC_CALLBACK_1(Setting::menuMusicToggleCallback,this),
musicOnMenuItem,
musicOffMenuItem,
musicToggleMenuItem-&setPosition(Director::getInstance()-&convertToGL(Point(818,362)));
autookMenuItem
= MenuItemImage::create(
"ok-down.png",
"ok-up.png",
CC_CALLBACK_1(Setting::menuOkCallback, this));
okMenuItem-&setPosition(Director::getInstance()-&convertToGL(Point(600,510)));
Menu* mn = Menu::create(soundToggleMenuItem,
musicToggleMenuItem,okMenuItem,NULL);
mn-&setPosition(Point::ZERO);
this-&addChild(mn);
void Setting::menuOkCallback(Ref*pSender)
Director::getInstance()-&popScene();
void Setting::menuSoundToggleCallback(Ref*pSender)
void Setting::menuMusicToggleCallback(Ref*pSender)
上述代码中的第①行定义的函数menuOkCallback,是在用户在设置场景点击“OK”菜单时候回调。第②行代码是使用popScene函数返回HelloWorld场景。
更多内容请关注Cocos2d-x系列图书《Cocos2d-x实战(卷Ⅰ):C++开发》
本书交流讨论网站:http://www.cocoagame.net
欢迎加入cocos2d-x技术讨论群:、
Cocos2d-x场景性命周期函数介绍
Cocos2d-x场景生命周期函数介绍层(Layer)的生命周期函数有如下:
init()。初始化层调用。
onEnter()。进入层时候调用。
onEnterTransitionDidFinish()。进入层而且过渡动画结束时候调用。
onExit()。退出层时候调用。
onExitTransitionDidStart()。退出层而且开始过渡动画时候调用。
cleanup()。层对象被清除时候调用。
层(Layer)继承于节点(Node),这些生命周期函数根本上是从Node继承而来。事实上所有Node对象(包括:场景、层、精灵等)都有这些函数,只要是子类化这些类都可以重写这些函数,来处理这些对象的不同生命周期阶段事件。
我们重写HelloWorld层的中几个生命周期函数,代码如下:
bool HelloWorld::init()
if( !Layer::init() )
log("HelloWorldinit");
void HelloWorld::onEnter()
Layer::onEnter();
log("HelloWorldonEnter");
voidHelloWorld::onEnterTransitionDidFinish()
Layer::onEnterTransitionDidFinish();
log("HelloWorldonEnterTransitionDidFinish");
void HelloWorld::onExit()
Layer::onExit();
log("HelloWorldonExit");
voidHelloWorld::onExitTransitionDidStart()
Layer::onExitTransitionDidStart();
log("HelloWorldonExitTransitionDidStart");
void HelloWorld::cleanup()
Layer::cleanup();
log("HelloWorldcleanup");
注意 在重写层生命周期函数中,第一行代码应该是调用父类的函数,例如HelloWorld::onEnter()中第一行应该是Layer::onEnter()函数,如果不调用父类的函数可能会导致层中动画、动作或计划无法执行。
如果HelloWorld是第一个场景,当启动HelloWorld场景时候,它的调用顺序如下图所示:
更多内容请关注Cocos2d-x系列图书《Cocos2d-x实战(卷Ⅰ):C++开发》
本书交流讨论网站:http://www.cocoagame.net
欢迎加入cocos2d-x技术讨论群:、
pl/sql配置连接远程数据库oracle,当地没有安装oracle数据库的情况下
pl/sql配置连接远程数据库oracle,本地没有安装oracle数据库的情况下首先下载instantclient 可以到oracle官网下载,要注册账号,一定要下对应版本的,要不然不成功,
10G,11G版的,我已经传上来了,免费下载:正在上传中,稍等
配置文件tnsnames.ora 这个一个地方一般都放(network/ADMIN),只有在pl/sql -----&tools--&proferences...------&connection----& oracle home(empty is autodetect)
写上tnsnames.ora的路径(相关路径换成你自已的)
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = 172.16.100.183)(PORT = 1521))
(CONNECT_DATA =
(SERVICE_NAME = orcl)
ORACLR_CONNECTION_DATA =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1521))
(CONNECT_DATA =
(SID = CLRExtProc)
(PRESENTATION = RO)
设置环境变量(目录换成你自已的)
TNS_ADMIN=D:\soft\oarcleclient\instantclient_11_2
NLS_LANG=SIMPLIFIED CHINESE_CHINA.ZHS16GBK
path=D:\soft\oarcleclient\instantclient_11_2
如果您想提高自己的技术水平,欢迎加入本站官方1号QQ群:&&,&&2号QQ群:,在群里结识技术精英和交流技术^_^
本站联系邮箱:Cocos2d-X3.0 刨根问底(九)----- 场景切换(TransitionScene)源码分析 - 小鱼老师 - 推酷
Cocos2d-X3.0 刨根问底(九)----- 场景切换(TransitionScene)源码分析 - 小鱼老师
上一章我们分析了Scene与Layer相关类的源码,对Cocos2d-x的场景有了初步了解,这章我们来分析一下场景变换TransitionScene源码。
直接看TransitionScene的定义
1 class CC_DLL TransitionScene : public Scene
/** Orientation Type used by some transitions
enum class Orientation
/// An horizontal orientation where the Left is nearer
LEFT_OVER = 0,
/// An horizontal orientation where the Right is nearer
RIGHT_OVER = 1,
/// A vertical orientation where the Up is nearer
UP_OVER = 0,
/// A vertical orientation where the Bottom is nearer
DOWN_OVER = 1,
/** creates a base transition with duration and incoming scene */
static TransitionScene * create(float t, Scene *scene);
/** called after the transition finishes */
void finish(void);
/** used by some transitions to hide the outer scene */
void hideOutShowIn(void);
// Overrides
virtual void draw(Renderer *renderer, const kmMat4 &transform, bool transformUpdated) override;
virtual void onEnter() override;
virtual void onExit() override;
virtual void cleanup() override;
35 CC_CONSTRUCTOR_ACCESS:
TransitionScene();
virtual ~TransitionScene();
/** initializes a transition with duration and incoming scene */
bool initWithDuration(float t,Scene* scene);
42 protected:
virtual void sceneOrder();
void setNewScene(float dt);
Scene *_inS
Scene *_outS
bool _isInSceneOnT
bool _isSendCleanupToS
52 private:
CC_DISALLOW_COPY_AND_ASSIGN(TransitionScene);
这个类并不大,从类的头信息继承关系上可以看出场景切换的类其实也是一个场景。
老套路,先从成员变量开始分析。
TransitionScene 类一共有五个成员变量这五个变量从变量命名上就已经能猜得差不多了。
Scene *_inS
// 场景切换 切入的场景指针
Scene *_outS
// 场景切换 切出的场景指针
// 场景切换 消耗的时间
bool _isInSceneOnT
// 场景切换 描述切入场景与切出场景的渲染层次关系,true 切入场景在切出场景的顶层
bool _isSendCleanupToS // 场景切换 标记是否已经给切出场景发送了清理的命令。
到这里,可以猜出TransitionScene 类到底是以一个什么样的过程来实现 场景切换的,
TransitionScene 是一个中介场景,它左手拿着要切入的场景(
_inScene),右手拿着要切出的场景( _outScene),让这两个入出场景在自己身上以一种华丽的方式完成切场的过程,最后这个中介场景退出,把舞台交给新切入的场景。
上面我们猜测了一下TransitionScene实现场景切换的原理,我们便有了好奇,TransitionScene类实现切入场景与切出场景的具体过程是什么呢?我们猜测的切换原理是否正确呢?
带着问题我们继续看源码来找答案。
我们先从TransitionScene的创建方法开始。
TransitionScene的构造函数是个空函数忽略,我们看一下TransitionScene::Create这个静态方法开始分析。
1 TransitionScene * TransitionScene::create(float t, Scene *scene)
TransitionScene * pScene = new TransitionScene();
if(pScene && pScene-&initWithDuration(t,scene))
pScene-&autorelease();
CC_SAFE_DELETE(pScene);
看到create函数的结构 熟悉的不能再熟悉了,在Cocos2d-x基本年有Node类及子类的创建都是这个结构。
下面我们看一下initWithDuration这个初始化方法。
1 bool TransitionScene::initWithDuration(float t, Scene *scene)
CCASSERT( scene != nullptr, &Argument scene must be non-nil&);
if (Scene::init())
_duration =
_inScene =
_inScene-&retain();
_outScene = Director::getInstance()-&getRunningScene();
if (_outScene == nullptr)
_outScene = Scene::create();
_outScene-&retain();
CCASSERT( _inScene != _outScene, &Incoming scene must be different from the outgoing scene& );
sceneOrder();
return true;
return false;
从这个函数的参数来判断,这个初始化函数的作用是,通过指定场景切换的持续时间与要切换的场景指针来初始化一个场景切换中介场景(TransitionScene)的实例。
TransitionScene实例初始过程
调用基类Scene初始化方法。Scene::init
将传入的持续时间参数进行赋值 _duration =
切入场景赋值 _inScene =注意这里增加了一次对切入场景的引用,因为在中介场景引用了一次切入场景,所以增加了一次引用计数。
切出场景赋值 这里的切出场景当然就是指的当前Director类正在运行的场景 通过 Director::getInstance()-&getRunningScene(); 得到当前正在运行的场景赋值给_outScene还有一个判断,如果没有正在运行的场景那么会创建一个空的场景做为切出场景,并且增加了一次对切也场景的引用记数。
调用了sceneOrder()函数,从这个函数的命名上来看是对场景进行了一次排序,具体都干了些啥事呢?下在对sceneOrder进行分析。
void TransitionScene::sceneOrder()
_isInSceneOnTop = true;
sceneOrder 这是一个虚函数,里面的过程很简单,只是设置了_isInSceneOnTop这个标记,来指定切入场景与切出场景的层次关系,就是谁在谁的上面。
TransitionScene 的实例创建我们分析完了,下面来寻找场景切换的过程是怎么样实现的。
看一下TransitionScene 类头文件发现了以下几个函数。
virtual void draw(Renderer *renderer, const kmMat4 &transform, bool transformUpdated) override;
virtual void onEnter() override;
virtual void onExit() override;
virtual void cleanup() override;
从命名上初步分析这四个函数的作用分别是
draw 渲染方式
onEnter 中介场景进入舞台时调用
onExit 中介场景退出舞台时调用
clearup 清理场景方法。
一个一个分析先看onEnter
void TransitionScene::onEnter()
Scene::onEnter();
// disable events while transitions
_eventDispatcher-&setEnabled(false);
// outScene should not receive the onEnter callback
// only the onExitTransitionDidStart
_outScene-&onExitTransitionDidStart();
_inScene-&onEnter();
函数过程分析:
调用Scene基类的onEnter
将事件分发器设置为不可用状态,场景切换是一个动画过程,在这个过程中不处理事件,以免发生意想不到的错误。
调用切出场景的onExitTransitionDidStart方法。看过以前章节的朋友应该还有印象,这个方法是在Node基类里面定义的,函数意义为场景变化切出开始时的回调方法。中介场景进入舞台当然是当前场景离开的时候在这里调用这个方法合情合理
最后调用了切入场景的onEnter ,一点问题都没有,切出场景开始离开,切入场景进入舞台,这正是这个中介场景在左右手交换的过程。
再看onExit方法。
void TransitionScene::onExit()
Scene::onExit();
// enable events while transitions
_eventDispatcher-&setEnabled(true);
_outScene-&onExit();
// _inScene should not receive the onEnter callback
// only the onEnterTransitionDidFinish
_inScene-&onEnterTransitionDidFinish();
函数过程分析:
调用基类Scene的onExit方法。
恢复了事件分发器的可用状态。
调用了切出场景的离开回调
调用了切入场景的进入完成回调。
我们onEnter和onExit这两个方法来比较着看。
通过分析,我们可以了解切入切出场景 进入舞台到离开舞台的函数调用顺序,在这里小结一下。
场景进入舞台 ----&离开舞台。 (这里说的舞台可以理解成就是屏幕上可以显示的区域)
onEnter(进入舞台) ---& onEnterTransitionDidFinish(进入完成) ---& onExitTransitionDidStart(开始离开舞台) ---& onExit(离开)
了解了场景的进入舞台函数调用顺序,我们就可以理解中介场景的onExit与onEnter这两个函数都是干了些什么。
中介场景进入舞台的时候正是切出场景开始离开舞台与切入场景进入舞台的时候
中介场景离开始了舞台,切入场景完成了进入舞台,切出场景离开了舞台。
就在这个时候中介场景与切出场景都离开始了舞台,在舞台上就留下了切入的场景,至此完成了场景的切换。
接下来我们看一下另外两个虚函数
void TransitionScene::draw(Renderer *renderer, const kmMat4 &transform, bool transformUpdated)
Scene::draw(renderer, transform, transformUpdated);
if( _isInSceneOnTop ) {
_outScene-&visit(renderer, transform, transformUpdated);
_inScene-&visit(renderer, transform, transformUpdated);
_inScene-&visit(renderer, transform, transformUpdated);
_outScene-&visit(renderer, transform, transformUpdated);
draw方法没什么难度,就是根据_isInSceneOnTop这里记录的切入切出两个场景层次关系,来做分别的渲染。
void TransitionScene::cleanup()
Scene::cleanup();
if( _isSendCleanupToScene )
_outScene-&cleanup();
clearup方法也是先调用其它的clearup然后根据切出场景是否已经清除过_isSendCleanupToScene这个标记来对切出场景进行清理操作。
下面我们看一下TransitionScene还有哪些方法
void TransitionScene::finish()
// clean up
_inScene-&setVisible(true);
_inScene-&setPosition(Point(0,0));
_inScene-&setScale(1.0f);
_inScene-&setRotation(0.0f);
_inScene-&setAdditionalTransform(nullptr);
_outScene-&setVisible(false);
_outScene-&setPosition(Point(0,0));
_outScene-&setScale(1.0f);
_outScene-&setRotation(0.0f);
_outScene-&setAdditionalTransform(nullptr);
//[self schedule:@selector(setNewScene:) interval:0];
this-&schedule(schedule_selector(TransitionScene::setNewScene), 0);
这个finish方法,大家一看就能知道是场景切换完成时调用的方法
里面的函数过程也很简单,设置切入 场景为显示状态,切出场景不显示,并且将场景的旋转、缩放、位置都恢复成初始状态。
值得注意的是最后将一个回调函数加入到了定时调度器里 TransitionScene::setNewScene 这个回调间隔时间为0也就是在下一帧就会被调用。
下面看一下这个setNewScene这个函数是干什么的。
void TransitionScene::setNewScene(float dt)
CC_UNUSED_PARAM(dt);
this-&unschedule(schedule_selector(TransitionScene::setNewScene));
// Before replacing, save the &send cleanup to scene&
Director *director = Director::getInstance();
_isSendCleanupToScene = director-&isSendCleanupToScene();
director-&replaceScene(_inScene);
// issue #267
_outScene-&setVisible(true);
这个函数有一个参数但并没有使用,可能是预留的。
这个函数里面取到了Director类是清除场景的标记,并且赋值给了_isSendCleanupToScene这个变量。
注意这一行代码 director-&replaceScene(_inScene);
我们知道,Director管理着场景,同时只能有一个runningScene,这行代码实际上是真正的把舞台通过Director交给了我们要切入的场景(_inScene)
void TransitionScene::hideOutShowIn()
_inScene-&setVisible(true);
_outScene-&setVisible(false);
函数 hideOutShowIn 隐藏切出场景显示切入场景,没什么可多说的。
分析到这里,所有TransitionScene类里的方法我们都分析过了,可能大家有一些疑问
只分析到了一些场景切入舞台与场景离开舞台的回调,而没有看到那些动态的场景切换的过程。
中介场景是如何进入舞台的?如何使用中介场景来做场景切换呢?
finish函数并没有被调用,那么这个finish好像名存实亡。
带着疑问,我们继续在源码中寻找答案。
我们看CCTransition.h这个头文件里面除了TransitionScene还定义了好多TransitionScene类的子类,下面我们选择一个类来分析一下
/** @brief TransitionRotoZoom:
Rotate and zoom out the outgoing scene, and then rotate and zoom in the incoming
class CC_DLL TransitionRotoZoom : public TransitionScene
static TransitionRotoZoom* create(float t, Scene* scene);
// Overrides
virtual void onEnter() override;
protected:
TransitionRotoZoom();
virtual ~TransitionRotoZoom();
CC_DISALLOW_COPY_AND_ASSIGN(TransitionRotoZoom);
看一下这个类的注释,切出场景缩放旋转着移出,切入场景旋转缩放着移入。
TransitionRotoZoom 类继承 TransitionScene类 并没有增加什么属性与方法,而是重载了onEnter方法,那么onEnter里面有什么变化呢?
void TransitionRotoZoom:: onEnter()
TransitionScene::onEnter();
_inScene-&setScale(0.001f);
_outScene-&setScale(1.0f);
_inScene-&setAnchorPoint(Point(0.5f, 0.5f));
_outScene-&setAnchorPoint(Point(0.5f, 0.5f));
ActionInterval *rotozoom = (ActionInterval*)(Sequence::create
Spawn::create
ScaleBy::create(_duration/2, 0.001f),
RotateBy::create(_duration/2, 360 * 2),
DelayTime::create(_duration/2),
_outScene-&runAction(rotozoom);
_inScene-&runAction
Sequence::create
rotozoom-&reverse(),
CallFunc::create(CC_CALLBACK_0(TransitionScene::finish,this)),
看到了onEnter实现,是有这么点意思了,里面有提到动画,延时……. 开始分析。
onEnter函数过程:
调用基类的onEnter这里面连接了切入切出场景的onEnter与onExit相关的场景过程回调。
设置切入场景缩小到0.001倍大小& 切出场景为原大小。
将切入,切出场景的锚点设置在场景的中心部位。
这里出现了一个新的类ActionInterval& 从命名上可得知是一个动画的类,的这里设置了两个变化过程,一个是缩放上面的变化,一个是旋转上面的变化。切出场景运行了这个动作过程。
切入场景反运行了上面定义的动作过程rotozoom-&reverse()
在创建动画序列对象时定义了一个回调函数CallFunc::create(CC_CALLBACK_0(
TransitionScene::finish
,this)),& 哈哈,这里我们看到了
TransitionScene::finish 这个函数 在这里出现完全可以理解, 在切入场景动画播放完成的时候调用了中介场景的finish方法。上面讲过在finish方法里面最终通过director的replaceScene方法来将切入场景加入到了舞台。
注意:这里用了ActionInterval& 等动画相关的类,在这里我们只要知道这些动画类的大概作用就可以了,后面的章节我们一个一个地分析。
小鱼写了一个Demo给大家展示一下 TransitionRotoZoom& 切换场景的过程。
通过对 TransitionScene 类的派生类 TransitionRotoZoom 的分析,我们了解了TransitionScene类的动作过程,总结如下:
TransitionScene 类是场景切换的基类,Cocos2d-x的场景效果都继承 这个类。但这个类没有任何切换场景的效果,只提供了onEnter onExit等几个函数接口,在子类里面重载这些接口函数来实现特定的场景切换效果。
TransitionScene& 系列类是一个场景的中介类,在这个类里会相继调用 切入切出场景的onEnter与onExit。
如果你自己定义场景切换的效果,不要忘记在效果结束后调用
TransitionScene::finish 方法.
现在上面的三个疑问基本都找到答案了。
这里还有一点可能有些读者会产生疑问。
小鱼在这里一起和大家再分析一下场景切换与Director类及引擎的关联。
先说一下TransitionScene& 类的使用方法。
看以下代码。
auto visibleSize = Director::getInstance()-&getVisibleSize();
Scene *myScene = Scene::create();
Sprite * sp = Sprite::create(&mv2.jpg&);
sp-&setPosition( visibleSize.width / 2, visibleSize.height / 2 );
myScene-&addChild( sp );
TransitionRotoZoom *tranScene = TransitionRotoZoom::create( 2.0, myScene );
Director::getInstance()-&replaceScene( tranScene );
这个例子是我上面gif图的代码片断,主要用到了 TransitionRotoZoom& 这种变化。
前五行代码很简单,就是我创建了一个新的场景我们叫场景2,将一个图片放到了场景2上面。
第六行代码,我创建了一个TransitionRotoZoom场景切换对象实例,并且设置切换时间为2秒,将场景2传入做为切出场景。
第七行代码 ,找到Director实例对象,用场景2来替换当前场景。
就这几行代码就实现了上面的效果。
一句话,在使用场景切换的时候就是将场景变换的中介场景加入到舞台上。上面我们已经分析了中介场景,在结束的时候会真正的将切入场景replace到舞台上面。
为了加深理解,我们以上面的实例代码为例子在这里再分析几断Director相关函数的代码。
我们先看replaceScene都干了些什么。
void Director::replaceScene(Scene *scene) // 这里传入的scene就是我们的中介场景 myScene
CCASSERT(_runningScene, &Use runWithScene: instead to start the director&);
CCASSERT(scene != nullptr, &the scene should not be null&);
if (_nextScene)// 这里判断如果已经指定了下一个要切的场景那就在这里面就把下个场景释放掉。
if (_nextScene-&isRunning())
_nextScene-&onExitTransitionDidStart();
_nextScene-&onExit();
_nextScene-&cleanup();
_nextScene =
// 这里将myScene放到场景栈顶,并且重新修改了_nextScene为 myScene
ssize_t index = _scenesStack.size();
_sendCleanupToScene = true;
_scenesStack.replace(index - 1, scene);
_nextScene =
} // 函数结束后现在Director里面的_nextScene就是我们的myScene。 在director每一帧的主循环里我们找一下对_nextScene的处理。
我们再回顾了下Director 的mainLoop
void DisplayLinkDirector::mainLoop()
if (_purgeDirectorInNextLoop)
_purgeDirectorInNextLoop = false;
purgeDirector();
else if (! _invalid)
drawScene();// 其它的不用看,我们再跟进drawScene找找对 _nextScene的处理。
// release the objects
PoolManager::getInstance()-&getCurrentPool()-&clear();
下面是drawScene的代码片断
void 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)// 在drawScene里面有对_nextScene处理,这时_nextScene就是我们上面会话的myScene
setNextScene();
kmGLPushMatrix();
// 下面省略
跟进setNextScene方法。
void Director::setNextScene()
{// 下面两个转换大家要注意一下,此时的_runningScene是我们的场景1 就是一个普通的scene 所以在做dynamic_cast 转换时为null
bool runningIsTransition = dynamic_cast&TransitionScene*&(_runningScene) !=
//这里runningIsTransition == false
bool newIsTransition = dynamic_cast&TransitionScene*&(_nextScene) !=
//这里newIsTransition = true
// If it is not a transition, call onExit/cleanup
if (! newIsTransition) // 因为_nextScene是 transiton类型所以这个if判断里面不会走进来
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的引用计数,因为_runningScene要被_nextScene替代
_runningScene-&release();
_runningScene = _nextS // _nextScene增加了一次引用计数
_nextScene-&retain();
_nextScene =
if ((! runningIsTransition) && _runningScene) // 这个判断会进入,大家如果没弄明白仔细想想 虽然现在的_runningScene是Transition类型但我们取得 runningIsTransition值的时候是还没有将_nextScene进行替换。
_runningScene-&onEnter(); // 终于找到了,在这里调用了中介场景 myScene的 onEnter 然后就有一系列的 旋转、缩放变化。这就是我们前面分析TransitionScene 这个类的过程联系起来了。直到myScene的finish方法将场景2换到舞台上。
_runningScene-&onEnterTransitionDidFinish();
好啦,今天的内容基本就这些了。
通过上面的分析我们了 Cocos2d-x的场景变化是怎么做的。这里我只给了大家一个实例,如果想多了解Cocos2d-x都准备了哪些场景变化给我们,不妨把CCTransition.h里面的类做成Demo都试一下。
今天我们在分析中碰到了与 Action有关的类,现在我们只知道它与动画变化有关系,那么Action系列类究竟都是些什么玩意呢?
好,搞定它,我们下章就对Action相关源码做分析。
已发表评论数()
&&登&&&陆&&
已收藏到推刊!
请填写推刊名
描述不能大于100个字符!
权限设置: 公开
仅自己可见

我要回帖

更多关于 cocos2dx场景切换特效 的文章

 

随机推荐