转:http://www.it165.net/pro/html/201406/16195.html

回顾一下上一篇的内容,我们已经学会了创建一个新的场景scene,添加sprite和label到层中,掌握了定时事件schedule。我们可以顺利的写出打飞机的主场景框架。

上一篇的内容我练习了七个新场景,每一个场景都展示不同的东西,像背景定时切换、各种字体的随机颜色和位置等。每次要切换一个场景都要修改AppDelegate中的调用代码,非常的不方便查看,这一篇我们写场景的切换。每当我们创建一个新的场景的时候只要添加对应按钮到主界面,点击即可以切换过去查看对应的效果。这个有点类似官方提供的cpptest的查看方式,所以说场景切换是非常简单易用的功能。

要点击切换场景,必须要有按钮可以接收消息,所以首先学习一下菜单(Menu):

Menu创建菜单

MenuItem Create 菜单子项的创建

MenuItemFont是字菜子项。

1.auto item= MenuItemFont::create("Hello,Menu",CC_CALLBACK_1(MenuScene::Menutest, this));

"Hello, Menu"是菜单子项按钮的文字。

MenuScene::Menutest是回调函数,它的参数是Menutest(Ref * pSender),这个参数类型是什么可以通过查看create定义来获得。

CC_CALLBACK_1就是绑定一个函数为回调函数,_1表示这个函数的只有一个参数。

我们的第一个菜单可以这样写:

01.//开头这四句肯定是添加到init()函数里的
02.auto item= MenuItemFont::create("Hello,Menu",CC_CALLBACK_1(MenuScene::Menutest, this));
03.auto menu= Menu::create();
04.menu->addchild(item);
05.this->addchild(menu);
06. 
07.voidMenuScene::Menutest(Ref *ref){
08.//此处可以添加一个精灵,每点击一次菜单按钮就添加一个精灵到场景中。
09.}

还可以这样创建一个菜单,不必每次都调用menu->addchild(item):

01.auto item =MenuItemFont::create("Hello, Menu",CC_CALLBACK_1(MenuScene::Menutest,this));
02.auto item1 =MenuItemFont::create("Ruck, Menu",CC_CALLBACK_1(MenuScene::Menutest1, this));
03.auto item2 =MenuItemFont::create("Click, Menu",CC_CALLBACK_1(MenuScene::Menutest2, this));
04.auto item3 =MenuItemFont::create("KTWork", CC_CALLBACK_1(MenuScene::KTWork,this));
05.auto item4 =MenuItemFont::create("PushScene", CC_CALLBACK_1(MenuScene::PushScene,this));
06.auto item5 =MenuItemFont::create("HomeWork", CC_CALLBACK_1(MenuScene::HomeWork,this));
07.auto item6 =MenuItemFont::create("HomeWork0617",CC_CALLBACK_1(MenuScene::HomeWorkSnow, this));
08.auto item7 =MenuItemFont::create("KT0618", CC_CALLBACK_1(MenuScene::KT0618,this));
09. 
10.auto menu =Menu::create(item, item1, item2, item3, item4, item5 ,item6,item7,<span style="color:#ff0000;">NULL);//注意最后一个参数为空</span>
11.menu->setPosition(Director::getInstance()->getVisibleSize().width/ 2,Director::getInstance()->getVisibleSize().height / 2);
12.menu->alignItemsVerticallyWithPadding(40);//看英文就知道是垂直对齐  间隔40像素
13.this->addchild(menu);

在回调函数中操作菜单子项的属性:

voidMenuScene::Menutest1(Ref *ref){

MenuItemFont *item =(MenuItemFont *)ref;//所有的类的基类Ref,我们在菜单中是通过MenuItemFont创建的item,所以在回调函数中可以强制转换回MenuItemFont类型。然后就可以在回调函数中修改菜单子项的属性了。

01.if (item->getColor() == Color3B::RED)
02.{
03.item->setColor(Color3B::GREEN);
04.item->setFontSizeObj(55);
05.item->setFontNameObj("Baskerville-Boldltalic");
06.item->setString("GreenClick");
07.}
08.else
09.{
10.item->setColor(Color3B::RED);
11.item->setFontSizeObj(24);
12.item->setFontName("Baskerville-Boldltalic");
13.item->setString("RedClick");
14.}
15.}

