Cocos2d-x 实现委托机制

本文介绍了如何在Cocos2d-x中实现委托机制,通过一个具体的示例——LayerA和LayerB的交互,详细阐述了委托的工作原理。LayerA中的sprite执行action结束后,通过委托机制通知LayerB执行特定方法。文中还解释了动态绑定和多态性的概念,帮助理解委托的实现过程。
摘要由CSDN通过智能技术生成

在 点击打开链接 这里看到一篇关于如何实现委托机制的文章,感觉有点意思,由于这篇文章只是讲了个思路,所以我自己实践了一下,写了一个demo。

实现委托机制demo的情景描述:

LayerA是一个层,里面有个sprite,一旦A被初始化,这个sprite就会执行一个action;LayerB是另一个层。我在LayerB中加入了LayerA,但是要等到A中的那个sprite的action执行完毕后,B再立刻执行另外一个方法。

问题来了,我怎么在LayerB中知道LayerA中的sprite的action执行完了,那么解决的方法就是使用委托机制。

下面直接通过我的demo进行讲解。

(1)首先创建一个VirtualClassC类,里面有一个虚函数。

class VirtualClassC
{
public:
    //虚函数
    virtual void actionFinished(){};
};

(2)接着创建LayerA,这个类继承CCLayer,并且有一个VirtualClassC类实例。

LayerA.h

#ifndef __delegate__LayerA__
#define __delegate__LayerA__

#include <iostream>
#include "VirtualClassC.h"
#include "cocos2d.h"
USING_NS_CC;

class LayerA :public CCLayer
{
public:
    virtual bool init();
    CREATE_FUNC(LayerA);
    
    VirtualClassC *delegate_;
    
    void callBack();
};

#endif /* defined(__delegate__LayerA__) */

LayerA.cpp

#include "LayerA.h"

bool LayerA::init()
{
    if (!CCLayer::init()) {
        return false;
    }
    
    //在LayerA层中添加一个sprite
    CCSprite *pSprite = CCSprite::create("Icon.png");
    CCSize wSize = CCDirector::sharedDirector()->getWinSize();
    pSprite->cocos2d::CCNode::setPosition(wSize.width/2, wSize.height/2);
    this->addChild(pSprite);
    
    //让这个sprite执行一个动作序列
    
    CCSequence *action = CCSequence::create(CCRotateBy::create(0.5, 360),CCCallFunc::create(this, callfunc_selector(LayerA::callBack)),NULL);
    pSprite->runAction(action);
    
    return true;
}


void LayerA::callBack()
{
    if (delegate_) {
        delegate_->actionFinished();
    }
}

(3)最后,创建LayerB,这个类继承 VirtualClassC类和CCLayer类。

Layer.h

#ifndef __delegate__LayerB__
#define __delegate__LayerB__

#include <iostream>
#include "VirtualClassC.h"
#include "LayerA.h"
#include "cocos2d.h"
USING_NS_CC;

//
class LayerB:public VirtualClassC,public CCLayer
{
public:
    virtual bool init();
    static cocos2d::CCScene* scene();
    
    CREATE_FUNC(LayerB);
    
    virtual void actionFinished();
    
    //假如A中action完毕后,B要去执行下面的方法
    void doNext();
};

#endif /* defined(__delegate__LayerB__) */

Layer.cpp

#include "LayerB.h"

bool LayerB::init()
{
    if ( !CCLayer::init() )
    {
        return false;
    }
    
    CCSize wSize = CCDirector::sharedDirector()->getWinSize();
    
    LayerA *layerA = LayerA::create();
    layerA->delegate_ = this;
    layerA->setPosition(0, 0);
    this->addChild(layerA);
    
    CCLabelTTF *label = CCLabelTTF::create("LayerB", "Arial", 24);
    label->setPosition(ccp(wSize.width/2, 80));
    this->addChild(label);
    
    return true;
}

CCScene* LayerB::scene()
{
    // 'scene' is an autorelease object
    CCScene *scene = CCScene::create();
    
    // 'layer' is an autorelease object
    LayerB *layer = LayerB::create();
    
    // add layer as a child to scene
    scene->addChild(layer);
    
    // return the scene
    return scene;
}

void LayerB::actionFinished()
{
    doNext();
}

void LayerB::doNext()
{
    CCLog("LayerA中sprite的acton已经结束");
}

(4)在程序启动的时候

 // create a scene. it's an autorelease object
    CCScene *pScene = LayerB::scene();

    // run
    pDirector->runWithScene(pScene);


显然,程序运行的效果是,LayerA中的sprite执行一个旋转动作后,LayerB就会执行doNext方法,在终端中输出

"LayerAspriteacton已经结束"。


下面对于这个委托机制解释一下(结合OC中的委托机制):

VirtualClassC类中定义了一个虚函数,这个函数相当于就是委托方法;

LayerB继承了这个类,那么就要实现这个类中的虚函数,也即实现了委托方法;

LayerA中定义了一个VirtualClassC类实例,而且在LayerB的init方法中:layerA->delegate_ =this;即将LayerA中的委托对象指定为LayerB。


委托实现再理解:函数调用时,发生动态绑定。

我们知道:基类类型的指针或引用可以指向或引用基类类型对象,或者派生类类型对象。

那么:

1、通过基类类型指针或者引用指向了派生类对象,然后对函数调用

2、所调用函数为虚函数,派生类重写了该虚函数。

这个时候会发生的函数的函数调用是在运行期间才知道的,调用的不是基类版本的函数,而是派生类中的函数,所以是动态绑定。这就是动态多态性了。(静态多态性是函数重载)


在这个例子中:

                                                               

1、首先定义一个基类VirtualClassC,其中有一个虚函数(基类相当于一个委托协议,虚函数相当于委托方法,但还未实现);

2、然后 LayerA 有一个该基类 VirtualClassC 的实例指针(public),使用这个指针调用VirtualClassC 中的虚函数,即调用委托方法LayerA 相当于委托者,基类实例指针相当于委托实例,委托实例调用委托方法);

3、最后 LayerB 继承基类VirtualClassC,成为其子类,重写虚函数,并且创建 LayerA 实例,将 LayerA 中的 VirtualClassC 实例指针指向自己(this)(LayerB 相当于被委托者,需要实现委托方法)。

4、这样的效果是:在 LayerA 中 VirtualClassC 实例调用的是 LayerB 中重写的虚函数(委托方法)。这样就完成了委托的过程。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值