Cocos2DX - >图层实例化场景?

时间:2014-11-07 09:30:23

标签: c++ cocos2d-x

阅读关于Cocos2dx的书籍和主题,每个人似乎都在教这样:

  1. 创建一个继承自CCLayer的类
  2. 在该CCLayer类中,实例化Static SCENE
  3. 将布局添加到场景
  4. 隐喻,就像Egg创造了它的父母一样。这看起来倒退,不直观。为什么不这样做:

    1. 创建一个继承自CCScene的类(称之为GameScene)
    2. 创建另一个继承自CCLayer的类(称之为GameLayer)
    3. GameScene类是一个单例(有一个单例成员:静态GameScene *场景)
    4. 在GameScene类中实例化GameLayer类
    5. GameLayer类将拥有通常的嫌疑:UPDATE,INIT等,而GameScene类具有INIT及其静态自引用成员。

      虽然这可能看起来更有效,但它实际上并非逻辑上更有意义,而且,它为开发人员提供了一个位置,放置SCENE特定逻辑和LAYER特定逻辑。

      这样做有什么问题吗?为什么有这么多人向后教学呢?

      示例

      #GameScene

      #ifndef __GameScene__
      #define __GameScene__
      
      #include "cocos2d.h"
      using namespace cocos2d;
      
      class GameScene : public cocos2d::CCScene
      {
      
      public:
          ~GameScene();
          virtual bool init();
          static GameScene* scene();
          CREATE_FUNC(GameScene);
      };
      
      #endif /* defined(__GameScene__) */
      
      #include "GameScene.h"
      #include "GameLayer.h"
      
      GameScene::~GameScene() {}
      
      GameScene* GameScene::scene()
      {
          GameScene *scene = GameScene::create();
          GameLayer *layer = GameLayer::create();
          scene->addChild(layer);
          return scene;
      }
      
      bool GameScene::init()
      {
          if (!CCScene::init()) return false;
          return true;
      }
      

      #GameLayer

      #ifndef __GAMELAYER_H__
      #define __GAMELAYER_H__
      
      #include "cocos2d.h"
      
      using namespace cocos2d;
      
      class GameLayer : public cocos2d::CCLayer
      {
      public:
          ~GameLayer();        
          virtual bool init();
          virtual void draw();
          void update(float dt);        
          CREATE_FUNC(GameLayer);
      };
      
      #endif // __GAMELAYER_H__
      
      #include "GameLayer.h"
      
      GameLayer::~GameLayer() {}
      
      bool GameLayer::init()
      {
          if (!CCLayer::init())
              return false;
      
          this->schedule(schedule_selector(GameLayer::update));
          return true;
      }
      
      void GameLayer::draw() {}
      
      void GameLayer::update(float dt) {}
      

      最后在AppDelegate CPP中

      bool AppDelegate::applicationDidFinishLaunching()
      {
          // initialize director
          ...
          ...
      
          // Create a scene
          GameScene *pScene = GameScene::scene();
      
          // Run
          pDirector->runWithScene(pScene);
          return true;
      }
      

      我在cocos2dx上也有关于这个主题的主题:

        

      http://discuss.cocos2d-x.org/t/layer-instantiates-scene/18149/4

2 个答案:

答案 0 :(得分:4)

基类名和子类名之间存在混淆。

例如,cocos2d-x wiki他们是Layer(CCLayer)的子类,但他们将这个Layer子类命名为GameScene,即使它不是一个真实的场景,它是一层。进一步向下,他们通过调用createScene创建实际的Scene(CCScene)实例,我假设它返回一个通用的Scene实例,并将GameScene实例添加到场景中:

auto scene = GameScene::createScene();
Director::getInstance()->replaceScene(scene);

所以你最终会得到以下层次结构:

Scene
    Layer (custom class: GameScene)
        Nodes...

现在,这种奇怪的命名理念的起源仅仅是它已经在cocos2d社区中流传了很长时间。在非常早期的cocos2d-iphone项目模板中,您有一个继承自HelloWorldScene的{​​{1}}类。它包含一个类方法CCLayer,它创建了一个scene实例,创建了一个CCScene实例,并在返回之前将其添加到通用场景实例中。

所以基本上这只是一个混乱,因为在项目模板,教程和书籍中命名错误的子类。反对所有理性思考的传统"在cocos2d-x中占了上风。在cocos2d-iphone中,最终通过将模板类重命名为HelloWorldScene来修复(在v2.x中我相信)。

答案 1 :(得分:1)

Rodger Engelbert Cocos2d-x示例作者,初学者指南通过电子邮件回复此问题。

  

嗨Jason,

     

无需遵循模板中使用的策略。事实上   我不认识在Cocos2d-x组之外做任何人的人,而且我只是   曾经在本书的例子中用它来保持一致性。

     

场景是独一无二的,它是导演运行所需要的。它' S   转换期间可能有两个场景在运行,但不然   场景在结构上被视为您体系结构中的一个块。您   可能会也可能不会将您的项目组织成多个块,但是您   至少需要一个。

     

但是你可以以任何你想要的方式自由地做到这一点。你可以使用场景   更重要的是,正如一些开发人员为此而做或只使用一个   主管,并专注于主层对象。另外,请记住   模板中生成的代码只是试图给你一个   帆布尽快。它不是最好的起点   指向您的项目。由你做出决定。

     

罗杰