Cocos2d-x 3.1.1 Lua演示样例 ActionManagerTest(动作管理)
本篇博客介绍Cocos2d-x的动作管理样例,这个样例展示了Cocos2d-x的几个动作:
MoveTo——移动动作,移动到某一个点
MoveBy——移动动作,与MoveTo是相似的,仅仅是MoveBy能够移动到某一个点然后按原路返回,提供reverse方法。RotateTo——旋转动作,把某一精灵旋转到某一角度RotateBy——旋转动作,把某一精灵旋转某个角度,它有一个方法reverse,它让对象按原路径旋转回ScaleTo——缩放动作,把某一精灵(Sprite)放大或缩小到某一比例Scaleby——缩放动作,把某一精灵(Sprite)放大或缩小多少比例,它有一个方法reverse,它让对象按原路径旋转回这个样例涉及到的知识点有:
- 创建动作序列,比如: cc.Sequence:create(cc.DelayTime:create(1.4),cc.CallFunc:create(removeThis)
- 执行动作序列,比如:ret:runAction( cc.Sequence:create(cc.DelayTime:create(1.4),cc.CallFunc:create(removeThis)))
我们先来看一下这个样例的效果,特别制作动态图给大家展示:
详细代码实现,详细API的用法,希望各位能认真看,假设对当中所传參数不清楚和不理解的,能够请教百度老师或者到官网參考详细API,这是学习方法。
》》》ActionManagerTest.lua
local kTagNode = 0 -- 结点标识 local kTagGrossini = 1 -- local kTagSequence = 2 -- -- 获取和这个 director 关联的调度器 local scheduler = cc.Director:getInstance():getScheduler() -------------------------------------------------------------------- -- -- Test1 -- -------------------------------------------------------------------- local function CrashTest() -- 创建測试层 local ret = createTestLayer("Test 1. Should not crash") -- 精灵,s_pPathGrossini为图片路径 local child = cc.Sprite:create(s_pPathGrossini) -- 显示到x=200,y=200的位置 child:setPosition( 200,200 ) ret:addChild(child, 1) --Sum of all action's duration is 1.5 second. -- 旋转一个节点,1.5秒,旋转90度 child:runAction(cc.RotateBy:create(1.5, 90)) -- 执行动作序列,1.4秒延迟,淡出 child:runAction(cc.Sequence:create(cc.DelayTime:create(1.4),cc.FadeOut:create(1.1))) local function removeThis() -- 溢出孩子 ret:getParent():removeChild(ret, true) Helper.nextAction() end --After 1.5 second, self will be removed. -- 1.5秒之后,自身会被移除 ret:runAction( cc.Sequence:create(cc.DelayTime:create(1.4),cc.CallFunc:create(removeThis))) return ret end -------------------------------------------------------------------- -- -- LogicTest -- 逻辑測试 -------------------------------------------------------------------- local function LogicTest() local ret = createTestLayer("Logic test") -- 精灵,s_pPathGrossini为图片路径 local grossini = cc.Sprite:create(s_pPathGrossini) -- 加入一个子节点到容器中,有Z轴顺序和一个标记。 ret:addChild(grossini, 0, 2) grossini:setPosition(200,200) local function bugMe(node) -- 停止全部动作 node:stopAllActions() --After this stop next action not working, if remove this stop everything is working node:runAction(cc.ScaleTo:create(2, 2)) end -- 执行动作序列 grossini:runAction( cc.Sequence:create(cc.MoveBy:create(1, cc.p(150,0)) ,cc.CallFunc:create(bugMe))) return ret end -------------------------------------------------------------------- -- -- PauseTest -- 暂停測试 -------------------------------------------------------------------- local function PauseTest() local ret = createTestLayer("Pause Test") local schedulerEntry = nil local function unpause(dt) scheduler:unscheduleScriptEntry(schedulerEntry) schedulerEntry = nil local node = ret:getChildByTag( kTagGrossini ) local pDirector = cc.Director:getInstance() pDirector:getActionManager():resumeTarget(node) end local function onNodeEvent(event) -- 进入时 if event == "enter" then local s = cc.Director:getInstance():getWinSize() local l = cc.Label:createWithTTF("After 3 seconds grossini should move", "fonts/Thonburi.ttf", 16) ret:addChild(l) l:setAnchorPoint(cc.p(0.5, 0.5)) l:setPosition( cc.p(s.width / 2, 245) ) local grossini = cc.Sprite:create(s_pPathGrossini) ret:addChild(grossini, 0, kTagGrossini) grossini:setPosition(cc.p(200,200)) -- 创建移动动作,持续时间1秒,移动到(150,0)的位置 local action = cc.MoveBy:create(1, cc.p(150,0)) local pDirector = cc.Director:getInstance() -- 通过获取director关联的ActionManager并为目标加入动作 -- 为一个目标加入动作。 假设目标已经存在,动作将被加在已经存在的目标上。 -- 假设目标不存在,将会创建这个目标的新对象,这个动作将被加入在这个新创建出来的对象上 当目标动作被暂停,动作队列的顺序也不会乱。 pDirector:getActionManager():addAction(action, grossini, true) schedulerEntry = scheduler:scheduleScriptFunc(unpause, 3.0, false) -- 退出 elseif event == "exit" then if schedulerEntry ~= nil then scheduler:unscheduleScriptEntry(schedulerEntry) end end end -- 注冊响应事件 ret:registerScriptHandler(onNodeEvent) return ret end -------------------------------------------------------------------- -- -- RemoveTest -- -------------------------------------------------------------------- local function RemoveTest() local ret = createTestLayer("Remove Test") local l = cc.Label:createWithTTF("Should not crash", "fonts/Thonburi.ttf", 16) -- 获得屏幕大小 local s = cc.Director:getInstance():getWinSize() ret:addChild(l) l:setAnchorPoint(cc.p(0.5, 0.5)) l:setPosition( cc.p(s.width / 2, 245)) -- 创建移动动作,持续2秒,到(200,0)的位置 local pMove = cc.MoveBy:create(2, cc.p(200, 0)) -- 停止动作 local function stopAction() -- 依据Tag来获取子节点 local pSprite = ret:getChildByTag(kTagGrossini) pSprite:stopActionByTag(kTagSequence) end -- 创建一个回调函数 local callfunc = cc.CallFunc:create(stopAction) local pSequence = cc.Sequence:create(pMove,callfunc) pSequence:setTag(kTagSequence) local pChild = cc.Sprite:create(s_pPathGrossini) pChild:setPosition( 200, 200 ) ret:addChild(pChild, 1, kTagGrossini) pChild:runAction(pSequence) return ret end -------------------------------------------------------------------- -- -- ResumeTest -- 恢复測试 -------------------------------------------------------------------- local function ResumeTest() local ret = createTestLayer("Resume Test") local schedulerEntry = nil local function resumeGrossini(time) scheduler:unscheduleScriptEntry(schedulerEntry) schedulerEntry = nil local pGrossini = ret:getChildByTag(kTagGrossini) local pDirector = cc.Director:getInstance() pDirector:getActionManager():resumeTarget(pGrossini) end local function onNodeEvent(event) if event == "enter" then local l = cc.Label:createWithTTF("Grossini only rotate/scale in 3 seconds", "fonts/Thonburi.ttf", 16) ret:addChild(l) local s = cc.Director:getInstance():getWinSize() l:setAnchorPoint(cc.p(0.5, 0.5)) l:setPosition( s.width / 2, 245) local pGrossini = cc.Sprite:create(s_pPathGrossini) ret:addChild(pGrossini, 0, kTagGrossini) pGrossini:setPosition(200,200) -- 执行缩放的动作 pGrossini:runAction(cc.ScaleBy:create(2, 2)) local pDirector = cc.Director:getInstance() -- 暂停目标 pDirector:getActionManager():pauseTarget(pGrossini) -- 执行旋转动作,旋转360度,持续2秒 pGrossini:runAction(cc.RotateBy:create(2, 360)) schedulerEntry = scheduler:scheduleScriptFunc(resumeGrossini, 3.0, false) elseif event == "exit" then if schedulerEntry ~= nil then scheduler:unscheduleScriptEntry(schedulerEntry) end end end ret:registerScriptHandler(onNodeEvent) return ret end function ActionManagerTestMain() cclog("ActionManagerTestMain") Helper.index = 1 -- 初始索引为1 -- 设置深度測试 cc.Director:getInstance():setDepthTest(true) -- 创建场景 local scene = cc.Scene:create() -- 初始化方法表 Helper.createFunctionTable = { CrashTest, LogicTest, PauseTest, RemoveTest, ResumeTest } -- 加入层 scene:addChild(CrashTest()) scene:addChild(CreateBackMenuItem()) return scene end
在样例中用到一些定义好的资源路径,还有相关帮助类,童鞋们能够到能够到对应文件夹下进行查找:
help.lua(帮助类,封装定义了相关方法,创建測试层、切换场景等)
require "Cocos2d" CC_CONTENT_SCALE_FACTOR = function() -- 获取surface的大小,单位为像素 return cc.Director:getInstance():getContentScaleFactor() end --把以像素为单位的矩形转换为以点为单位的矩形 CC_POINT_PIXELS_TO_POINTS = function(pixels) return cc.p(pixels.x/CC_CONTENT_SCALE_FACTOR(), pixels.y/CC_CONTENT_SCALE_FACTOR()) end -- 把以点为单位的矩形转换为以像素为单位的矩形 CC_POINT_POINTS_TO_PIXELS = function(points) return cc.p(points.x*CC_CONTENT_SCALE_FACTOR(), points.y*CC_CONTENT_SCALE_FACTOR()) end -- cclog 打印日志 cclog = function(...) print(string.format(...)) end -- change table to enum type 把表转换为枚举类型 function CreateEnumTable(tbl, index) local enumTable = {} local enumIndex = index or -1 for i, v in ipairs(tbl) do enumTable[v] = enumIndex + i end return enumTable end -- back menu callback 返回菜单回调 local function MainMenuCallback() local scene = cc.Scene:create() scene:addChild(CreateTestMenu()) -- 切换场景 cc.Director:getInstance():replaceScene(scene) end -- add the menu item for back to main menu -- 为返回主菜单加入菜单项 function CreateBackMenuItem() -- 创建一个标签 local label = cc.Label:createWithTTF("MainMenu", s_arialPath, 20) -- 设置器锚点 label:setAnchorPoint(cc.p(0.5, 0.5)) -- 设置菜单项标签 local MenuItem = cc.MenuItemLabel:create(label) MenuItem:registerScriptTapHandler(MainMenuCallback) -- 获得屏幕大小 local s = cc.Director:getInstance():getWinSize() -- 创建菜单 local Menu = cc.Menu:create() -- 加入菜单项 Menu:addChild(MenuItem) -- 设置菜单位置 Menu:setPosition(0, 0) -- 设置菜单项位置,大致在右下角的位置 MenuItem:setPosition(s.width - 50, 25) return Menu end -- 帮助类 Helper = { index = 1, -- 索引 createFunctioinTable = nil, -- 存储方法的表 currentLayer = nil, -- 当前层 titleLabel = nil, -- 标题 subtitleLabel = nil -- 子标题 } -- 下个动作 function Helper.nextAction() Helper.index = Helper.index + 1 -- 索引加1 if Helper.index > table.getn(Helper.createFunctionTable) then Helper.index = 1 end return Helper.newScene() end -- 回退动作 function Helper.backAction() Helper.index = Helper.index - 1 if Helper.index == 0 then Helper.index = table.getn(Helper.createFunctionTable) end return Helper.newScene() end -- 又一次開始动作 function Helper.restartAction() return Helper.newScene() end -- 切换新的场景 function Helper.newScene() local scene -- 假设使用物理效果 if Helper.usePhysics then -- 创建一个带物理效果的场景 scene = cc.Scene:createWithPhysics() else scene = cc.Scene:create() end Helper.currentLayer = Helper.createFunctionTable[Helper.index]() -- 加入当前层 scene:addChild(Helper.currentLayer) -- 加入返回菜单 scene:addChild(CreateBackMenuItem()) -- 切换场景 cc.Director:getInstance():replaceScene(scene) end -- 初始化层 function Helper.initWithLayer(layer) Helper.currentLayer = layer -- 获取屏幕大小 local size = cc.Director:getInstance():getWinSize() Helper.titleLabel = cc.Label:createWithTTF("", s_arialPath, 28) Helper.titleLabel:setAnchorPoint(cc.p(0.5, 0.5)) layer:addChild(Helper.titleLabel, 1) Helper.titleLabel:setPosition(size.width / 2, size.height - 50) Helper.subtitleLabel = cc.Label:createWithTTF("", s_thonburiPath, 16) Helper.subtitleLabel:setAnchorPoint(cc.p(0.5, 0.5)) layer:addChild(Helper.subtitleLabel, 1) Helper.subtitleLabel:setPosition(size.width / 2, size.height - 80) -- menu菜单 local item1 = cc.MenuItemImage:create(s_pPathB1, s_pPathB2) local item2 = cc.MenuItemImage:create(s_pPathR1, s_pPathR2) local item3 = cc.MenuItemImage:create(s_pPathF1, s_pPathF2) item1:registerScriptTapHandler(Helper.backAction) item2:registerScriptTapHandler(Helper.restartAction) item3:registerScriptTapHandler(Helper.nextAction) local menu = cc.Menu:create() menu:addChild(item1) menu:addChild(item2) menu:addChild(item3) menu:setPosition(cc.p(0, 0)) -- 摆放三个菜单项的位置 item1:setPosition(cc.p(size.width / 2 - item2:getContentSize().width * 2, item2:getContentSize().height / 2)) item2:setPosition(cc.p(size.width / 2, item2:getContentSize().height / 2)) item3:setPosition(cc.p(size.width / 2 + item2:getContentSize().width * 2, item2:getContentSize().height / 2)) layer:addChild(menu, 1) local background = cc.Layer:create() layer:addChild(background, -10) end -- 创建測试层 function createTestLayer(title, subtitle) -- 创建一个层 local layer = cc.Layer:create() Helper.initWithLayer(layer) local titleStr = title == nil and "No title" or title local subTitleStr = subtitle == nil and "" or subtitle Helper.titleLabel:setString(titleStr) Helper.subtitleLabel:setString(subTitleStr) return layer end
testResource.lua
定义了全部的资源路径,方便管理和获取
s_pPathGrossini = "Images/grossini.png" s_pPathSister1 = "Images/grossinis_sister1.png" s_pPathSister2 = "Images/grossinis_sister2.png" s_pPathB1 = "Images/b1.png" s_pPathB2 = "Images/b2.png" s_pPathR1 = "Images/r1.png" s_pPathR2 = "Images/r2.png" s_pPathF1 = "Images/f1.png" s_pPathF2 = "Images/f2.png" s_pPathBlock = "Images/blocks.png" s_back = "Images/background.png" s_back1 = "Images/background1.png" s_back2 = "Images/background2.png" s_back3 = "Images/background3.png" s_stars1 = "Images/stars.png" s_stars2 = "Images/stars2.png" s_fire = "Images/fire.png" s_snow = "Images/snow.png" s_streak = "Images/streak.png" s_PlayNormal = "Images/btn-play-normal.png" s_PlaySelect = "Images/btn-play-selected.png" s_AboutNormal = "Images/btn-about-normal.png" s_AboutSelect = "Images/btn-about-selected.png" s_HighNormal = "Images/btn-highscores-normal.png" s_HighSelect = "Images/btn-highscores-selected.png" s_Ball = "Images/ball.png" s_Paddle = "Images/paddle.png" s_pPathClose = "Images/close.png" s_MenuItem = "Images/menuitemsprite.png" s_SendScore = "Images/SendScoreButton.png" s_PressSendScore = "Images/SendScoreButtonPressed.png" s_Power = "Images/powered.png" s_AtlasTest = "Images/atlastest.png" -- tilemaps resource s_TilesPng = "TileMaps/tiles.png" s_LevelMapTga = "TileMaps/levelmap.tga" -- spine test resource s_pPathSpineBoyJson = "spine/spineboy.json" s_pPathSpineBoyAtlas = "spine/spineboy.atlas" -- fonts resource s_markerFeltFontPath = "fonts/Marker Felt.ttf" s_arialPath = "fonts/arial.ttf" s_thonburiPath = "fonts/Thonburi.ttf" s_tahomaPath = "fonts/tahoma.ttf"