《Cocos2D-x权威指南》——3.3 场景类

3.3 场景类

CCScene类是CCNode的子类。和CCNode相比,它只是添加了一个特性,那就是拥有自己的锚点,位置在屏幕的正中央。除此之外,它目前还没有额外的功能,只是一个抽象的概念。
3.1节中介绍CCNode类时,把屏幕上所有显示对象的父节点设置为我们定义的节点,这个父节点的角色一般由场景承担。CCScene类的继承关系如图3-9所示。

可以看到,CCScene类有CCTransitionScene(切换场景类),并且CCTransitionScene类有很多子类,这些类都用于切换场景的特效,将在本节的后半段介绍。
注意 游戏通常都会出现这种情况,当切换场景时,程序会由于旧场景的内存没有释放并且新场景已经载入,出现短暂的“峰值”,但是不必为此而做额外的工作,因为Cocos2D-x引擎会清除旧场景的内存。但是要注意,正确使用内存的保留与释放(这点会在后面介绍),尤其是使用场景切换特效的时候,你要做的工作是尽早上机测试和合理的内存使用。
下面来看CCScene类在游戏中的使用和场景切换特效。

3.3.1 如何新建一个场景

下面通过HelloWorld项目中新建场景的过程来总结使用场景的过程。
1)定义一个场景类实例。
Cocos2D-x引擎中的HelloWorld范例中,HelloWorldScene.cpp中的scene函数即是新建场景的地方,如代码清单3-9所示。
代码清单3-9 HelloWorld新建场景类实例

CCScene* HelloWorld::scene()
{
    //新建场景类实例
    CCScene *scene = CCScene::create();
    //CCScene *scene = CCScene::node();
    //定义布景层
    HelloWorld *layer = HelloWorld::create();

    //将布景层加入场景
    scene->addChild(layer);

    //返回场景类
    return scene;
}

通过create方法构造一个场景,当然,create函数是Cocos2D-x 2.0以后的版本 才有的方式,2.0之前的版本采用的是后面被注释掉的方法,然后将定义的布景层作为子项加入场景中,要显示的成员都在布景层中。至于布景层的定义,将在后面做介绍。
2)获得并运行场景。
在游戏入口AppDelegate类中的applicationDidFinishLaunching函数中调用上一步定义的方法,并使用导演类的runWithScene方法运行场景,如代码清单3-10所示。
代码清单3-10 获得并运行场景

bool AppDelegate::applicationDidFinishLaunching() {
    // 初始化导演类
    CCDirector *pDirector = CCDirector::sharedDirector();

    //设置OpenGL视图
    pDirector->setOpenGLView(&CCEGLView::sharedOpenGLView());

    //设置是否显示每帧时间
    pDirector->setDisplayStats(true);

    //设置每帧时间
    pDirector->setAnimationInterval(1.0 / 60);

    //创建场景
    CCScene *pScene = HelloWorld::scene();

    //运行场景
    pDirector->runWithScene(pScene);

    return true;
}

到这里已经可以新建一个场景并把它加入游戏中了。
这时也许有人会有疑问:一般来讲,游戏都会由多个场景组成,至少会有菜单场景和游戏场景,更复杂的游戏甚至会有更多场景,那么如何在场景间切换呢?下一节将通过引擎自带的tests例子来学习如何在场景间切换。
3.3.2 场景的切换
tests项目是一个Cocos2D-x的功能示例。对于Cocos2D-x的初学者来说,看tests项目中的示例并理解它们,是个不错的学习方式。本节就通过介绍tests的基本结构来介绍场景间的切换。
游戏入口AppDelegate类中的applicationDidFinishLaunching函数如代码清单3-11所示。
代码清单3-11 tests项目的AppDelegate类的applicationDidFinishLaunching函数

