前几天在练习制作一个消除游戏,其中多次遇到这样一个问题:怎么在多个动作结束后,再回调一个函数?比如说,在消除几个宝石后,才需要刷新布局。那么只要有一个宝石的动作没有结束,就不能回调刷新的函数。
在cocos2d-x当中,提供了CallFunc这样一个动作,可以在一个动作结束后回调一个函数。可是这仅仅适用于一个节点的动作,多个节点就不知道如何是好了。好像用CallFunc这条路是走不通了。想来想去,我找到一个比较笨的办法,但并不影响效率,却完美解决了问题。
那就是用schedule做一个捕捉函数——这是我给它起的名字。它有这样的特性:
1.捕捉部分:每帧(或者很短时间间隔)调用,对节点的状态进行捕捉,若不满足条件那么返回;
2.处理部分:当捕捉到后,立即unschedule停止捕捉,然后执行后续逻辑代码。
这样在一个节点动作结束完毕后,给它设置一个状态位,捕捉函数就能在下一个时间步内捕捉到该节点的状态。一旦所有节点状态都满足了要求,那么立即停止捕捉,随后回调一个函数。
拿消除的捕捉函数作例子,代码如下:
void JewelsGrid::onJewelsCrushing(float dt) { //捕捉宝石消除状态,如果有宝石还在消除,那么继续捕捉 for (auto jewel : m_crushJewelBox) { if (jewel->isCrushing()) { //log("crushing"); return; } } //如果全部宝石已经消除完毕,停止捕捉函数 unschedule(schedule_selector(JewelsGrid::onJewelsCrushing)); m_crushJewelBox.clear(); //清空消除宝石盒子 log("crush over!"); log("begin to refresh!"); //刷新宝石阵列,并开启刷新状态捕捉函数 refreshJewelsGrid(); schedule(schedule_selector(JewelsGrid::onJewelsRefreshing)); }
每一帧遍历每一个正在消除的宝石,一旦全部消除完成,那么立即停止捕捉。并依次执行之后的逻辑代码。消除完后就是刷新布局,它也是要进行多个动作然后回调一个函数的,因此使用了同样的机制。可以看出,使用捕捉函数的方法就是:将其和动作函数写在一起,保证在同一帧开始动作,同一帧开始捕捉。