您的位置:首页 > 移动开发 > Cocos引擎

Cocos2d-x学习(十四):用cocos2d-x实现MoonWarriors(暂停和恢复的实现)

2013-01-11 01:04 441 查看
特别声明:本文所有图片资源来源于MoonWarriors cocos2d-html 开源项目

今天搞了半天子弹发射这块,还是没弄完,我打算做一个子弹缓冲池,将所有子弹的图片资源打到同一个图片资源中,用一个CCSpriteBatchNode来绘制,这样在很多子弹的时候,就起到优化的效果了,CCSpriteBatchNode的原理是开启一次opengl绘制,绘制所有子精灵!


1.实现原理

原理不是通过调用 CCDirector::sharedDirector()->pause(),因为这个调用将会导致游戏彻底暂停,而无法返回运行状态!

而我们需要的是暂停的时候是游戏逻辑暂停,但是触摸事件监听不能停止,换句话说就是希望我们能控制哪一部分暂停,哪一部分不暂停。

有一种很繁琐的方法(看起来繁琐,代码不会很多),就是递归遍历需要暂停的层和精灵,调用pause()方法!

另一种简单的方法,就是调用需要暂停的层onExit()方法,这个方法在层中被复写了,其实就是删除重力加速的代理和按键代理。

[cpp] view
plaincopy

<span style="font-size:14px;">void CCLayer::onExit()  

{  

    if( m_bIsTouchEnabled )  

    {  

        CCTouchDispatcher::sharedDispatcher()->removeDelegate(this);  

        unregisterScriptTouchHandler();  

    }  

  

    // remove this layer from the delegates who concern Accelerometer Sensor  

    if (m_bIsAccelerometerEnabled)  

    {  

        CCAccelerometer::sharedAccelerometer()->setDelegate(NULL);  

    }  

  

    // remove this layer from the delegates who concern the kaypad msg  

    if (m_bIsKeypadEnabled)  

    {  

        CCKeypadDispatcher::sharedDispatcher()->removeDelegate(this);  

    }  

  

    CCNode::onExit();  

}  

</span>  

在最后调用了CCNode::onExit(),这个方法暂停了所有的schedule和action,这正是我们想要的结果!

[cpp] view
plaincopy

<span style="font-size:14px;">void CCLayer::onExit()  

{  

    if( m_bIsTouchEnabled )  

    {  

        CCTouchDispatcher::sharedDispatcher()->removeDelegate(this);  

        unregisterScriptTouchHandler();  

    }  

  

    // remove this layer from the delegates who concern Accelerometer Sensor  

    if (m_bIsAccelerometerEnabled)  

    {  

        CCAccelerometer::sharedAccelerometer()->setDelegate(NULL);  

    }  

  

    // remove this layer from the delegates who concern the kaypad msg  

    if (m_bIsKeypadEnabled)  

    {  

        CCKeypadDispatcher::sharedDispatcher()->removeDelegate(this);  

    }  

  

    CCNode::onExit();  

}</span>  


2.我的实现


(1)暂停

自定义一个暂停层PauseLayer,在其init()方法中得到当前运行场景,遍历这个场景的子节点(一般都是层吧),调用子节点的onExit()方法即可!

[cpp] view
plaincopy

<span style="font-size:14px;">bool PauseLayer::init()  

{  

    bool ret = false;  

      

    do {  

        CC_BREAK_IF(!CCLayerColor::initWithColor(ccc4f(255, 0, 0, 50)));  

          

        CCArray *array = CCDirector::sharedDirector()->getRunningScene()->getChildren();  

        CCObject *object = NULL;  

        CCARRAY_FOREACH(array, object)  

        {  

            CCLayer *layer = (CCLayer*) object;  

            layer->onExit();  

        }  

          

        ret = true;  

    } while (0);  

      

    return ret;  

}</span>  


(2)恢复

我这里只是简单的在触屏开始的事件中恢复的,与onExit()调用相反,调用onEnter()就可以实现了!

[cpp] view
plaincopy

<span style="font-size:14px;">bool PauseLayer::ccTouchBegan(cocos2d::CCTouch *pTouch, cocos2d::CCEvent *pEvent)  

{  

    CCArray *array = CCDirector::sharedDirector()->getRunningScene()->getChildren();  

    CCObject *object = NULL;  

    CCARRAY_FOREACH(array, object)  

    {  

        CCLayer* layer = (CCLayer*) object;  

        layer->onEnter();  

    }  

      

    this->removeFromParentAndCleanup(false);  

      

    return true;  

}</span>  

效果如图





(左图为暂停状态,右图为运行状态)

项目地址
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