从上面代码可以看到我创建了一个菜单里面有很多子项,这些子项都是场景切换。每一个新的场景都是一个练习。

见效果图:

关于创建菜单子项还有很多方法:

MenuItemLabel、MenuItemImage、MenuItemSprite等

下面拿MenuItemLabel举例(futura-48.fnt在我第一篇打飞机源码的素材里,源码在一楼,这种字体除了fnt还有一个png文件,是一起的,不能分开。这种字体创建的菜单就是下图中黄色的效果。)

autoitem2 =MenuItemLabel::create(Label::createWithBMFont("fonts/futura-48.fnt","Start"), CC_CALLBACK_1(MenuSceneTwo::MenuTest, this));

具体的效果图看下面:

这是我的第一个Hello,Menu场景

上面已经介绍了菜单的创建,尝试这去创建一个新场景吧,点击按钮可以切换不同的背景。

给菜单子项绑定数据

在这里还要学习菜单子项item的两个操作函数。setUserData和setUserObject。

setUserData看定义接收的是void*参数,可以接收任意类型的数据。我们可以用它来传递C++的基本类型数据,但是千万不要自己new一些变量来传值,会造成意外的。

setUserObject接收的是继承自Ref的子类。继承自Ref的子类,最常用的就是cocos2dx本身的String了。

01.auto item1 = MenuItemLabel::create(Label::createWithBMFont("fonts/futura-48.fnt""Easy"), CC_CALLBACK_1(HomeWorkSnow::Start, this));
02.item1->setUserObject(String::create("Easy"));
03.auto item2 = MenuItemLabel::create(Label::createWithBMFont("fonts/futura-48.fnt""Hard"), CC_CALLBACK_1(HomeWorkSnow::Start, this));
04.item2->setUserObject(String::create("Hard"));
05.auto item3 = MenuItemLabel::create(Label::createWithBMFont("fonts/futura-48.fnt""Difficult"), CC_CALLBACK_1(HomeWorkSnow::Start, this));
06.item3->setUserObject(String::create("Difficult"));
07.auto item4 = MenuItemLabel::create(Label::createWithBMFont("fonts/futura-48.fnt""Hell"), CC_CALLBACK_1(HomeWorkSnow::Start, this));
08.item4->setUserObject(String::create("Hell"));
09.auto menu = Menu::create(item1, item2, item3, item4, NULL);
10.addChild(menu);
11.menu->alignItemsVertically();

我们要把set的数据取出来,对应的两个函数是getUserData和getUserObject。

在菜单响应回调函数中,我们可以如下操作:

01.void  HomeWorkSnow::Start(Ref *ref)
02.{
03.MenuItemLabel *item = (MenuItemLabel*)ref;
04.String * str = (String *)item->getUserObject();
05. 
06.auto scene = HomeWorkSnowFight::createScene();
07.HomeWorkSnowFight *layer = (HomeWorkSnowFight*)scene->getChildren().at(0);
08. 
09.layer->setData(mode[str->getCString()]);
10.Director::getInstance()->pushScene(TransitionCrossFade::create(1, scene));
11. 
12.}

第一步是强转,我们用什么类型创建的item,在回调里我们就使用对应的类型强转回来。然后调用item的getUserObjet获取set的值。

后面三句是场景的正向传值,这个会在本篇最后讲到。提前提一下,就是调用下个场景层对象的成员函数做到传道的。

***********************************************************************************************************************************

切换场景

再创建一个新场景,然后使用下面语句添加到菜单回调函数来切换场景:

1.auto scene =KTWork_SwitchBg::createScene();
2.Director::getInstance()->replaceScene(scene);

这样我们就实现了从一个场景切换到另一个场景。

我们可以在另一个场景中尽情的添加想要的精灵,你也可以尝试把昨天创建的打飞机的场景添加进来,点击菜单按钮就可以开始打飞机了!

切换场景动画

如果要使用切换的特效动画,如下修改即可:

1.auto scene =KTWork_SwitchBg::createScene();
2.Director::getInstance()->replaceScene(TransitionPageTurn::create(1,scene,true));

还有(TransitionShrinkGrow::create(1,scene)); (TransitionCrossFade::create(1, scene));等

请多尝试几种特效方法Transition******::create()。

如果你想返回主菜单,只需要在子场景中添加一个返回的按钮即可,聪明的你肯定能想到怎么返回主菜单。

