分析Cocos2d-x 场景切换

时间:2023-02-07 20:03:15

本文三部分:

1.前言

2.菜单按钮执行场景切换

3.场景切换特效


1.前言

场景切换,我觉得可以分为两种:

1)一种就是自动切换,比如玩游戏碰到的,游戏加载完成时的切换,这种一般有个事件触发机制,本次暂先不讲。

2)还有就是点击切换,比如点击某个按钮,回调函数时场景切换。


首先说一下,我们刚开始创建新的项目后,开始的HelloWorld场景是怎么显现出来的呢?


C++程序在运行时,首找main函数,可以发现,在新建项目中Classes里面没有main函数,难道Cocos2d-x没有main函数吗?当然...不是!


其实在win32目录下,main.cpp和main.h


打开main.cpp 可以看到:

 
 
#include "main.h"#include "AppDelegate.h"#include "cocos2d.h"USING_NS_CC; int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCEhPrevInstance, LPTSTRlpCmdLine, intnCmdShow) { UNREFERENCED_PARAMETER(hPrevInstance);UNREFERENCED_PARAMETER(lpCmdLine);// create the application instanceAppDelegate app;returnApplication::getInstance()->run(); }


最上面那三行,不用多说,接下来的using namespace cocos2d。然后是Cocos2d-x的入口 APIENTRY _tWinMain。接下来,看到了创建了AppDelegate对象,然后,run函数。


暂时先说到这,感兴趣的,可以跟踪一下,看具体有什么,怎么执行。


在AppDelegate类中,有个函数applicationDidFinishLaunching(),这个函数是程序启动后调用的函数,一般在这个函数里创建设备与场景。