bool AppDelegate::applicationDidFinishLaunching()
{

    CCDirector *pDirector = CCDirector::sharedDirector();
    pDirector->setOpenGLView(&CCEGLView::sharedOpenGLView());

    pDirector->setDisplayStats(true);

    pDirector->setAnimationInterval(1.0 / 60);

    CCScene * pScene = CCScene::create();
    CCLayer * pLayer = new TestController();
    pLayer->autorelease();

    pScene->addChild(pLayer);
    pDirector->runWithScene(pScene);

    return true;
}

这里和上一节的applicationDidFinishLaunching有一点区别,它的定义场景和给场景加层的操作都在这个函数里完成,但是本质上是类似的。下面就来看TestController布景层里面是如何调用下一级场景的。
切换场景这个事件应该是在按下主菜单上的按键后发生的,于是找到controller.cpp文件中的menuCallback函数。它是自定义的一个回调函数,在定义布景层时定义。如果不理解这一点,没关系,请跳过,后面会讲解这个问题。
menuCallback函数如代码清单3-12所示。
代码清单3-12 menuCallback函数

void TestController::menuCallback(CCObject * pSender)
{

    CCMenuItem pMenuItem = (CCMenuItem )(pSender);
    int nIdx = pMenuItem->getZOrder() - 10000;

    TestScene* pScene = CreateTestScene(nIdx);
    if (pScene)
    {
        pScene->runThisTest();
        pScene->release();
    }
}

除了处理菜单类的内容,这部分可以暂时跳过。后面调用在controller.cpp文件中定义的CreateTestScene函数获得场景,然后调用场景的runThisTest函数,这是自定义的。
首先来看CreateTestScene函数,如代码清单3-13所示。
代码清单3-13 CreateTestScene函数

static TestScene* CreateTestScene(int nIdx)
{
    //清空缓存
    CCDirector::sharedDirector()->purgeCachedData();

    TestScene* pScene = NULL;

    switch (nIdx)
    {
    case TEST_ACTION_MANAGER:
        pScene = new ActionManagerTestScene();
        break;
    // 中间部分的代码过长,省略到这部分。如果需要完整代码,请参考Cocos2D-x引擎目录下tests
    // 项目的controller.cpp文件
    default:
        break;
    }

    return pScene;
}

这里省略中间的部分,首先调用导演类的清除缓存函数,然后新建场景,并返回场景。
关于场景的定义,来看ActionManagerTestScene场景的定义。ActionManagerTest.h文件中的ActionManagerTestScene类的定义如代码清单3-14所示。
代码清单3-14 ActionManagerTestScene类的定义

class ActionManagerTestScene : public TestScene
{
public:
    virtual void runThisTest();
};
ActionManagerTest.cpp文件中的runThisTest函数的定义如代码清单3-15所示。
代码清单3-15 runThisTest函数的定义
void ActionManagerTestScene::runThisTest()
{
    CCLayer* pLayer = nextActionManagerAction();
    addChild(pLayer);

    CCDirector::sharedDirector()->replaceScene(this);
}

这里做的就是把布景层加入场景中,并把场景通过导演类的replaceScene将当场景替换成场景。
以上过程分为以下三步:
1)调用CCDirector::sharedDirector()->purgeCachedData()清空缓存。
2)新建场景。
3)调用CCDirector::sharedDirector()->replaceScene(this)替换新场景。Cocos2D-x提供了场景间切换的特效,下一节将会介绍这些内容。
注意 不要在节点初始化的init函数中调用replaceScene函数。导演类不允许在一个节点初始化的调用场景替换,否则会导致程序崩溃。
这里说一下压入场景(pushScene)和弹出场景(popScene)。它们都可以用来显示场景和保留当前场景并显示新场景;不同的是它们不把旧场景从内存中释放掉,这样可以提高加载速度,这时需要注意,如果内存不足以支撑的话,建议采用replaceScene函数。
3.3.3 场景间切换的动画
上一节介绍了使用replaceScene切换场景。很多时候,为了游戏效果,使UI更有动态,会在切换界面的过程中加入一些过程动画,如平移切换场景动画(见图3-10)、旋转切换场景动画(见图3-11)。

