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

回顾一下上一篇的内容我们已经学会了创建一个新的场景scene,添加spritelabel到层中掌握了定时事件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表示这个函数的只有一个参数

 

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

  1. //开头这四句肯定是添加到init()函数里的  
  2. auto item= MenuItemFont::create("Hello,Menu",CC_CALLBACK_1(MenuScene::Menutest, this));  
  3. auto menu= Menu::create();  
  4. menu->addchild(item);  
  5. this->addchild(menu);  
  6.    
  7. voidMenuScene::Menutest(Ref *ref){  
  8. //此处可以添加一个精灵,每点击一次菜单按钮就添加一个精灵到场景中。  
  9. }  

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

  1.  auto item =MenuItemFont::create("Hello, Menu",CC_CALLBACK_1(MenuScene::Menutest,this));  
  2.  auto item1 =MenuItemFont::create("Ruck, Menu",CC_CALLBACK_1(MenuScene::Menutest1, this));  
  3.  auto item2 =MenuItemFont::create("Click, Menu",CC_CALLBACK_1(MenuScene::Menutest2, this));  
  4.  auto item3 =MenuItemFont::create("KTWork", CC_CALLBACK_1(MenuScene::KTWork,this));  
  5.  auto item4 =MenuItemFont::create("PushScene", CC_CALLBACK_1(MenuScene::PushScene,this));  
  6.  auto item5 =MenuItemFont::create("HomeWork", CC_CALLBACK_1(MenuScene::HomeWork,this));  
  7.  auto item6 =MenuItemFont::create("HomeWork0617",CC_CALLBACK_1(MenuScene::HomeWorkSnow, this));  
  8.  auto item7 =MenuItemFont::create("KT0618", CC_CALLBACK_1(MenuScene::KT0618,this));  
  9.   
  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. his->addchild(menu);  

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

voidMenuScene::Menutest1(Ref *ref){

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

  1.     if (item->getColor() == Color3B::RED)  
  2.     {  
  3.         item->setColor(Color3B::GREEN);  
  4.         item->setFontSizeObj(55);  
  5.        item->setFontNameObj("Baskerville-Boldltalic");  
  6.        item->setString("GreenClick");  
  7.     }  
  8.     else  
  9.     {  
  10.         item->setColor(Color3B::RED);  
  11.         item->setFontSizeObj(24);  
  12.        item->setFontName("Baskerville-Boldltalic");  
  13.        item->setString("RedClick");  
  14.     }  
  15. }  

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

见效果图:


 

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

MenuItemLabelMenuItemImageMenuItemSprite

下面拿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了。

  1. auto item1 = MenuItemLabel::create(Label::createWithBMFont("fonts/futura-48.fnt""Easy"), CC_CALLBACK_1(HomeWorkSnow::Start, this));  
  2. item1->setUserObject(String::create("Easy"));  
  3. auto item2 = MenuItemLabel::create(Label::createWithBMFont("fonts/futura-48.fnt""Hard"), CC_CALLBACK_1(HomeWorkSnow::Start, this));  
  4. item2->setUserObject(String::create("Hard"));  
  5. auto item3 = MenuItemLabel::create(Label::createWithBMFont("fonts/futura-48.fnt""Difficult"), CC_CALLBACK_1(HomeWorkSnow::Start, this));  
  6. item3->setUserObject(String::create("Difficult"));  
  7. auto item4 = MenuItemLabel::create(Label::createWithBMFont("fonts/futura-48.fnt""Hell"), CC_CALLBACK_1(HomeWorkSnow::Start, this));  
  8. item4->setUserObject(String::create("Hell"));  
  9. auto menu = Menu::create(item1, item2, item3, item4, NULL);  
  10. addChild(menu);  
  11. menu->alignItemsVertically();  

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

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

  1. void  HomeWorkSnow::Start(Ref *ref)  
  2. {  
  3.     MenuItemLabel *item = (MenuItemLabel*)ref;  
  4.     String * str = (String *)item->getUserObject();  
  5.   
  6.     auto scene = HomeWorkSnowFight::createScene();  
  7.     HomeWorkSnowFight *layer = (HomeWorkSnowFight*)scene->getChildren().at(0);  
  8.   
  9.     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. }  
  6.    

在类中我们通常设变量为私有通过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);//这个针对于指针变量。你现在使用可能会有崩溃的地方,这个在后面的内存管理会详细讲。这个宏定义没有想象的那么简单,提醒一下,要修改类的构造和析构函数。  

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

 


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

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

效果如下:





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

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值