Cocos2d-x入门之旅[4]场景
我们之前讲了场景图(Scene Graph) 的概念,继续之前你先要知道
- 场景图决定了场景内节点对象的渲染顺序
- 渲染时 z-order 值大的节点对象会后绘制,值小的节点对象先绘制
HelloWorld
你还记得HelloWorld场景是如何启动的么?回看我们工程里的AppDelegate.cpp,滚到applicationDidFinishLaunching()的尾部:
// create a scene. it's an autorelease object
auto helloWorldscene = HelloWorld::createScene();
// run
director->runWithScene(helloWorldscene);
Ctrl+鼠标左键 点选createScene()查看定义,可以看到这个函数在HelloWorldScnen.h内声明,在HelloWorldScnen.cpp内定义
// HelloWorldScnen.h
static cocos2d::Scene* createScene();
// HelloWorldScnen.cpp
Scene* HelloWorld::createScene()
{
return HelloWorld::create();
}
我们可以通过该函数获取一个HelloWorld场景对象
之后就是场景的初始化,菜单,精灵等对象的Set都在这里进行
bool HelloWorld::init()
{
...
}
最后我们看到一个回调函数
void HelloWorld::menuCloseCallback(Ref* pSender)
{
//Close the cocos2d-x game scene and quit the application
Director::getInstance()->end();
}
C++基础差的同学可能还不理解回调的概念,但你只需要知道,这个函数实现了:HelloWorld场景内点击关闭按可钮关闭窗口 的功能,就行了、
SecondScene
现在我们对着HelloWorld的代码来创建一个SecondScene
和HelloWorld一样,首先我们需要一份SecondScene.h存放声明,然后是一份SecondScene.cpp存放定义
注意VS内新建文件时,一定要保存到Class文件夹内,不然你是不能直接include“xxxxxx”的(万恶的VS默认保存路径不是Class)
修改到项目目录下的Class
SecondScene.h
首先是套一层宏保护到头尾
#ifndef __SECOND_SCENE_H__
#define __SECOND_SCENE_H__
#endif // __SECOND_SCENE_H__
然后
#include "cocos2d.h"
现在我开始我们要做一点点小变化,我们让SecondScene继承Layer而不是Scene
class SecondScene : public cocos2d::Layer {
public:
static cocos2d::Scene* createScene();
virtual bool init();
CREATE_FUNC(SecondScene);
//暂时不需要回调函数
};
实际上之前的cocos实例工程里HelloWorld都是继承自Layer的,不知为何现在改了,但是无妨,我们借此机会介绍Layer和Scene的区别
SecondScene.cpp
首先要include我们之前写好的SecondScene.h,为了方便我们也和HelloWorld一样using namespace cocos2d
你可能看到了HelloWorld.cpp里写的是
USING_NS_CC而不是using namespace cocos2d,但其实效果是一样的
接下来我们定义creatSceen()函数,也和HelloWorld::createScene()略有不同
Scene* SecondScene::createScene() {
//创建一个Scene类的对象scene
auto scene = Scene::create();
//创建一个SecondScene类的对象layer
auto SecondScene = SecondScene::create();
//把layer添加到scene里
scene->addChild(layer);
//返回scene
return scene;
}
理解起来很简单:首先我们创建了一个Scene类的对象scene,然后创建了一个SecondScene类的对象layer(别忘了我们的SecondScene继承自layer),再把layer添加到了scene里,最后返回我们的scene
之后就可以开始写初始化函数了
bool SecondScene::init() {
auto visibleSize = Director::getInstance()->getVisibleSize();
Vec2 origin = Director::getInstance()->getVisibleOrigin();
Label* label = Label::create("Second Test", "fonts/Marker Felt.ttf", 24);
label->setPosition(
Vec2(
origin.x + visibleSize.width / 2,
origin.y + visibleSize.height - label->getContentSize().height
)
);
this->addChild(label); // 默认z-order=0
return true;
}
我们不用加太多东西,加入一个label让自己知道这是SecondScene场景就行
现在我们去程序的入口,AppDelegate.cpp里看看,还记得启动HelloWorld场景的那两行代码么,我们改成启动SecondScene场景:
(记得先要加入#include "SecondScene.h"到AppDelegate.cpp里)
// create a scene. it's an autorelease object
auto helloWorldscene = HelloWorld::createScene();
// run
director->runWithScene(helloWorldscene);
改成
auto secondScene = SecondScene::createScene();
director->runWithScene(secondScene);
运行测试:

没有问题
场景切换
接下来我们把AppDelegate.cpp还原回去(Crtl+Z),让程序运行时还是从HelloWorld场景开始,然后尝试使用回调函数切换到SecondScene
由于我们要在HelloWorld切换到Second,所以我们需要在HelloWorld场景里添加一个回调事件,刚好HelloWolrd里就有一个关闭按钮的回调,我们改改代码就行(这里重点是演示如何切换,真的不是我懒)
追踪到HelloWorld::menuCloseCallback():
把Director::getInstance()->END改成
Director::getInstance()->replaceScene(
SecondScene::createScene()
);
运行测试,不出意外再点击HelloWorld右下角的关闭按钮,就会一瞬间切换到Second
切换动画
Cocos内置了很多切换场景的动画,比如
Director::getInstance()->replaceScene(
TransitionSlideInT::create(
3.0f, SecondScene::createScene()
)
);
运行,Second会在3秒内从上平滑切换掉HelloWorld
别的切换动画就不赘述了,和Actions又异曲同工之妙,各自己试试吧
场景栈
我们之前都是在使用replaceScene进行场景切换,replaceScene会使前一个场景被释放(简单来说就是删掉了,不再占用内存,想找回来只能重新创建一个),节省了内存资源,但有时我们不希望场景被释放怎么办呢
Cocos还提供了 推进pushScene()和弹出popScene两种方法,把一系列场景存储到栈内,按需弹出(释放)和推进新场景
栈是一种数据结构,你可以简单理解为一个弹匣,对栈有两种操作:
- 入栈(push),装入子弹
- 出栈(pop),射出子弹
子弹总是最上面的先被射出(pop时栈顶的元素最先出栈),也就是“先进后出”
新加入场景时使用pushScene(),新旧场景就会被存入场景栈,新在上旧在下(也就是说旧的场景没有释放),popScene会将新的场景释放,旧的场景就被弹了上来原来的位子,显示旧场景
你可以在场景初始化函数内写一段等待x秒的代码(换个思路,可以写一个计时器),验证pop后显示的旧场景不是新创建的:
bool HelloWorld::init()
{
...
for(int i = 0; i <19999999; i++)// 耗时操作
...
}
发挥你的奇思妙想,还有什么方法,自己实验一下
层和场景
这个好理解,想想你玩过的2d游戏,或者Photoshop的图层界面,一个场景里可以有好几个层
场景内创建层很简单:
Layer* layer2 = Layer::create();
当然一个层必须添加到场景内才会生效,层无法离开场景独立存在
之后的学习中我们会进一步体会到层的作用
Cocos2d-x入门之旅[4]场景的更多相关文章
- Cocos2d-x入门之旅[1]场景
在游戏开发过程中,你可能需要一个主菜单,几个关卡和一个END的界面,如何组织管理这些东西呢? 和其他游戏引擎类似,Cocos也使用了场景(Scene) 这个概念 试想象一部电影或是番剧,你不难发现它是 ...
- Swift语言入门之旅
Swift语言入门之旅 学习一门新的计算机语言,传统来说都是从编写一个在屏幕上打印"Hello world"的程序開始的.那在 Swift,我们使用一句话来实现它: printl ...
- cocos2d基础入门
HelloCpp中Classes目录下放开发者自己的类: win32:平台相关,coco2d已默认创建:coco2d-x目录下,samples/cpp/HelloCpp/(工程根目录)图片放置位置:根 ...
- nginx入门系列之应用场景介绍
目录 HTTP服务器 反向代理服务器 作为一个虚拟主机下多个应用的反向代理 作为多个虚拟主机的反向代理 负载均衡器 简单轮训策略 最小连接数策略 客户端IP哈希策略 服务器权重策略 邮件代理服务器 官 ...
- Cocos2d-x入门之旅[2]精灵
精灵就是cocos是屏幕上移动的对象,能被我们控制,比如我们HelloWorld场景的这个图片就是精灵(Sprite) 怎么才算精灵?你能控制它的,就是一个精灵,否则就只是一个节点(Node) 准确的 ...
- Cocos2d-x入门之旅[3]动作
Cocos通过动作(Action)可以让精灵动起来,把数个动作组成序列(Sequence)就能让精灵做出连续的动作,在动作中我们可以改变精灵的位置,旋转角度,缩放比例,等等 动作(Action) 首先 ...
- Cocos2d-x入门之旅
Cocos通过动作(Action)让精灵动起来,把数个动作组成序列(Sequence)就能让精灵做出连续的动作,在动作中我们可以改变精灵的位置,旋转角度,缩放比例,等等 动作(Action)# 首先我 ...
- IOS-swift5.1快速入门之旅
快速之旅 传统表明,新语言中的第一个程序应在屏幕上打印“Hello,world!”字样.在Swift中,这可以在一行中完成: print("Hello, world!") // P ...
- 云原生 - 体验Istio的完美入门之旅(一)
作者:justmine 头条号:大数据达摩院 微信公众号:大数据处理系统 创作不易,在满足创作共用版权协议的基础上可以转载,但请以超链接形式注明出处. 为了方便大家阅读,可以关注头条号或微信公众号,后 ...
随机推荐
- Hbase 日常运维
日常维护的命令 1,major_compact 'testtable',通常生产环境会关闭自动major_compact(配置文件中hbase.hregion.majorcompaction设 为0) ...
- [kuangbin带你飞]专题一 简单搜索 题解报告
又重头开始刷kuangbin,有些题用了和以前不一样的思路解决.全部题解如下 点击每道题的标题即可跳转至VJ题目页面. A-棋盘问题 棋子不能摆在相同行和相同列,所以我们可以依此枚举每一行,然后标记每 ...
- Linux 笔记 - 第二十一章 配置 NFS 服务
一.前言 NFS(Network File System,网络文件系统),主要功能是通过网络(一般是局域网)让不同的主机系统之间可以共享文件或目录.NFS 客户端(一般为应用服务器,例如web)可以通 ...
- centos php7 安装mysqli扩展心得
在新配服务器时发现,php无法连接到mysql.通过phpinfo发现.根本没有显示mysqli的相关配置.经过一系列研究.总结了下.: 第一步: 在phpinfo里没有mysqli配置,原因是安装p ...
- 01.Django基础一之web框架的本质
一 web框架的本质及自定义web框架 我们可以这样理解:所有的Web应用本质上就是一个socket服务端,而用户的浏览器就是一个socket客户端,基于请求做出响应,客户都先请求,服务端做出对应的响 ...
- CSS从大图中抠图然后显示其中的一部分
相信大家在使用css时会遇到一个情况吧 就是一张大图片里面什么都有 各种图标都有 然而自己就是不太会使用其中的小图标 这是我最近的一次学习 首先上图 这么大一张图片 那么这么使其只显示一部分 并且为我 ...
- Spring boot 官网学习笔记 - Spring DevTools 介绍
想要使用devtools支持,只需使用dependencies将模块依赖关系添加到你的构建中 运行打包的应用程序时,开发人员工具会自动禁用.如果你通过 java -jar或者其他特殊的类加载器进行启动 ...
- python自动化测试三部曲之untitest框架
终于等到十一,有时间写博客了,准备利用十一这几天的假期把这个系列的博客写完 该系列文章本人准备写三篇博客 第一篇:介绍python自动化测试框架unittest 第二篇:介绍django框架+requ ...
- overflow滚动条如何隐藏
隐藏滚动条有很多方法,比较简单和直观的方法可以使用::-webkit-scrollbar来完成 例如: .box::-webkit-scrollbar{ display:none } 这样的话就把bo ...
- 体验Code::Blocks下的Windows GUI编程(32 bit and 64 bit)
0. 前言 不知道为什么,几乎所有的C++编程教程都是从命令行版(控制台应用程序)的Hello World开始的.然而,对于现在的年轻人来说,从小就用鼠标点击窗口或图标操作电脑,对于那个神秘黑色的窗口 ...