正常的无过渡场景,如果尚未建立场景(游戏中的第一个场景),使用runWithScene函数即可以使用相应场景;如果是替换场景,则使用replaceScene函数替换相应的场景即可;而如果要使用场景间的切换效果,则需要使用相应的切换类,即在3.1节中介绍的CCTransitionScene子类的create函数(2.0版本之前是transitionWithDuration函数),生成相应场景。当然,不同效果的使用方法略有不同。
然后,通过replaceScene函数启动场景,也就是说给这个场景加了一个外包装类,然后再启动。那么,这个场景就不是直接显示了,而是在场景的效果动画播完以后进入场景,起到过渡的效果。
一般情况,CCTransitionScene子类的create函数有两个参数。第一个参数是特效的切换时间,直接生成一个CCTime类即可,例子中设定的时间是1~2s,对于很多场景的显示都很舒服,你也可以根据你的要求修改切换时间;第二个参数是要进入的场景。有的类会有第三个参数,如表3-6所示。

其中,CCTransitionPageTurn类需要先设置摄像机,使用以下代码:

CCDirector::sharedDirector()->setDepthTest(true)

有三种特效需要检测OpenGL版本是否支持,如表3-7所示。使用如下代码检查,如果为真则不支持:

CCConfiguration::sharedConfiguration()->getGlesVersion() <= GLES_VER_1_0

tests项目的TransitionsTest文件夹中的是场景切换的示例。切换场景动画的使用步骤如下。
1)新建场景。
2)根据需要的新建场景的切换动画选择CCTransitionScene子类,通过create将之前建的场景传入其中,并设置其他参数。
3)调用CCDirector::sharedDirector()->replaceScene(第2步中定义的CCTransitionScene的子类)替换新场景。
下一节开始介绍布景层类CCLayer。

时间: 2024-11-05 04:50:26

《Cocos2D-x权威指南》——3.3 场景类的相关文章

《Cocos2D权威指南》——3.3 CCScene场景类

3.3 CCScene场景类 CCScene是CCNode的子类,和CCNode一样,也是一个抽象类.事实上,CCScene和CCNode几乎完全相同,唯一差异在于CCScene的锚点位置默认在屏幕中心.如果打开模板中CCScene.h文件,大家会发现其中只说明CCScene继承自CCNode,并没有任何其他内容.图3-4是典型的游戏场景跳转示意图.当前版本的Cocos2D中,CCScene类基本上没有附加任何逻辑机制和特殊功能.通常建议将CCScene作为其他所有节点的父节点,看作CCLaye

《Cocos2D权威指南》——3.6 CCSprite精灵类

3.6 CCSprite精灵类 CCSprite是Cocos2D游戏开发中最常用的类,用图片把精灵(sprite)显示在屏幕上. 在游戏开发中,经常会遇到精灵(sprite)这个术语.精灵是一个图像,可以在屏幕上独立地移动.一个精灵可能是玩家角色.敌人,或者是大的背景图像.一般情况下,精灵来自于开发者所准备的PNG或PVRTC图像.一旦图像载入内存,就会将精灵转换成纹理图,从而被iPhone GPU用于在屏幕上渲染.3.6.1 CCSprite类的属性及方法 生成精灵的最简单方法是把图片文件加载

《Cocos2D权威指南》——第3章 3.0 Cocos2D核心类

第3章 3.0 Cocos2D核心类 本章主要分析第2章代码示例,同时向大家展示构成Cocos2D的核心类如何组织在一起并构成一个完整的游戏.几乎任何一款Cocos2D游戏中都会用到这些类,所以了解它们的作用.属性和方法,以及如何使用这些类,有助于我们开发出更好的游戏.掌握了这些基本知识,大家会发现Cocos2D并没有想象的那么难:而且即使只用这些类,也可以创造出很有意思的游戏.掌握这些游戏构建的关键类和关键概念之后,我们在开始一个新的游戏项目时会更加得心应手.