细心的话会发现切换场景的时候会提示有两个切换方式,一种是replacescene,一种是pushscene。这两种切换方式的区别在于,前者释放了当前场景,后者把当前场景压入栈中保存。pushscene的场景要切换回来,只需在子场景中调用popscene即可。 相当于原来的场景暂停了一会。

************************************************************************************************************

场景传值

正向传值

我们在切换场景之前,向下一个场景传递参数,这个是正向传值。

最简单的方法就是给下一个场景的类成员变量赋值。 这样我们就能在主场景控制我们在下一个场景想要展示的属性。

如下回调函数,我们返回的场景获取场景中所有的子节点。请右键查看getChildren的返回值。因为子场景中只有一个节点,所以我们第一个元素肯定是层,也就是 KTWork_PushScene类对象。然后我们可以使用tmp来任意正向传递参数给下个场景。

1.voidMenuScene::PushScene(Ref *ref){
2.this->stopAllActions();
3.auto scene =KTWork_PushScene::createScene();
4.<span style="color:#ff0000;">KTWork_PushScene * tmp = (KTWork_PushScene*)(scene->getChildren().at(0));</span>
5.Director::getInstance()->pushScene(TransitionShrinkGrow::create(1,scene));
6.}

注意:我们在传递参数之前,KTWork_PushScene已经调用过init()函数初始化完毕,那我们应该怎么使传递的值生效呢?答案是使用虚函数onEnter()。onEnter是在切换场景后,展示场景前调用。所以我们可以如下修改代码:

1.voidHomeWork::onEnter()
2.{
3.<span style="color:#ff0000;"> Layer::onEnter(); //一定要先调用父类onEnter方法</span>
4.label->setString(StringUtils::format("%s",strHp.getCString()));//这样我们就动态修改了Label展示的值
5.}

在类中我们通常设变量为私有,通过get、set方法来对其访问。在cocos2dx中,有一个宏可以替代我们定义这两个方法的操作。

1.CC_SYNTHESIZE(int, hp, HP);//定义了一个protected变量hp,定义了两个方法setHP,getHP来获取和设置hp的值。
2.CC_SYNTHESIZE(String, strHp, sHP);
3.CC_SYNTHESIZE_RETAIN(__String *, strname, Name);//这个针对于指针变量。你现在使用可能会有崩溃的地方,这个在后面的内存管理会详细讲。这个宏定义没有想象的那么简单,提醒一下,要修改类的构造和析构函数。

这两个宏大家一定要自己去看一下是如何定义的。

总结:我们学习了菜单,触控响应,切换场景等,现在可以做一个 如下的游戏了。

有四种游戏模式,天空会降落雪花,每一种模式雪花大小不同。 鼠标点击可以使雪花小时。游戏结束返回主场景。

效果如下:

游戏代码我放到一楼去。 这些代码我后期也在优化。可能有一些知识点还没有涉及到。大家可以用一下素材。

可能会看到我主场景有飘雪花的特效,一些烟火特效。这些都是我复制别人的代码实现的,有兴趣的可以自己看一下,很简单。

