Cocos2d-x学习(十四):用cocos2d-x实现MoonWarriors(暂停和恢复的实现)
2013-01-11 01:04
441 查看
特别声明:本文所有图片资源来源于MoonWarriors cocos2d-html 开源项目
今天搞了半天子弹发射这块,还是没弄完,我打算做一个子弹缓冲池,将所有子弹的图片资源打到同一个图片资源中,用一个CCSpriteBatchNode来绘制,这样在很多子弹的时候,就起到优化的效果了,CCSpriteBatchNode的原理是开启一次opengl绘制,绘制所有子精灵!
原理不是通过调用 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>
自定义一个暂停层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>
我这里只是简单的在触屏开始的事件中恢复的,与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>
效果如图
(左图为暂停状态,右图为运行状态)
项目地址
今天搞了半天子弹发射这块,还是没弄完,我打算做一个子弹缓冲池,将所有子弹的图片资源打到同一个图片资源中,用一个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>
效果如图
(左图为暂停状态,右图为运行状态)
项目地址
相关文章推荐
- [置顶] Cocos2d-x学习(十四):用cocos2d-x实现MoonWarriors(暂停和恢复的实现)
- Cocos2d-x学习(十四):用cocos2d-x实现MoonWarriors(暂停和恢复的实现)
- Cocos2d-x 用cocos2d-x实现MoonWarriors(暂停和恢复的实现)
- Cocos2d-x 用cocos2d-x实现MoonWarriors(暂停和恢复的实现)(转)
- cocos2d-x-2.1.3 中实现游戏的简单暂停与恢复
- Cocos2d-x学习(十三):用cocos2d-x实现MoonWarriors(使用触屏改变飞船位置)
- Cocos2d-x学习(十一):用cocos2d-x实现MoonWarriors(游戏场景切换和主菜单实现)
- Cocos2d-x学习(十一):用cocos2d-x实现MoonWarriors(游戏场景切换和主菜单实现)
- Cocos2d-x学习(十二):用cocos2d-x实现MoonWarriors(无限背景滚动的简单实现)
- Cocos2d-x学习(十一):用cocos2d-x实现MoonWarriors(游戏场景切换和主菜单实现)
- Cocos2d-x学习(十三):用cocos2d-x实现MoonWarriors(使用触屏改变飞船位置)
- Cocos2d-x学习(十二):用cocos2d-x实现MoonWarriors(无限背景滚动的简单实现)
- Cocos2d-x学习(十三):用cocos2d-x实现MoonWarriors(使用触屏改变飞船位置)
- Cocos2d-x学习(十二):用cocos2d-x实现MoonWarriors(无限背景滚动的简单实现)
- Android学习总结(十四) ———— ListView Item多布局的实现
- MySQL学习笔记之十四 备份和恢复数据表的方法
- C语言学习历程(十四) 结构体链表实现通讯录
- cocos2d-x类似Temple Run 游戏恢复的321倒计时实现
- cocos2d-x学习笔记(二)Eclipse+cdt实现cocos2dx跨平台解决方案(转)
- OpenGL ES 学习教程(十四) 帧缓冲区对象(FBO) 实现渲染到纹理(Render To Texture/RTT)