马上加入IBC程序猿 各种源码随意下,各种教程随便看! 注册 每日签到 加入编程讨论群

C#教程 ASP.NET教程 C#视频教程程序源码享受不尽 C#技术求助 ASP.NET技术求助

【源码下载】 社群合作 申请版主 程序开发 【远程协助】 每天乐一乐 每日签到 【承接外包项目】 面试-葵花宝典下载

官方一群:

官方二群:

Cocos2d-x入门之旅[4]场景

[复制链接]
查看2254 | 回复1 | 2019-10-24 09:49:35 | 显示全部楼层 |阅读模式

我们之前讲了场景图(Scene Graph) 的概念,继续之前你先要知道

  • 场景图决定了场景内节点对象的渲染次序
  • 渲染时 z-order 值大的节点对象会后绘制,值小的节点对象先绘制

HelloWorld

你还记得HelloWorld场景是如何启动的么?回看我们工程里的AppDelegate.cpp,滚到applicationDidFinishLaunching()的尾部:

  1. <code>// create a scene. it&#39;s an autorelease object
  2. auto helloWorldscene = HelloWorld::createScene();
  3. // run
  4. director->runWithScene(helloWorldscene);</code>
复制代码

Ctrl+鼠标左键 点选createScene()查看界说,可以看到这个函数在HelloWorldScnen.h内声明,在HelloWorldScnen.cpp内界说

  1. <code>// HelloWorldScnen.h
  2. static cocos2d::Scene* createScene();
  3. // HelloWorldScnen.cpp
  4. Scene* HelloWorld::createScene()
  5. {
  6. return HelloWorld::create();
  7. }</code>
复制代码

我们可以通过该函数获取一个HelloWorld场景对象

之后就是场景的初始化,菜单,精灵等对象的Set都在这里进行

  1. <code>bool HelloWorld::init()
  2. {
  3. ...
  4. }</code>
复制代码

末了我们看到一个回调函数

  1. <code>void HelloWorld::menuCloseCallback(Ref* pSender)
  2. {
  3. //Close the cocos2d-x game scene and quit the application
  4. Director::getInstance()->end();
  5. }</code>
复制代码

C++底子差的同砚可能还不理解回调的概念,但你只必要知道,这个函数实现了:HelloWorld场景内点击关闭按可钮关闭窗口 的功能,就行了、

SecondScene

如今我们对着HelloWorld的代码来创建一个SecondScene

和HelloWorld一样,起首我们必要一份SecondScene.h存放声明,然后是一份SecondScene.cpp存放界说

