cocos2d-x 自定义的场景转换

    虽然coco2d-x里提供了很多强大的场景转换类 ,但有时候自己需要的一些效果cocos2d-x还是无法解决,毕竟越是方便的东西越有它的局限性,所以我就自己定义了一个场景转换类:

    因为自定义的场景转换类 需要继承 CCTransitionScene场景转换基类,于是我还是把场景转换类的代码 全部看了一遍,以防在某些环节使用不当而导致未知的错误,所以我先来说明CCTransitionScene 的内部构造和实现方式。

首先,我们来看看 CCTransitionScene的定义

class CC_DLL CCTransitionScene : public CCScene
{

protected:
    //载入场景
    CCScene    * m_pInScene;
    //载出场景
    CCScene    * m_pOutScene;
    //动画播放时间
    float    m_fDuration;
    //顾名思义 就是载入场景是否置顶
    bool    m_bIsInSceneOnTop;
    //载出场景是否需要被清理,在clearnup()中被调用
    bool    m_bIsSendCleanupToScene;

public:

    CCTransitionScene();
    virtual ~CCTransitionScene();
    //决定场景 层的先后顺序
    virtual void draw();
    virtual void onEnter();
    virtual void onExit();
    //清理载出场景
    virtual void cleanup();

    /** creates a base transition with duration and incoming scene
    @deprecated: This interface will be deprecated sooner or later.
    */
    //CC_DEPRECATED_ATTRIBUTE 表示 不建议使用的,分配空间函数
    CC_DEPRECATED_ATTRIBUTE static CCTransitionScene * transitionWithDuration(float t, CCScene *scene);

    /** creates a base transition with duration and incoming scene */
    //同上,现在cocos2d-x把地址分配函数都 统一成create ,这点做的很好
    static CCTransitionScene * create(float t, CCScene *scene);

    /** initializes a transition with duration and incoming scene */
    //初始化函数,一般不需要自己调用
    virtual bool initWithDuration(float t,CCScene* scene);

    /** called after the transition finishes */
    //销毁函数,当新场景载入完成时隐式销毁旧场景
    void finish(void);

    /** used by some transitions to hide the outer scene */
    //隐藏旧场景 显示新场景
    void hideOutShowIn(void);

protected:
    //把载入场景置顶
    virtual void sceneOrder();
private:
    void setNewScene(float dt);

};

看看各个函数的定义

CCTransitionScene * CCTransitionScene::create(float t, CCScene *scene)
{
    CCTransitionScene * pScene = new CCTransitionScene();//分配地址
    if(pScene && pScene->initWithDuration(t,scene))//初始化
    {
	//用smart point
        pScene->autorelease();
        return pScene;
    }
    //安全释放,既if(pScene)delete pScene = 0
    CC_SAFE_DELETE(pScene);
    return NULL;
}
transitionWithDuration 函数也是调用create

bool CCTransitionScene::initWithDuration(float t, CCScene *scene)
{
    CCAssert( scene != NULL, "Argument scene must be non-nil");

    if (CCScene::init())
    {
        m_fDuration = t;

        // retain
        m_pInScene = scene;
        m_pInScene->retain();
        //保证2个场景同时存在
m_pOutScene = CCDirector::sharedDirector()->getRunningScene(); if (m_pOutScene == NULL) { m_pOutScene = CCScene::create(); m_pOutScene->init(); } m_pOutScene->retain(); //防止 旧场景 和新场景是 同一场景 CCAssert( m_pInScene != m_pOutScene, "Incoming scene must be different from the outgoing scene" ); // disable events while transitions


        CCDirector* pDirector = CCDirector::sharedDirector();    
        //停止 所有touch 事件
pDirector->getTouchDispatcher()->setDispatchEvents(false);

        让新场景置顶
        this->sceneOrder();

        return true;
    }
    else
    {
        return false;
    }
}


void CCTransitionScene::sceneOrder()
{
    m_bIsInSceneOnTop = true;
}

void CCTransitionScene::draw()
{
    CCScene::draw();
    //画场景的先后顺序 
    if( m_bIsInSceneOnTop ) {
        m_pOutScene->visit();
        m_pInScene->visit();
    } else {
        m_pInScene->visit();
        m_pOutScene->visit();
    }
}

void CCTransitionScene::finish()
{
    // clean up 
     //场景转换完成,还原所有场景 然后delete 掉旧场景 replace 到新场景    
     m_pInScene->setVisible(true);
     m_pInScene->setPosition(ccp(0,0));
     m_pInScene->setScale(1.0f);
     m_pInScene->setRotation(0.0f);
     m_pInScene->getCamera()->restore();
 
     m_pOutScene->setVisible(false);
     m_pOutScene->setPosition(ccp(0,0));
     m_pOutScene->setScale(1.0f);
     m_pOutScene->setRotation(0.0f);
     m_pOutScene->getCamera()->restore();

    //[self schedule:@selector(setNewScene:) interval:0];
    this->schedule(schedule_selector(CCTransitionScene::setNewScene), 0);

}

void CCTransitionScene::setNewScene(float dt)
{    
    CC_UNUSED_PARAM(dt);
    // [self unschedule:_cmd]; 
    // "_cmd" is a local variable automatically defined in a method 
    // that contains the selector for the method
    this->unschedule(schedule_selector(CCTransitionScene::setNewScene));
    CCDirector *director = CCDirector::sharedDirector();
    // Before replacing, save the "send cleanup to scene"
    m_bIsSendCleanupToScene = director->isSendCleanupToScene();
    director->replaceScene(m_pInScene);
    // enable events while transitions(恢复touch事件)
    director->getTouchDispatcher()->setDispatchEvents(true);
    // issue #267
    m_pOutScene->setVisible(true);
}

void CCTransitionScene::hideOutShowIn()
{
    m_pInScene->setVisible(true);
    m_pOutScene->setVisible(false);
}


// custom onEnter
void CCTransitionScene::onEnter()
{
    CCScene::onEnter();
    m_pInScene->onEnter();
    // outScene should not receive the onEnter callback
}

// custom onExit
void CCTransitionScene::onExit()
{
    CCScene::onExit();
    m_pOutScene->onExit();

    // inScene should not receive the onExit callback
    // only the onEnterTransitionDidFinish
    m_pInScene->onEnterTransitionDidFinish();
}

// custom cleanup
void CCTransitionScene::cleanup()
{
    CCScene::cleanup();

    if( m_bIsSendCleanupToScene )
        m_pOutScene->cleanup();
}

还有cocos2d 2.0 的新派生类CCTransitionScene,但今天就写怎么多,下次继续写




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值