《Cocos2d-x-3.2 Lua-tests》文件详解 之 动作管理ActionManager
直接上代码:
1 --给精灵、动作贴标签,标签要事先声明。标签的好处之一在下面的注释中会有讲到 2 local kTagNode = 0 3 local kTagGrossini = 1 4 local kTagSequence = 2 5 --获取脚本调度器(注意,仅仅是获取),此调度器用于在每一帧调自动执行一次你设定的方法,在一些效果上跟action + repeatforever相似 6 local scheduler = cc.Director:getInstance():getScheduler() 7 -------------------------------------------------------------------- 8 -- 9 -- Test1 10 -- 11 -------------------------------------------------------------------- 12 --Test1层 13 local function CrashTest() 14 local ret = createTestLayer("Test 1. Should not crash") 15 16 --调用s_pPathGrossini资源创建精灵--项目根目录下的testResource.lua统一管理所有资源,此处只需要用资源对应的名称即可 17 local child = cc.Sprite:create(s_pPathGrossini) 18 child:setPosition( 200,200 ) 19 ret:addChild(child, 1) 20 21 --Sum of all action's duration is 1.5 second. 22 --[[ 23 下面展示了精灵运行Action动画的方法: 24 cc.RotateBy:create(1.5,90)创建旋转动作,完成时间1.5.秒,旋转90度 25 调用runAction()方法,以action为参数,就可以让精灵以action为规则动起来了 26 27 Sequence是动作链,即一连串的有序的动作,会被依次执行,在Sequence的最后,可以用cc.CallFunc:create()调用一个方法, 28 该方法会在Sequence中所有的动作执行完毕后,被调用 29 ]]-- 30 child:runAction(cc.RotateBy:create(1.5, 90)) 31 child:runAction(cc.Sequence:create(cc.DelayTime:create(1.4),cc.FadeOut:create(1.1))) 32 33 local function removeThis() 34 --getParent()用来获取父容器,removeChild()用来从父容器中移除child 35 --刚才试了一下把removeChild()第二个参数改成false,一样能删除,至于为什么,以后慢慢研究 36 ret:getParent():removeChild(ret, true) 37 Helper.nextAction() 38 end 39 40 --After 1.5 second, self will be removed. 41 ret:runAction( cc.Sequence:create(cc.DelayTime:create(1.4),cc.CallFunc:create(removeThis))) 42 return ret 43 end 44 45 46 -------------------------------------------------------------------- 47 -- 48 -- LogicTest 49 -- 50 -------------------------------------------------------------------- 51 --简单的Sequence的应用 52 local function LogicTest() 53 local ret = createTestLayer("Logic test") 54 local grossini = cc.Sprite:create(s_pPathGrossini) 55 ret:addChild(grossini, 0, 2) 56 grossini:setPosition(200,200) 57 local function bugMe(node) 58 --新知识:停掉动画stopAllActions(),只是停掉本句代码之前的所有动作,接下来的动作还是湖继续的 59 node:stopAllActions() --After this stop next action not working, if remove this stop everything is working 60 node:runAction(cc.ScaleTo:create(2, 2)) 61 end 62 grossini:runAction( cc.Sequence:create(cc.MoveBy:create(1, cc.p(150,0)) ,cc.CallFunc:create(bugMe))) 63 return ret 64 end 65 66 -------------------------------------------------------------------- 67 -- 68 -- PauseTest 69 -- 70 -------------------------------------------------------------------- 71 --(动作)暂停测试 72 local function PauseTest() 73 local ret = createTestLayer("Pause Test") 74 local schedulerEntry = nil 75 76 77 local function unpause(dt) 78 --释放调度器,停掉动作。 在调度器的回调中释放调度器 79 scheduler:unscheduleScriptEntry(schedulerEntry) 80 schedulerEntry = nil 81 82 local node = ret:getChildByTag( kTagGrossini ) 83 local pDirector = cc.Director:getInstance() 84 85 --getActionManager()封装了多种管理Action的方法,上面的StopAllActions()是其中之一 86 --resumeTarget,恢复,对kTagGrossini进行停止、暂停等相关的操作之后,须调用resumeTarget(),之后才能继续被操作 87 pDirector:getActionManager():resumeTarget(node) 88 end 89 --事件函数 90 local function onNodeEvent(event) 91 if event == "enter" then 92 --layer的载入事件,做以下事情: 93 local s = cc.Director:getInstance():getWinSize() 94 local l = cc.Label:createWithTTF("After 3 seconds grossini should move", "fonts/Thonburi.ttf", 16) 95 ret:addChild(l) 96 l:setAnchorPoint(cc.p(0.5, 0.5)) 97 l:setPosition( cc.p(s.width / 2, 245) ) 98 99 local grossini = cc.Sprite:create(s_pPathGrossini) 100 ret:addChild(grossini, 0, kTagGrossini) 101 grossini:setPosition(cc.p(200,200)) 102 103 local action = cc.MoveBy:create(1, cc.p(150,0)) 104 105 --是不是对下面两句比较陌生,其实它们可以合并: 106 --cc.Director:getInstance():getActionManager():addAction(action,grossini,true),懂了吧,一切动作由导演管理! 107 local pDirector = cc.Director:getInstance() 108 pDirector:getActionManager():addAction(action, grossini, true) 109 110 --启动脚本调动器,设置相应函数unpase,每3.0秒执行一次,。false还没弄清楚 - -! 111 schedulerEntry = scheduler:scheduleScriptFunc(unpause, 3.0, false) 112 113 --layer退出内存时,也要释放掉调度器 114 elseif event == "exit" then 115 if schedulerEntry ~= nil then 116 scheduler:unscheduleScriptEntry(schedulerEntry) 117 end 118 end 119 end 120 --看代码也是要找入口的,这个是主要的入口 121 --首先,给层注册节点事件 122 ret:registerScriptHandler(onNodeEvent) 123 return ret 124 end 125 126 -------------------------------------------------------------------- 127 -- 128 -- RemoveTest 129 -- 130 -------------------------------------------------------------------- 131 132 --这个层结构比较简单,从上到下。 133 --本例要点是:给Sprite和Sequence贴标签,然后与针对性地操作。 134 --贴标签,你能够在一个local方法中访问另一个local方法中的贴有标签的local变量 135 local function RemoveTest() 136 local ret = createTestLayer("Remove Test") 137 local l = cc.Label:createWithTTF("Should not crash", "fonts/Thonburi.ttf", 16) 138 local s = cc.Director:getInstance():getWinSize() 139 ret:addChild(l) 140 l:setAnchorPoint(cc.p(0.5, 0.5)) 141 l:setPosition( cc.p(s.width / 2, 245)) 142 --上面是操作层面的布局 143 144 --创建一个动作 145 local pMove = cc.MoveBy:create(2, cc.p(200, 0)) 146 --一个方法 147 local function stopAction() 148 local pSprite = ret:getChildByTag(kTagGrossini) 149 pSprite:stopActionByTag(kTagSequence) 150 end 151 --callfunc绑定上面的那个方法 152 local callfunc = cc.CallFunc:create(stopAction) 153 154 --将动作和方法集结到Sequence中,Sequence中最后可以放一个回调方法,上面有提到,这次不解释 155 local pSequence = cc.Sequence:create(pMove,callfunc) 156 --给Sequence贴个标签 157 pSequence:setTag(kTagSequence) 158 159 --创建精灵pChild 160 local pChild = cc.Sprite:create(s_pPathGrossini) 161 pChild:setPosition( 200, 200 ) 162 --把精灵放到层中,并设置层级为1,贴个kTagGrossini的标签 163 ret:addChild(pChild, 1, kTagGrossini) 164 165 --pChild运行pSequence 166 pChild:runAction(pSequence) 167 return ret 168 end 169 170 171 -------------------------------------------------------------------- 172 -- 173 -- ResumeTest 174 -- 175 -------------------------------------------------------------------- 176 --恢复动作 测试 177 local function ResumeTest() 178 local ret = createTestLayer("Resume Test") 179 180 local schedulerEntry = nil 181 local function resumeGrossini(time) 182 --首先,释放脚本调度器 183 scheduler:unscheduleScriptEntry(schedulerEntry) 184 --将schedulerEntry回归原始值 185 schedulerEntry = nil 186 187 --//关键点:用标签取出Sprite,然后,导演喊:“Action”,Sprite开始按照之前设定好的动作表演(运动)。。。 188 local pGrossini = ret:getChildByTag(kTagGrossini) 189 local pDirector = cc.Director:getInstance() 190 pDirector:getActionManager():resumeTarget(pGrossini) 191 end 192 193 194 local function onNodeEvent(event) 195 if event == "enter" then 196 local l = cc.Label:createWithTTF("Grossini only rotate/scale in 3 seconds", "fonts/Thonburi.ttf", 16) 197 ret:addChild(l) 198 local s = cc.Director:getInstance():getWinSize() 199 l:setAnchorPoint(cc.p(0.5, 0.5)) 200 l:setPosition( s.width / 2, 245) 201 202 --建精灵 203 local pGrossini = cc.Sprite:create(s_pPathGrossini) 204 ret:addChild(pGrossini, 0, kTagGrossini) 205 pGrossini:setPosition(200,200) 206 --绑定动作 207 pGrossini:runAction(cc.ScaleBy:create(2, 2)) 208 209 --导演喊话了:"cut",然后,所有的演员停掉所有的动作 210 local pDirector = cc.Director:getInstance() 211 pDirector:getActionManager():pauseTarget(pGrossini) 212 --此时runAction()无效:相当于导演已经设置好动作,演员还没正式表演 213 pGrossini:runAction(cc.RotateBy:create(2, 360)) 214 215 --启动脚本调度,3秒钟后,跳到resumeGrossini方法 216 schedulerEntry = scheduler:scheduleScriptFunc(resumeGrossini, 3.0, false) 217 elseif event == "exit" then 218 if schedulerEntry ~= nil then 219 scheduler:unscheduleScriptEntry(schedulerEntry) --退出Layer的时候,释放脚本调度器 220 end 221 end 222 end 223 --读代码的入口!!!!注册载入事件。。。 224 ret:registerScriptHandler(onNodeEvent) 225 return ret 226 end 227 228 --每个test文件是一个Scene,每一个test是一个Layer 229 function ActionManagerTestMain() 230 cclog("ActionManagerTestMain") 231 Helper.index = 1 232 --开启深度测试,即允许与处于非顶层的层进行交互 233 cc.Director:getInstance():setDepthTest(true) 234 local scene = cc.Scene:create() 235 236 Helper.createFunctionTable = { 237 CrashTest, 238 LogicTest, 239 PauseTest, 240 RemoveTest, 241 ResumeTest 242 } 243 scene:addChild(CrashTest()) 244 scene:addChild(CreateBackMenuItem()) 245 return scene 246 end
动作的创建就跟精灵的创建一样,随时随地随便一个local就可以创建,但是动作的管理则交给Director,而Director是全局的,
这样使用:cc.Director:getInstance():getActionManager():addAction(action,grossini,true)
浙公网安备 33010602011771号