《ELK Stack权威指南 》第3章 场景示例

本节书摘来自华章出版社<ELK Stack权威指南 >一书中的第1章,第3节,作者饶琛琳,更多章节内容可以访问"华章计算机"公众号查看. 场 景 示 例 前面虽然介绍了几十个Logstash插件的常见配置项,但是过多的选择下,如何组合使用这些插件,依然是一部分用户的难题.本章将列举一些最常见的日志场景,演示针对性的组件搭配,希望能给读者带来启发. 本章介绍的场景包括:Nginx访问日志.Nginx错误日志.Postfix日志.Ossec日志.Windows系统日志.Java

《Cocos2D权威指南》——导读

前言 为什么要写这本书 2011年10月5日,秋风萧瑟,阴雨绵绵,在这颗蔚蓝色的美丽星球上,一代传奇伟人乔布斯在亲友的陪伴下安然离去,宛若流星划过天际,空留那辆银色的奔驰SL55AMG在落叶纷飞中孤独守候着曾经的主人.这个世界从此失去了一位引领科技创新的时代领袖. 从1976年在父母的车库中创业开始,乔布斯参与.开创并改变了几个行业-PC.电脑动画.数字音乐.移动互联网.他创办了苹果公司,中途又因某些原因被苹果驱逐.然而在苹果挣扎于濒死的边缘时,他又挺身而出将苹果救活,并把它推到无人可以企及的高

《Cocos2D权威指南》——1.4 深入学习HelloCocos2D项目

1.4 深入学习HelloCocos2D项目 在完成了第一个HelloCocos2D项目后,如果读者不仅想看到飞机在屏幕上飞行,还想知道这一切是怎样实现的,我们不妨来一起探究其中的每一行代码.1.4.1 初识场景和节点 要想理解HelloCocos2D这个项目,首先要了解场景(CCScene).层(CCLayer)和节点(CCNode)的概念. Cocos2D游戏是由不同的场景构成的,由导演(CCDirector)负责运行和切换各个场景.在Cocos2D中,CCDirector在任何一个时间点上

《Cocos2D-x权威指南》——3.4 布景层类

3.4 布景层类 布景层类CCLayer是CCNode类的子类,并且在此基础上实现触屏事件代理(TouchEventsDelegate)协议,可以实现CCNode类的功能,并且可以处理输入,包括触屏和加速度传感器. 每个游戏场景中可以有很多层,每一层负责各自的任务,如专门负责显示地图的背景.专门负责显示敌人.专门负责机关和专门负责主角等:每一层上可以放置不同的元素,包括文本.精灵图片和菜单等.通过层与层之间的组合关系,就可以构成游戏显示的界面UI,游戏中等.当然为了看到每一层的东西,可把一些层设

Ansible权威指南.

Linux/Unix技术丛书 Ansible权威指南 李松涛 魏 巍 甘 捷 著 图书在版编目(CIP)数据 Ansible权威指南 / 李松涛,魏巍,甘捷著. -北京:机械工业出版社,2016.11 (Linux/Unix技术丛书) ISBN 978-7-111-55329-8 I. A- II. ①李- ②魏- ③甘- III. 程序开发工具-指南 IV. TP311.561-62 中国版本图书馆CIP数据核字(2016)第258615号 Ansible权威指南 出版发行:机械工业出版社(北

《ELK Stack权威指南 》第2章 插件配置

本节书摘来自华章出版社<ELK Stack权威指南 >一书中的第1章,第2节,作者饶琛琳,更多章节内容可以访问"华章计算机"公众号查看. 插 件 配 置 插件是Logstash最大的特色.各种不同的插件源源不断地被创造出来,发布到社区中供大家使用.本章会按照插件的类别,对一般场景下的一些常用插件做详细的配置和用例介绍.本章介绍的插件包括:1)输入插件.基于shipper端场景,主要介绍STDIN.TCP.File等插件.2)编解码插件.编解码通常是会被遗忘的环节,但是运用好