【cocos2d-x】C++利用类名动态生成对象,类似于Objective-C Class *aclass = [object class]

这个类主要是用于replaceScene用习惯了Objective-C直接传入类,然后动态生成该CCLayer的对象,以下是Objective-C的写法,这样写不需要每个CCSene都要写一个switch-case,现在用cocos2d-x,所以也模仿Objective-C 动态生成的方法,在网上找了资料,也整合到cocos2d-x中。(本来在网上找了很好的资料,没保存,额,放不了链接,下次找到在编辑了)Objective-C 版本
+(void)replaceLayer:(Class)layer
{
    CCScene *scene = [[CCScene alloc]init];
    
    CCLayer *node = [[layer alloc]init];
    [scene addChild:node];
    
    [[CCDirector sharedDirector] replaceScene:[CCTransitionFade transitionWithDuration:1.0 scene:scene]];
    
    [node release];
    [scene release];
}
C++ 版本,和OC一样,定义成类变量
void SceneManager::onReplaceScene(const Class *className)
{
    CCLayer *pLayer = className->newInstace();
    pLayer->init();
    pLayer->autorelease();
    CCScene *pScene = CCScene::create();
    pScene->addChild(pLayer);
    CCDirector::sharedDirector()->replaceScene(pScene);
}



//Class 类的实现

//Class.h

#ifndef __ClassTest__Class__
#define __ClassTest__Class__

#include <iostream>
#include <map.h>
#include <string.h>
#include "cocos2d.h"

using namespace cocos2d;
using namespace std;

class Class;

class BaseLayer : public CCLayer {
    
public:
    CCSize winSize;
    
public:
    static const Class *theClass;
    virtual bool init();
  // 用来配置iphone5的背景图
    CCSprite *spriteForBg(string fileName);
    
    BaseLayer();
    virtual ~BaseLayer();
};

template <class T>
class ObjectFactory {

public:
    static BaseLayer *create(){
        return new T();
    }
    
};

class Class {
private:
    BaseLayer *(*factory)(void);
    static map<string, Class *>classMap;
    string name;
    
    Class() {
        
    }
    
public:
    template<class T> static Class *Register(string className) {
        if (classMap.count(className) == 0) {
            Class *cls = new Class();
            cls->factory = &ObjectFactory<T>::create; 
            cls->name = className;
            classMap[className] = cls;
        }
        
        return classMap[className];
    }
    
    static Class *forName(string clsName);
    
    BaseLayer *newInstace() const;
    string getName() const;
    virtual ~Class();
    
};

#endif /* defined(__ClassTest__Class__) */

//Class.cpp

#include "Class.h"

#pragma mark ----Class------

map<string, Class *> Class::classMap = map<string, Class *>();

string Class::getName() const
{
    return name;
}

Class *Class::forName(string clsName)
{
    if (classMap.count(clsName) != 0) {
        return classMap[clsName];
    }
    
    return NULL;
}

BaseLayer *Class::newInstace() const
{
    return factory();
}

Class::~Class()
{
    
}

#pragma  mark ------BaseLayer------------

const Class *BaseLayer::theClass = Class::Register<BaseLayer>("BaseLayer");

BaseLayer::BaseLayer()
{
    winSize = CCDirector::sharedDirector()->getWinSize();
}

BaseLayer::~BaseLayer()
{
    
}

bool BaseLayer::init()
{
    if (CCLayer::init()) {
        
    }
    
    return true;
}

CCSprite *BaseLayer::spriteForBg(string fileName)
{
    string str = fileName;
    
    unsigned c = str.find('.');
    string firstStr = str.substr(0,c);
    string extenStr = str.substr(c+1,str.length());
    
    if (winSize.width == 568 || winSize.height == 568 || winSize.width == 1136 || winSize.height == 1136) {
        firstStr = firstStr.append("-568h@2x");
    }
    
    char name[64] = "";
    
    sprintf(name, "%s.%s",firstStr.c_str(),extenStr.c_str());
    
    return CCSprite::create(name);
    
}

//如何使用,我就写个简单的使用吧
//MainLayer.h
#ifndef __ClassTest__MainLayer__
#define __ClassTest__MainLayer__

#include 
  
   
#include "Class.h"

class MainLayer : public BaseLayer {
    
public:
    static const Class *theClass;
    
public:
    MainLayer();
    virtual ~MainLayer();
    
    virtual bool init();
    CREATE_FUNC(MainLayer);
private:
    void onGame();

};

#endif /* defined(__ClassTest__MainLayer__) */

//MainLayer.cpp

#include "MainLayer.h"
#include "SceneManager.h"
#include "GameLayer.h"

const Class *MainLayer::theClass = Class::Register
   
    ("MainLayer"); MainLayer::MainLayer() { } MainLayer::~MainLayer() { } bool MainLayer::init() { if (BaseLayer::init()) { CCSprite *bg = this->spriteForBg("bg.png"); bg->setPosition(ccp(winSize.width/2, winSize.height/2)); this->addChild(bg); CCMenuItemFont *fontItem = CCMenuItemFont::create("Game", this, menu_selector(MainLayer::onGame)); fontItem->setPosition(ccp(winSize.width/2, winSize.height/2)); CCMenu *menu = CCMenu::create(fontItem,NULL); menu->setPosition(CCPointZero); this->addChild(menu,1); } return true; } void MainLayer::onGame() { SceneManager::onReplaceScene(GameLayer::theClass); } 
   
  

你可能感兴趣的:(c,cocos2d-x,CCScene跳转的方法,C++利用类名动态创建对象,C++动态生成对象)