这里我用的以前的项目,所以创建的场景不是HelloWorld的。

 
 bool AppDelegate::applicationDidFinishLaunching() { // initialize directorauto director = Director::getInstance();auto glview = director->getOpenGLView();if(!glview) {glview = GLView::create("My Game");director->setOpenGLView(glview);}// turn on display FPSdirector->setDisplayStats(true);// set FPS. the default value is 1.0/60 if you don't call thisdirector->setAnimationInterval(1.0 / 60);// create a scene. it's an autorelease objectauto scene = WelcomeScene::createScene();// rundirector->runWithScene(scene);returntrue; } <span style="BACKGROUND-COLOR: #ffffff"></span>


然后,我们可以看到 director->runWithScene。对的,控制场景运行是 导演在执行的。


2.菜单按钮的场景切换

现在来进行场景的切换吧,先要创建一个场景,这里就用我以前创建的Welcomscene场景,在里面加一个按钮,通过按钮的回调函数跳转到程序初始原有的HelloWorld场景中。


这里,场景的跳转也有不同方式:

替换,就是用某个场景替换当前场景,原先场景就被释放掉了。

栈式,将现在的场景保存,向入栈一样,压入栈中,显示新场景,如果新场景释放,将原场景显示。原场景不释放,耗内存大。


①替换

先演示,替换的,主要就是在回调函数中导演的动作,我先在WelcomeScene场景中新建背景图层即一个菜单按钮。

WelcomeScene.h:

 
 #include "cocos2d.h"classWelcomeScene : publiccocos2d::Layer { public:// 创建场景函数staticcocos2d::Scene* createScene(); virtualbool init(); voidmenujumpCallback(cocos2d::Ref* pSender); // 是一个宏定义CREATE_FUNC(WelcomeScene);}; 


WelcomeScene.cpp:

 
#include "WelcomeScene.h"#include "HelloWorldScene.h"USING_NS_CC; // 创建场景函数 Scene* WelcomeScene::createScene(){ auto scene = Scene::create();auto layer = WelcomeScene::create();scene->addChild(layer);returnscene; } boolWelcomeScene::init() { // 判断是否能初始化,若不能则直接返回,退出。if( !Layer::init() ) {returnfalse; }// 获得屏幕高度与宽度与起点坐标Size visibleSize = Director::getInstance()->getVisibleSize();Point origin = Director::getInstance()->getVisibleOrigin();// 背景图片auto mysprite=Sprite::create("backg.png");mysprite->setPosition(Point(visibleSize.width/2,visibleSize.height/2));this->addChild(mysprite,0);// 创建菜单按钮,三个参数,第一个为点击前样子,第二个为点击后样子,第三个为点击按钮所执行的函数(就是回调函数)auto jumpItem = MenuItemImage::create("icon01.png","icon01.png",CC_CALLBACK_1(WelcomeScene::menujumpCallback,this)); // 设置放置按钮的位置(宽度:屏幕最右侧-按钮的宽度/2,高度:屏幕最下侧-按钮高度/2,因为锚点在中心,所以除以2)jumpItem->setPosition(Point(origin.x + visibleSize.width - jumpItem->getContentSize().width/2 ,origin.y + jumpItem->getContentSize().height/2));// 添加到菜单auto menu = Menu::create(jumpItem, NULL);menu->setPosition(Point::ZERO);this->addChild(menu, 1);returntrue; } voidWelcomeScene::menujumpCallback(Ref* pSender) { // 创建HelloWorld场景auto scene=HelloWorld::createScene();// 让导演 用HelloWorld场景 ☆替换☆ 现在的场景,注意是替换!Director::getInstance()->replaceScene(scene);}


注意,要调用哪个场景时,不要忘了添加那个场景的头文件。


主要看一下回调函数,创建HelloWorld场景,然后导演执行的replaceScene函数,所以是替换操作。


②栈换

然后再试一试,压栈出栈的场景跳转。


这时候,需要两个场景的配合,以为这样场景切换,主要用于游戏进行时,点击暂停,我们需要将现在场景压栈,然后弹出暂停界面,点击暂停界面返回,这时候就出栈,原场景重现。


这时候,我们改变一下,HelloWorld场景中,关闭按钮的回调函数,让它进行导演的pop操作。


WelcomeScene.cpp,只有回调函数改变了:

 
 void WelcomeScene::menujumpCallback(Ref* pSender) { // 创建HelloWorld场景auto scene=HelloWorld::createScene();// 让导演 用HelloWorld场景 ☆压栈☆ 现在的场景Director::getInstance()->pushScene(scene);} <span style="BACKGROUND-COLOR: #ffffff"></span>

HelloWorldScene.cpp,也是只有回调函数改变:

 
void HelloWorld::menuCloseCallback(Ref* pSender) { // 让导演 ☆出栈☆ 现在的场景Director::getInstance()->popScene();}

我们可以Push很多个场景,每一次Pop恢复上一个,当然也可以通过 void popToRootScene() 来回到根场景,就是最初的场景。

这就是第二种进行入栈,出栈式的场景切换。


3.切换动画效果

Cocos2d-x 引擎,对于切换场景提供了很多动画效果。


我们来试一试吧。

 
void WelcomeScene::menujumpCallback(Ref* pSender) { auto scene=HelloWorld::createScene();auto scene02=TransitionZoomFlipY::create(1.0f,scene);Director::getInstance()->replaceScene(scene02);}

在第一行创建了HelloWorld场景,在第二行创建动画效果的场景,第三行导演类执行替换场景,用第二行创建的场景。


一般第二行的参数必要的为两个(多长时间动画(浮点类型),切换到的目标场景),第三个可选,一般都有,这次我用的动画效果API里是这样的:

分析Cocos2d-x 场景切换

Orientation就是一些转换方向的类型:

分析Cocos2d-x 场景切换

动画效果还有很多:

 
//慢慢淡化到另一场景 TransitionCrossFade::create(时间,目标场景);//本场景变暗消失后另一场景慢慢出现TransitionFade::create(时间,目标场景);//本场景右上角到左下角方块消失到另一场景TransitionFadeBL::create(时间,目标场景);//本场景从上到下横条消失到另一场景TransitionFadeDown::create(时间,目标场景);//本场景左下角到右上角方块消失到另一场景TransitionFadeTR::create(时间,目标场景);//本场景从下到上横条消失到另一场景TransitionFadeUp::create(时间,目标场景);//本场景翻转消失到另一场景(斜上方)TransitionFlipAngular::create(时间,目标场景,样式 );//本场景翻转消失到另一场景(X轴)TransitionFlipX::create(时间,目标场景,样式);//本场景翻转消失到另一场景(Y轴)TransitionFlipY::create(时间,目标场景);//本场景跳动消失后另一场景跳动出现TransitionJumpZoom::create(时间,目标场景);//另一场景由整体从下面出现TransitionMoveInB::create(时间,目标场景);//另一场景由整体从左面出现TransitionMoveInL::create(时间,目标场景);//另一场景由整体从上面出现TransitionMoveInT::create(时间,目标场景);//另一场景由整体从右面出现TransitionMoveInR::create(时间,目标场景);//翻页切换,bool为true是向前翻。TransitionPageTurn::create(时间,目标场景,bool);//本场景从左到右消失同时另一场景出现TransitionProgressHorizontal::create(时间,目标场景);//本场景从中间到四周消失同时另一场景出现TransitionProgressInOut::create(时间,目标场景);//本场景从四周到中间消失同时另一场景出现TransitionProgressOutIn::create(时间,目标场景);//本场景逆时针消失到另一场景TransitionProgressRadialCCW::create(时间,目标场景);//本场景顺时针消失到另一场景TransitionProgressRadialCW::create(时间,目标场景);//本场景从上到下消失同时另一场景出现TransitionProgressVertical::create(时间,目标场景);//本场景旋转消失后另一场景旋转出现TransitionRotoZoom::create(时间,目标场景);//本场景缩小切换到另一场景放大TransitionShrinkGrow::create(时间,目标场景);//本场景向上滑动到另一场景TransitionSlideInB::create(时间,目标场景);//本场景向右滑动到另一场景TransitionSlideInL::create(时间,目标场景);//本场景向左滑动到另一场景TransitionSlideInR::create(时间,目标场景);//本场景向下滑动到另一场景TransitionSlideInT::create(时间,目标场景);//本场景三矩形上下消失后另一场景三矩形上下出现TransitionSplitCols::create(时间,目标场景);//本场景三矩形左右消失后另一场景三矩形左右出现TransitionSplitRows::create(时间,目标场景);//本场景小方块消失到另一场景TransitionTurnOffTiles::create(时间,目标场景);//本场景翻转消失到另一场景(斜上方)TransitionZoomFlipAngular::create(时间,目标场景,样式);//本场景翻转消失到另一场景(X轴)TransitionZoomFlipX::create(时间,目标场景,样式);//本场景翻转消失到另一场景(Y轴)TransitionZoomFlipY::create(时间,目标场景,样式);