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

Cocos2d-x中的那些坑--Action stop后无法恢复的一种解决方法

2014-08-23 13:31 429 查看
Cocos2d-x中的Action系列的类是非常常用到的功能,使用这些Action,可以构建游戏中绝大部分的内容,但是使用了Action一段时间后,发现Action只能在被Node调用了stopAction停止掉之后不能恢复,Node没有提供resumeAction之类函数来恢复被停止的Action的,查看了下源码才知道stop其实就是把Action直接从,而在编写游戏的时候,有时候确实是是有想对被停止掉的Action进行恢复,这时候就有些麻烦了,那么怎么实现让Action既可以停止,又可以继续呢?

经过仔细查看源码,可以知道所有的Action都是又一个叫ActionManager的对象进行统一管理的,在游戏运行的时候,如果没有自己创建任何ActionManager的话,Director的单例对象自己在初始化的时候会创建一个ActionManager,而它就是用来管理游戏中的所有的Action对象的默认对象,Director的单例会注册一个每帧调用的函数,该函数内部其实就是调用了这个ActionManager的update函数,而这个update函数就会对所有其管理的Action进行更新,Director单例的创建的默认的ActionManager管理的Action对象其实就是游戏中所有的Action对象,查看源码可以发现,所有的Action对象其实都是交给这个ActionManager来管理的。

从这里可以想到的一个实现可以被停止后恢复的Action的方法就是自己创建一个ActionManager,由自己来决定什么时候调用这个自建的ActionManager的update函数,那么这样就可以实现对Action的控制了,这里要注意的是调用ActionManager的update函数式需要传入一个dt(距离上一帧所经过的时间) 来用于计算Action的更新。

这里贴出一段用lua写的通过自建ActionManager来控制Layer中的Node的Action的更新,大概思路就是为当前Layer创建一个ActionManager,然后对该Layerr中所创建的Node调用setActionManager来设置自建的ActionManager来负责管理Node的Action,经过这个设置后再调用runAction,这些Node的Action就会变为由自建的ActionManager来管理了,接下来在为Layer注册的update函数中来手动调用自建的ActionManager的update函数,在这里加入逻辑,根据需要来选择是否要调用自建的ActionManager的update函数,此时有了这个自建的ActionManager,我们就可以实现让Layer中的Action随着其所属的游戏对象的暂停而暂停,恢复而恢复之类的效果了。

例子代码如下,仅供参考(Lua):

GameLayer = class("GameLayer",function ()
	return cc.Layer:create()
end)
function  GameLayer:objCreate()
    local pObj = self.new()
    pObj:registerScriptHandler(function(tag)
        if "enter" == tag then
            pObj:onEnter()
        end
    end)
    --默认情况下Layer不是暂停的
    pObj.m_isPaused = false
    --创建由自己控制的ActionManager
    pObj.m_actionManager = cc.ActionManager:new()
    pObj.m_actionManager:retain()
    --创建不停旋转的精灵
    local sprite = cc.Sprite:create("sprite.png")
    sprite:setActionManager(pObj.m_actionManager)
    sprite:runAction(cc.RepeatForever:create(cc.RotateBy:create(0.1,20)))
    pObj:addChild(sprite)

    return pObj
end
function GameLayer:onEnter()
      --定义每帧调用的函数
      local function update(dt)
          --根绝游戏状态来控制ActionManager的更新
          if self.m_isPaused == false then
             self.m_actionManager:update(dt)
          end
       end
       --注册每帧调用的更新函数
       self:scheduleUpdateWithPriorityLua(update,0)
end
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: