美文网首页
Cocos2d-x-04: 场景与层

Cocos2d-x-04: 场景与层

作者: 慧科集团华东校区 | 来源:发表于2017-08-15 10:28 被阅读0次

作者:慧科集团华东校区-朱家聪老师,转载请注明出处及本链接。

场景和层

在一个游戏中往往有多个场景和多个层。每个场景都有一个或者一个以上的层。在我们所创建的游戏工程中,AppDelegate.cpp文件中使用如下代码来创建一个新的场景:

// create a scene. it's an autorelease object
auto scene = HelloWorld::createScene();

// run
director->runWithScene(scene);


class HelloWorld : public cocos2d::Scene
{
public:
    static cocos2d::Scene* createScene();

    virtual bool init();
    
    // a selector callback
    void menuCloseCallback(cocos2d::Ref* pSender);
    
    // implement the "static create()" method manually
    CREATE_FUNC(HelloWorld);
    
    virtual void onExit();
};

Scene* HelloWorld::createScene()
{
    return HelloWorld::create();
}

在老版本的Cocos2d-x中,将HelloWorld定义为一个Layer。然后在createScene()函数中创建所对应的Scene。再将HelloWorld层添加到这个场景中去。而在最新版本的Cocos2d-x中将HelloWorld直接定义为了一个Scene。在这个场景中我们可以去添加自己的层,来搭建我们需要的游戏场景或者UI界面。

场景过渡

一个完整的游戏一般是由多个场景构成的,这些场景之间需要做互相的切换和调度。以一个游戏的开始界面和设置界面为例来学习场景过渡的用法。

搭建开始游戏界面

//创建背景
Sprite *background = Sprite::create("background.png");
background->setContentSize(visibleSize);
background->setAnchorPoint(Vec2::ZERO);
background->setPosition(origin);
this->addChild(background);

//开始按钮
Sprite *startSpriteNormal = Sprite::create("start-up.png");
Sprite *startSpriteSelect = Sprite::create("start-down.png");
MenuItemSprite *startItem = MenuItemSprite::create(startSpriteNormal, startSpriteSelect, CC_CALLBACK_1(StartGameScene::startGame, this));
startItem->setPosition(Vec2(origin.x+visibleSize.width/2 - 100,origin.y+100));



//设置按钮
MenuItemImage *settingItem = MenuItemImage::create("setting-up.png", "setting-down.png", CC_CALLBACK_1(StartGameScene::settingCallback, this));
settingItem->setPosition(Vec2(origin.x+visibleSize.width/2 + 100, origin.y+100));

//菜单
Menu *menu = Menu::create(startItem, settingItem, NULL);
menu->setPosition(Vec2::ZERO);
this->addChild(menu);
startScenestartScene

场景的过渡和切换

在设置按钮的点击回调方法中,添加代码来完成场景的过渡。这里需要使用到的类是TransitionScene以及他的子类。TransitionScene是一个抽象类,表示用于做场景过渡效果的特殊场景,不能用来直接做场景的切换。而是应该用他的各种子类来实现场景切换的效果。这里我们使用TransitionMoveInL来完成一个从屏幕左边移动进入的场景切换效果。使用Director的pushScene函数来弹出一个新的场景。

void StartGameScene::settingCallback(Ref* pSender){
    //创建设置界面场景
    SettingScene *set = SettingScene::create();
    auto *ts = TransitionMoveInL::create(1.0f, set);
    Director::getInstance()->pushScene(ts);
    
};

搭建设置界面

//背景
Sprite *background = Sprite::create("setting-back.png");
background->setPosition(origin);
background->setAnchorPoint(Vec2::ZERO);
background->setContentSize(visibleSize);
this->addChild(background);

//音效
MenuItemImage *soundOn = MenuItemImage::create("on.png","on.png");
MenuItemImage *soundOff = MenuItemImage::create("off.png","off.png");
MenuItemToggle *soundToggle = MenuItemToggle::createWithCallback(CC_CALLBACK_1(SettingScene::toggleCallback, this), soundOn, soundOff, NULL);
soundToggle->setPosition(Vec2(origin.x+visibleSize.width - 150, origin.y+visibleSize.height / 2 + 10));

//背景音乐
MenuItemImage *musicOn = MenuItemImage::create("on.png","on.png");
MenuItemImage *musicOff = MenuItemImage::create("off.png","off.png");
MenuItemToggle *musicToggle = MenuItemToggle::createWithCallback(CC_CALLBACK_1(SettingScene::toggleCallback, this), musicOn, musicOff, NULL);
musicToggle->setPosition(Vec2(origin.x+visibleSize.width - 150, origin.y+visibleSize.height / 2 - 40));

//OK
MenuItemImage *okItem = MenuItemImage::create("ok-up.png", "ok-down.png", CC_CALLBACK_1(SettingScene::okButtonCallback, this));
okItem->setPosition(Vec2(origin.x+visibleSize.width / 2, 50));

//Menu
Menu *menu = Menu::create(soundToggle, musicToggle, okItem, NULL);
menu->setPosition(origin);
this->addChild(menu);

运行效果:


settingScenesettingScene

返回原场景

在设置界面的ok键的回调函数中,编写代码返回前一界面。因为我们在第一次界面转换时使用的是Push方法。这是一种类似于栈的场景管理方法,切换到后一个场景时,前一个场景不会被销毁。所以在需要返回时直接使用Pop方法进行弹出即可。

