cocos2dx场景A跳转到场景B,然后场景B再向A回传值(委托设计模式
class Delegator
{
public:
virtual ~Delegator(){};
virtual void callback(void* ctx,const char* str) = 0;
};
其中callback是纯虚函数,必须在子类中实现,就是在LayerA类中实现。这个函数就是将生成的数,按照const char*的格式传回到LayerA。为什么是这个格式?因为cocos2dx用的的字符串格式就是const char*而不是std::string。前面的void*是无类型的指针格式,就是可以存储任何指针类型,这个参数在后面介绍。
#include "cocos2d.h"
#include "Delegator.h"
class LayerB : public cocos2d::Layer
{
Delegator* _Delegate;
public :
static cocos2d::Scene* createScene();
virtual bool init();
void menUpdata(cocos2d::Ref* pSender);
void menCallback(cocos2d::Ref* pSender);
void setDelegator(Delegator* delegator);
CREATE_FUNC(LayerB);
};
static cocos2d::Scene* createScene();
virtual bool init();
这两个函数是cocos2dx场景模板自带的(静态工厂创建模式),不是今天介绍的内容。
Delegator* _Delegate;
void setDelegator(Delegator* delegator);
重点说下这两行代码,因为抽象函数是不能实例化对象的,所以要想创建Delegator类的对象指针,必须有其子类实现了基类里的纯虚函数,这个类就是LayerA,所以要把指向LayerA对象的指针赋值给_Delegate变量,LayerB才能算是“拥有了”Delegator接口。显然,setDelegator()函数的任务就是完成这项任务。
#include "LayerB.h"
#include "Delegator.h"
USING_NS_CC;
Scene* LayerB::createScene()
{
auto scene = Scene::create();
auto layer = LayerB::create();
scene->addChild(layer);
return scene;
}
bool LayerB::init()
{
if ( !Layer::init() )
{
return false;
}
Size visibleSize = Director::getInstance()->getVisibleSize();
Vec2 origin = Director::getInstance()->getVisibleOrigin();
//Updata菜单
auto menUpdata = MenuItemFont::create("Updata",CC_CALLBACK_1(LayerB::menUpdata,this));
menUpdata->setPosition(Vec2(visibleSize.width,visibleSize.height)/2);
//menCallback菜单
auto menCallback = MenuItemFont::create("menCallback",CC_CALLBACK_1(LayerB::menCallback,this));
menCallback->setPosition(Vec2(visibleSize.width/2,visibleSize.height/2 - 100));
auto menu = Menu::create(menUpdata,menCallback,NULL);
menu->setPosition(Vec2::ZERO);
this->addChild(menu,1);
return true;
}
以上没什么说的,就是创建两个菜单,然后加入回调函数。 void LayerB::menUpdata(Ref* pSender)
{
int num = CCRANDOM_0_1() * 1000;
__String* str = __String::createWithFormat("Updata %d",num);
//回调A场景
_Delegate->callback(this,str->getCString());
}
第一行:随机生成一个1000以内的数字 void LayerB::menCallback(Ref* pSender)
{ Director::getInstance()->popScene(); }
退出该场景没什么说的。 void LayerB::setDelegator(Delegator* Delegator)
{
_Delegate = Delegator;
}
这个函数功能在上面介绍过,他的使用是在LayerA中使用,到时候在具体说。
#include "cocos2d.h"
#include "LayerB.h"
#include "Delegator.h"
class LayerA : public cocos2d::Layer,public Delegator
{
public:
static cocos2d::Scene* createScene();
virtual bool init();
//跳转到场景B
void menNextScene(cocos2d::Ref* pSender);
//实现接口
virtual void callback(void* ctx,const char* str);
CREATE_FUNC(LayerA);
};
这里说一点值得注意的是LayerA类是继承了cocos2d::Layer和 Delegator这两个类,这是为什么可以把LayerA类的对象的指针赋值给LayerB对象里面的Delegator*类型的成员变量_Delegate。
#include "LayerA.h"
USING_NS_CC;
Scene* LayerA::createScene()
{
auto scene = Scene::create();
auto layer = LayerA::create();
scene->addChild(layer);
return scene;
}
bool LayerA::init()
{
if ( !Layer::init() )
{
return false;
}
Size visibleSize = Director::getInstance()->getVisibleSize();
Vec2 origin = Director::getInstance()->getVisibleOrigin();
//next菜单
auto muNext = MenuItemFont::create("Next Scene",CC_CALLBACK_1(LayerA::menNextScene,this));
muNext->setPosition(Vec2(visibleSize.width,visibleSize.height)/2);
auto menu = Menu::create(muNext,1);
//场景A显示传回来的的随机数字标签
auto label = Label::createWithTTF("","fonts/Marker Felt.ttf",24);
label->setPosition(Vec2( visibleSize.width/2,visibleSize.height/2 -100 ));
this->addChild(label,1,100);
return true;
}
上面是创建一个菜单和一个标签 void LayerA::menNextScene(Ref* pSender)
{
auto sc = Scene::create();
auto layerB = LayerB::create();
layerB->setDelegator(this);
sc->addChild(layerB);
Director::getInstance()->pushScene(sc);
}
第一行:创建一个场景 void LayerA::callback(void* ctx,const char* str)
{
Label* label = (Label*)this->getChildByTag(100);
if(label){
label->setString(str);
}
}
该函数实现了Delegator抽象类里面的纯虚函数,还记得LayerB中的menUpdata函数调用了它吗?他会把参数传到这里来进行处理。 到此就算实现了,但是还有一个void* ctx参数没有用,并且在LayerB的menUpdata函数里面给他传进来的是this,即LayerB的对象指针。你们如何使用它呢?不能直接用,要转换类型。如下 //这样转换后layer就相当于LayerB的对象指针
LayerB* layer = (LayerB*)ctx;
//这样转换后layer就相当于LayerA的对象指针
LayerA* layer = (LayerA*)ctx;
这样在callback()函数里面就可以调用LayerB的对象指针进行操作了,这里没有用到,但是在cocos2dx继承的SAX方式解析XML文件的时候函数理由有void* ctx这个参数,在解析的时候会用到,写他是为了为解析XML做铺垫。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |