《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)

 

posted on 2014-08-07 04:11  _Ernest  阅读(1244)  评论(0)    收藏  举报

导航