留意VS内新建文件时,肯定要保存到Class文件夹内,不然你是不能直接include“xxxxxx”的(万恶的VS默认保存路径不是Class

094935t6hs5ho6hzqsv3hr.png

修改到项目目次下的Class

094936j0smkhrmk6zzirk6.png

SecondScene.h

起首是套一层宏掩护到头尾

  1. <code>#ifndef __SECOND_SCENE_H__
  2. #define __SECOND_SCENE_H__
  3. #endif // __SECOND_SCENE_H__</code>
复制代码

然后

  1. <code>#include "cocos2d.h"</code>
复制代码

如今我开始我们要做一点点小变化,我们让SecondScene继续Layer而不是Scene

  1. <code>class SecondScene : public cocos2d::Layer {
  2. public:
  3. static cocos2d::Scene* createScene();
  4. virtual bool init();
  5. CREATE_FUNC(SecondScene);
  6. //暂时不必要回调函数
  7. };</code>
复制代码

实际上之前的cocos实例工程里HelloWorld都是继续自Layer的,不知为何如今改了,但是无妨,我们借此时机介绍Layer和Scene的区别

SecondScene.cpp

起主要include我们之前写好的SecondScene.h,为了方便我们也和HelloWorld一样using namespace cocos2d

你可能看到了HelloWorld.cpp里写的是USING_NS_CC而不是using namespace cocos2d,但着实效果是一样的

094936e4pt3m8pzzxzzhe9.png

接下来我们界说creatSceen()函数,也和HelloWorld::createScene()略有不同

  1. <code>Scene* SecondScene::createScene() {
  2. //创建一个Scene类的对象scene
  3. auto scene = Scene::create();
  4. //创建一个SecondScene类的对象layer
  5. auto SecondScene = SecondScene::create();
  6. //把layer添加到scene里
  7. scene->addChild(layer);
  8. //返回scene
  9. return scene;
  10. }</code>
复制代码

理解起来很简朴:起首我们创建了一个Scene类的对象scene,然后创建了一个SecondScene类的对象layer(别忘了我们的SecondScene继续自layer),再把layer添加到了scene里,末了返回我们的scene

之后就可以开始写初始化函数了

  1. <code>bool SecondScene::init() {
  2. auto visibleSize = Director::getInstance()->getVisibleSize();
  3. Vec2 origin = Director::getInstance()->getVisibleOrigin();
  4. Label* label = Label::create("Second Test", "fonts/Marker Felt.ttf", 24);
  5. label->setPosition(
  6. Vec2(
  7. origin.x + visibleSize.width / 2,
  8. origin.y + visibleSize.height - label->getContentSize().height
  9. )
  10. );
  11. this->addChild(label); // 默认z-order=0
  12. return true;
  13. }
  14. </code>
复制代码

我们不消加太多东西,加入一个label让自己知道这是SecondScene场景就行

如今我们去步伐的入口,AppDelegate.cpp里看看,还记得启动HelloWorld场景的那两行代码么,我们改成启动SecondScene场景:

(记得先要加入#include "SecondScene.h"到AppDelegate.cpp里)

  1. <code>// create a scene. it&#39;s an autorelease object
  2. auto helloWorldscene = HelloWorld::createScene();
  3. // run
  4. director->runWithScene(helloWorldscene);
  5. </code>
复制代码

改成

  1. <code>auto secondScene = SecondScene::createScene();
  2. director->runWithScene(secondScene);
  3. </code>
复制代码

运行测试:

094937loybgayavdoawcab.png

没有问题

场景切换

接下来我们把AppDelegate.cpp还原归去(Crtl+Z),让步伐运行时还是从HelloWorld场景开始,然后实验使用回调函数切换到SecondScene

由于我们要在HelloWorld切换到Second,以是我们必要在HelloWorld场景里添加一个回调变乱,刚好HelloWolrd里就有一个关闭按钮的回调,我们改改代码就行(这里重点是演示如何切换,真的不是我懒)

追踪到HelloWorld::menuCloseCallback()

Director::getInstance()->END改成

  1. <code>Director::getInstance()->replaceScene(
  2. SecondScene::createScene()
  3. );
  4. </code>
复制代码

运行测试,不出意外再点击HelloWorld右下角的关闭按钮,就会一刹时切换到Second

切换动画

Cocos内置了许多切换场景的动画,比如

  1. <code>Director::getInstance()->replaceScene(
  2. TransitionSlideInT::create(
  3. 3.0f, SecondScene::createScene()
  4. )
  5. );
  6. </code>
复制代码

运行,Second会在3秒内从上平滑切换掉HelloWorld

别的切换动画就不赘述了,和Actions又异曲同工之妙,各自己试试吧

场景栈

我们之前都是在使用replaceScene进行场景切换,replaceScene会使前一个场景被开释(简朴来说就是删掉了,不再占用内存,想找回来只能重新创建一个),节省了内存资源,但有时我们不希望场景被开释怎么办呢

Cocos还提供了 推进pushScene()和弹出popScene两种方法,把一系列场景存储到栈内,按需弹出(开释)和推进新场景

是一种数据结构,你可以简朴理解为一个弹匣,对栈有两种操作:

  1. 入栈(push),装入子弹
  2. 出栈(pop),射出子弹

子弹总是最上面的先被射出(pop时栈顶的元素开始出栈),也就是“先进后出”

新加入场景时使用pushScene(),新旧场景就会被存入场景栈,新在上旧在下(也就是说旧的场景没有开释),popScene会将新的场景开释,旧的场景就被弹了上来原来的位子,表现旧场景

你可以在场景初始化函数内写一段期待x秒的代码(换个思绪,可以写一个计时器),验证pop后表现的旧场景不是新创建的:

  1. <code>bool HelloWorld::init()
  2. {
  3. ...
  4. for(int i = 0; i <19999999; i++)// 耗时操作
  5. ...
  6. }
  7. </code>
复制代码

发挥你的奇思妙想,另有什么方法,自己实验一下

层和场景

这个好理解,想想你玩过的2d游戏,或者Photoshop的图层界面,一个场景里可以有好几个层

场景内创建层很简朴:

  1. <code>Layer* layer2 = Layer::create();
  2. </code>
复制代码

当然一个层必须添加到场景内才会见效,层无法离开场景独立存在

之后的学习中我们会进一步领会到层的作用







来源:https://www.cnblogs.com/zhxmdefj/p/11727785.html
C#论坛 www.ibcibc.com IBC编程社区
C#
C#论坛
IBC编程社区
*滑块验证:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则