Cocos2d-x 用cocos2d-x实现MoonWarriors(暂停和恢复的实现)(转)

[+]

  1. 实现原理
  2. 我的实现
    1. 1暂停
    2. 2恢复
 


1.实现原理

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

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

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

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

 

  1. <span style="font-size:14px;">void CCLayer::onExit()  
  2. {  
  3.     if( m_bIsTouchEnabled )  
  4.     {  
  5.         CCTouchDispatcher::sharedDispatcher()->removeDelegate(this);  
  6.         unregisterScriptTouchHandler();  
  7.     }  
  8.   
  9.     // remove this layer from the delegates who concern Accelerometer Sensor   
  10.     if (m_bIsAccelerometerEnabled)  
  11.     {  
  12.         CCAccelerometer::sharedAccelerometer()->setDelegate(NULL);  
  13.     }  
  14.   
  15.     // remove this layer from the delegates who concern the kaypad msg   
  16.     if (m_bIsKeypadEnabled)  
  17.     {  
  18.         CCKeypadDispatcher::sharedDispatcher()->removeDelegate(this);  
  19.     }  
  20.   
  21.     CCNode::onExit();  
  22. }  
  23. </span>  
<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()方法即可!

  1. <span style="font-size:14px;">bool PauseLayer::init()  
  2. {  
  3.     bool ret = false;  
  4.       
  5.     do {  
  6.         CC_BREAK_IF(!CCLayerColor::initWithColor(ccc4f(255, 0, 0, 50)));  
  7.           
  8.         CCArray *array = CCDirector::sharedDirector()->getRunningScene()->getChildren();  
  9.         CCObject *object = NULL;  
  10.         CCARRAY_FOREACH(array, object)  
  11.         {  
  12.             CCLayer *layer = (CCLayer*) object;  
  13.             layer->onExit();  
  14.         }  
  15.           
  16.         ret = true;  
  17.     } while (0);  
  18.       
  19.     return ret;  
  20. }</span>  
<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()就可以实现了!

  1. <span style="font-size:14px;">bool PauseLayer::ccTouchBegan(cocos2d::CCTouch *pTouch, cocos2d::CCEvent *pEvent)  
  2. {  
  3.     CCArray *array = CCDirector::sharedDirector()->getRunningScene()->getChildren();  
  4.     CCObject *object = NULL;  
  5.     CCARRAY_FOREACH(array, object)  
  6.     {  
  7.         CCLayer* layer = (CCLayer*) object;  
  8.         layer->onEnter();  
  9.     }  
  10.       
  11.     this->removeFromParentAndCleanup(false);  
  12.       
  13.     return true;  
  14. }</span>  
原文地址:https://www.cnblogs.com/wodehao0808/p/3975071.html