cocos2dx3.1从零学习(二)菜单、场景切换、场景传值的更多相关文章

  1. Vue学习(二)-Vue中组件间传值常用的几种方式

    版本说明:vue-cli:3.0 主要分为两类: 1.父子组件间的传值 2.非父子组件间的传值 1.父子组件间传值 父组件向子组件传值 第一种方式: props 父组件嵌套的子组件中,使用v-bind ...

  2. cocos2d-x实战 C++卷 学习笔记--第6章 场景与层

    前言: 一个场景(Scene)是由多个层(Layer)组成,而且层的个数要至少是1,不能为0. 场景切换 场景切换相关函数 1)void  runWithScene(Scene*  scene) 该函 ...

  3. cocos2dx 3.1从零学习(四)——内存管理(错误案例分析)

    本篇内容文字比較较多,可是这些都是建立在前面三章写代码特别是传值的时候崩溃的基础上的.可能表达的跟正确的机制有出入,还请指正. 假设有不理解的能够联系我.大家能够讨论一下,共同学习. 首先明白一个事实 ...

  4. 自制Unity小游戏TankHero-2D(5)声音+爆炸+场景切换+武器弹药

    自制Unity小游戏TankHero-2D(5)声音+爆炸+场景切换+武器弹药 我在做这样一个坦克游戏,是仿照(http://game.kid.qq.com/a/20140221/028931.htm ...

  5. cocos2dx 3.1从零学习(二)——菜单、场景切换、场景传值

    回想一下上一篇的内容,我们已经学会了创建一个新的场景scene,加入sprite和label到层中.掌握了定时事件schedule. 我们能够顺利的写出打飞机的主场景框架. 上一篇的内容我练习了七个新 ...

  6. 2、JavaScript 基础二 (从零学习JavaScript)

     11.强制转换 强制转换主要指使用Number.String和Boolean三个构造函数,手动将各种类型的值,转换成数字.字符串或者布尔值. 1>Number强制转换 参数为原始类型值的转换规 ...

  7. es6从零学习(二):promise

    es6从零学习(二):promise 一:promise的由来 某些情况下,回调嵌套很多时,代码就会非常繁琐,会给我们的编程带来很多的麻烦,这种情况俗称——回调地狱.由此,Promise的概念就由社区 ...

  8. 手牵手,从零学习Vue源码 系列二(变化侦测篇)

    系列文章: 手牵手,从零学习Vue源码 系列一(前言-目录篇) 手牵手,从零学习Vue源码 系列二(变化侦测篇) 陆续更新中... 预计八月中旬更新完毕. 1 概述 Vue最大的特点之一就是数据驱动视 ...

  9. 场景切换特效Transition——Cocos2d-x学习历程(十二)

    Transition 场景切换 在游戏中通常会用到一些场景的切换,比如从加载界面切换到欢迎界面.游戏中的所有场景存放在一个栈中,有且只有一个场景可以处于激活状态.直接replaceScene(即不适用 ...

随机推荐

  1. RTMP流媒体播放过程:握手,建立连接,建立流,播放

    本文讲述从打开一个RTMP流媒体到视音频数据开始播放的整个过程. 播放一个流媒体有两个前提步骤: 第一步,建立一个网络连接(NetConnection): 第二步,建立一个网络流(NetStream) ...

  2. 7 款基于 JavaScript/AJAX 的文件上传插件

    本文整理了7款基于JavaScript和AJAX的文件上传插件,这些插件基本上都能实现以下功能: 多文件上传 拖拽操作 实时上传进度 自定义上传限制 希望能为你的开发工作带来帮助. 1.  jQuer ...

  3. (四)Qt实现自定义模型基于QAbstractTableModel (一般)

    Qt实现自定义模型基于QAbstractTableModel 两个例子 例子1代码 Main.cpp #include <QtGui> #include "currencymod ...

  4. Geometric deep learning on graphs and manifolds using mixture model CNNs

    Monti, Federico, et al. "Geometric deep learning on graphs and manifolds using mixture model CN ...

  5. Ubuntu之Docker安装

    1.添加官方的GPG key到系统 curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - 2.添加D ...

  6. 中国餐馆过程(Chinese restaurant process)

    也就是说假设空桌子有a0个人,然后顾客选择桌子的概率和桌子上人数成正比. 性质: 改变用户的排列方式,桌子的排列方式,概率不变换.

  7. Spring IO platform 简介

    前提:熟悉Spring基础知识. 简介:Spring IO Platform将 the core Spring APIs 集成到一个Platform中.它提供了Spring portfolio中的大量 ...

  8. Ubuntu13.04下Eclipse中文乱码解决

    参考:http://www.linuxidc.com/Linux/2011-12/50056.htm baoyu@baoyu:~$ gedit /var/lib/locales/supported.d ...

  9. linux centos 系统怎么设置中文模式

    首先,需要安装一下linux桌面程序.一般系统有自带的桌面,然后我们打开系统,进入系统登录界面 2 我们先输入我们的帐号然后回车,之后接着输入密码,你会发现最下面边框有让你选择语言的选项 3 我们点击 ...

  10. 工厂模式(factory pattern) ------创造型模式

    创建型模式 简单工厂模式的缺点是: 当我们引入新产品时,由于静态工厂方法通过所传入参数的不同来创建不同的产品,需要修改工厂类的方法,违反了“开闭原则”. 工厂模式提供了一个抽象工厂接口来声明抽象工厂方 ...