void SettingScene::okButtonCallback(Ref *pSender){
    Director::getInstance()->popScene();
}

场景的生命周期

在Cocos2d-x中,多个场景在转换显示的时候会经历场景的创建和销毁。有一系列的函数可以用于操作在整个场景的生命周期中的各种事件。

系统函数

//场景的生命周期
bool SettingScene::init()
{
    cout<<"场景初始化"<<endl;
    if ( !Scene::init() )
    {
        return false;
    }    
    return true;
}
void SettingScene::onEnter(){
    Scene::onEnter();
    cout<<"进入场景"<<endl;
}
void SettingScene::onEnterTransitionDidFinish(){
    Scene::onEnterTransitionDidFinish();
    cout<<"进入场景动画完成"<<endl;
}
void SettingScene::onExit(){
    Scene::onExit();
    cout<<"退出场景"<<endl;
}
void SettingScene::onExitTransitionDidStart(){
    Scene::onExitTransitionDidStart();
    cout<<"退出场景动画开始"<<endl;
}
void SettingScene::cleanup(){
    Scene::cleanup();
    cout<<"场景清除"<<endl;
}

多场景过渡

两个场景切换时,关系到两个场景之间的生命周期,在Start场景中也可以编写相关函数来同时监控两个场景。

//场景的生命周期
bool StartGameScene::init()
{
    cout<<"场景初始化"<<"StartScene"<<endl;
    if ( !Scene::init() )
    {
        return false;
    }    
    return true;
}
void StartGameScene::onEnter(){
    Scene::onEnter();
    cout<<"进入场景"<<"StartScene"<<endl;
}
void StartGameScene::onEnterTransitionDidFinish(){
    Scene::onEnterTransitionDidFinish();
    cout<<"进入场景动画完成"<<"StartScene"<<endl;
}
void StartGameScene::onExit(){
    Scene::onExit();
    cout<<"退出场景"<<"StartScene"<<endl;
}
void StartGameScene::onExitTransitionDidStart(){
    Scene::onExitTransitionDidStart();
    cout<<"退出场景动画开始"<<"StartScene"<<endl;
}
void StartGameScene::cleanup(){
    Scene::cleanup();
    cout<<"场景清除"<<"StartScene"<<endl;
}

在考虑多场景切换时,我们需要从以下三种情况来尝试。

使用pushScene()跳转到设置界面

在使用push的从场景1跳转到场景2时,场景1虽然会退出,但是并不会被清除。执行后的控制台输出结果如下:

场景初始化SettingScene
退出场景动画开始StartScene
进入场景SettingScene
退出场景StartScene
进入场景动画完成SettingScene

我们可以发现,StartScene并没有被清除,而只是暂时的退出了。

使用replaceScene()跳转到设置界面

replaceScene来实现场景跳转的时候,会在整个场景过渡动画结束之后清除掉StartScene。所以使用replaceScene来跳转的场景无法再使用popScene来进行返回。

场景初始化SettingScene
退出场景动画开始StartScene
进入场景SettingScene
退出场景StartScene
进入场景动画完成SettingScene
场景清除StartScene

使用popScene()返回前一场景

在使用popScene退出一个场景时会完全清楚这个场景并且退出它。

退出场景动画开始SettingScene
退出场景SettingScene
场景清除SettingScene
进入场景StartScene
进入场景动画完成StartScene

相关文章

  • Cocos2d-x-04: 场景与层

    作者:慧科集团华东校区-朱家聪老师,转载请注明出处及本链接。 场景和层 在一个游戏中往往有多个场景和多个层。每个场...

  • cocos2d第三篇--场景与层

    场景与层的关系 编程的时候往往不需要子类化场景,而是子类化层。虽然场景与层之间是1:n组成的关系,但是通过模板生成...

  • 认知框架

    地下室是信仰层 第一层是心态层 第二层是传统社交范式 第三层是破冰,邀约与场景 第四层进化层,不要待在舒适区,不要...

  • Linux_336_Nginx七层转发场景

    Nginx七层转发场景URL转发应用场景根据HTTP的URL转发的场景,被称之为七层转发(应用层转发),然而LVS...

  • Mybatis3.2不支持Ant通配符TypeAliasesPa

    业务场景 业务场景:首先项目进行分布式拆分之后,按照模块再分为为api层和service层,web层。其中订单业务...

  • 不为场景打造的产品是垃圾!

    不为场景打造出来的产品与垃圾无异! 凯叔的这堂课,这句话我产生了强烈共鸣。首先聊聊什么是场景,场景包含两层含义,时...

  • Cocos2d-x 基础知识

    导演Director、场景Scene、布景层Layer、精灵Sprite 导演控制场景,场景控制图层,图层控制精灵...

  • utils层与tools层,manager层与service层,

    https://blog.csdn.net/cchchunhe/article/details/89452279[...

  • 定位引擎产品框架说明文档

    定位引擎产品由上至下分为四层,编码实现层、场景应用层、通用算法层、数据采集层,以及测试平台 编码实现层 主要工作:...

  • 总结21年5月22

    关于四层级联问题 1、实际应用场景,3层及以上级联,应用场景都比较少,更多的是俩层表1:n(n:1)的级联方式。 ...

网友评论

      本文标题:Cocos2d-x-04: 场景与层

      本文链接:https://www.haomeiwen.com/subject/gpsmrxtx.html