当游戏进入了手游时代, 快成为了开发游戏的主题曲. 开发快, 上线快, Bug修复快, 挣钱也会特别快.
脚本成为了在游戏开发中的助力, 而且脚本可以即时更新的特性, 更是为了避免平台冗长的审核过程的法宝. Lua脚本以其开发速度快, 运行快, 成为了众多游戏开发的首选.
CocoStudio也是以快著称, 如果CocoStudio和Cocos2d-x Lua珠联璧合, 快上加快, 很有想象的空间.
今天我们来看下在Cocos2d-x Lua项目中如何调用CocoStudio导出的动画.
一 版本
我们采用的是Cocos2d-x 3.0RC0和CocoStudio 1.3, 不同的版本在功能上可能略有差异, 希望大家尽量能采用这个版本.
大家请自行下载并配置开发环境, 如果大家在安装活配置的过程中遇到问题, 不妨在CocoaChina的CocoStudio专区提出, 一起交流.
二 创建新的Cocos2d-x Lua项目并导入资源
大家在命令行或者终端中, 找到将要存放工程的路径并运行命令
cocos new -p com.young40.animation -l lua LuaAnimation
我们在LuaAnimation\frameworks\runtime-src\目录下可以看到有iOS, Mac, Android, Win32等工程.
大家可以根据自己的情况来打开对应的工程项目. 我是在Win下创建的, 所以选择Win32的工程并打开.
我们打开CocoStudio的动画编辑器, 并打开示例项目HeroAnimation.
我们切换到动画模式, 为attack的其中一帧添加一个kill帧事件. 对帧事件不太了解的同学, 可以看下这篇教程.
CocoStudio sample讲解 SampleCollision骨骼动画与简单碰撞 http://www.cocoachina.com/bbs/read.php?tid=189665
大家可以看下其中的帧事件部分, 这里不再赘述.
导出这个项目, 稍后将导出的文件复制到LuaAnimation的res目录下边. 可能iOS, Mac工程还需要将其添加到Xcode项目中, 这里不再赘述.我们还增加了两个武器的图片(weapon1tex.png, weapon2tex.png), 做换装的演示.
三 代码实现
我们在代码中对CocoStudio做好的动画的操作很简单, 大概可以分为以下几个操作.
1. 加载动画数据
2. 生成动画对象
3. 播放动画
包括按名称播放, 按顺序播放, 以及获取动画列表数量
4. 骨骼动画换装
添加新的皮肤, 切换新的皮肤
5. 帧事件和动画事件
添加帧事件监听, 以及监听回调
添加动画事件, 以及监听回调
我们在默认的Cocos2d-x Lua工程里面直接修改main.lua.
好, 让我们直接看代码吧. 附件中有工程打包下载, 需要大家将2d-x copy一份到LuaAnimation\frameworks\cocos2d-x.
脚本成为了在游戏开发中的助力, 而且脚本可以即时更新的特性, 更是为了避免平台冗长的审核过程的法宝. Lua脚本以其开发速度快, 运行快, 成为了众多游戏开发的首选.
CocoStudio也是以快著称, 如果CocoStudio和Cocos2d-x Lua珠联璧合, 快上加快, 很有想象的空间.
今天我们来看下在Cocos2d-x Lua项目中如何调用CocoStudio导出的动画.
一 版本
我们采用的是Cocos2d-x 3.0RC0和CocoStudio 1.3, 不同的版本在功能上可能略有差异, 希望大家尽量能采用这个版本.
大家请自行下载并配置开发环境, 如果大家在安装活配置的过程中遇到问题, 不妨在CocoaChina的CocoStudio专区提出, 一起交流.
二 创建新的Cocos2d-x Lua项目并导入资源
大家在命令行或者终端中, 找到将要存放工程的路径并运行命令
cocos new -p com.young40.animation -l lua LuaAnimation
我们在LuaAnimation\frameworks\runtime-src\目录下可以看到有iOS, Mac, Android, Win32等工程.
大家可以根据自己的情况来打开对应的工程项目. 我是在Win下创建的, 所以选择Win32的工程并打开.
我们打开CocoStudio的动画编辑器, 并打开示例项目HeroAnimation.
我们切换到动画模式, 为attack的其中一帧添加一个kill帧事件. 对帧事件不太了解的同学, 可以看下这篇教程.
CocoStudio sample讲解 SampleCollision骨骼动画与简单碰撞 http://www.cocoachina.com/bbs/read.php?tid=189665
大家可以看下其中的帧事件部分, 这里不再赘述.
导出这个项目, 稍后将导出的文件复制到LuaAnimation的res目录下边. 可能iOS, Mac工程还需要将其添加到Xcode项目中, 这里不再赘述.我们还增加了两个武器的图片(weapon1tex.png, weapon2tex.png), 做换装的演示.
三 代码实现
我们在代码中对CocoStudio做好的动画的操作很简单, 大概可以分为以下几个操作.
1. 加载动画数据
2. 生成动画对象
3. 播放动画
包括按名称播放, 按顺序播放, 以及获取动画列表数量
4. 骨骼动画换装
添加新的皮肤, 切换新的皮肤
5. 帧事件和动画事件
添加帧事件监听, 以及监听回调
添加动画事件, 以及监听回调
我们在默认的Cocos2d-x Lua工程里面直接修改main.lua.
好, 让我们直接看代码吧. 附件中有工程打包下载, 需要大家将2d-x copy一份到LuaAnimation\frameworks\cocos2d-x.
-- 运行场景
local sceneGame = cc. Scene:create()
--sceneGame:addChild(createLayerFarm()) --注释掉默认的农场的场景
--sceneGame:addChild(createLayerMenu())
local function createTestLayer ()
local layerTest = cc. Layer:create()
-- 加载动画-资源
-- 还有异步加载资源的方法addArmatureFileInfoAsync, 大家可以自行看下其用法, 今天暂不讨论
ccs .ArmatureDataManager: getInstance():addArmatureFileInfo( "res/Hero0.png", "res/Hero0.plist" , "res/Hero.ExportJson" )
-- 创建动画对象
local armature = ccs. Armature:create( "Hero")
-- 设置位置
armature :setPosition(origin. x + visibleSize.width / 3, origin .y + visibleSize. height / 5)
-- 播放动画, 播放指定动作
armature :getAnimation(): play("attack")
-- 添加到游戏中
layerTest :addChild(armature)
-- 帧事件回调
do
-- 添加用于显示的标签
local killEventCount = 0 -- 计算事件发生数量
local killEventLabel = cc. Label:create( "Kill Event Count: 0", s_markerFeltFontPath, 20)
killEventLabel :setPosition(cc. p(50, 10))
layerTest :addChild(killEventLabel)
-- 添加帧事件回调
armature :getAnimation(): setFrameEventCallFunc(function ( bone, evt, originFrameIndex, currentFrameIndex )
if evt == "kill" then -- 判断帧事件名称是否为kill
killEventCount = killEventCount + 1
-- 更新输出显示
killEventLabel :setString("Kill Event Count: " .. killEventCount)
end
end)
end
-- 动画事件回调
do
-- 添加一个动画事件显示标签
local moveEventLabel = cc. Label:create( "", s_markerFeltFontPath, 20)
moveEventLabel :setPosition(cc. p(50, 30))
layerTest :addChild(moveEventLabel)
-- 添加帧事件回调
armature :getAnimation(): setMovementEventCallFunc(function (arm, eventType, movmentID)
-- 判断帧事件类型
local actionType = "Start Event"
if eventType == ccs. MovementEventType.start then
actionType = "Start Event"
elseif eventType == ccs. MovementEventType.complete then
actionType = "Complete Event"
elseif eventType == ccs. MovementEventType.loopComplete then
actionType = "Loop Complete Event"
end
-- 更新输出显示
moveEventLabel :setString("Got Event " .. movmentID .. " " .. actionType)
end)
end
-- 我们要实现触摸后切换动画-
-- 接受触摸
local function onTouchBegan(touch, event)
return true
end
local currentIndex = 0
-- 获取动作列表数量
local animationListCount = armature: getAnimation():getMovementCount()
-- 触摸结束后切换动画
local function onTouchEnded(touch, event)
-- 通过播放动画
armature :getAnimation(): playWithIndex(currentIndex)
currentIndex = currentIndex + 1
if currentIndex >= animationListCount then
currentIndex = 0
end
end
-- 监听触摸事件
local listener = cc. EventListenerTouchOneByOne:create()
listener :registerScriptHandler(onTouchBegan, cc.Handler .EVENT_TOUCH_BEGAN)
listener :registerScriptHandler(onTouchEnded, cc.Handler .EVENT_TOUCH_ENDED)
local eventDispatcher = layerTest: getEventDispatcher()
eventDispatcher :addEventListenerWithSceneGraphPriority(listener, layerTest)
-- 换装的实现
-- 生成新的皮肤(这里指装备)
local skin1 = ccs. Skin:create( "res/weapon1tex.png")
local skin2 = ccs. Skin:create( "res/weapon2tex.png")
-- 获取到装备的骨骼, 并添加新的显示
local bone = armature: getBone("Layer17")
bone :addDisplay(skin1, 1)
bone :addDisplay(skin2, 2)
-- 创建菜单
local function createLayerMenu()
local menu = cc. Menu:create()
local label = cc. Label:create( "ChangeDisplay", s_markerFeltFontPath, 20)
local menuChageDisplay = cc. MenuItemLabel:create(label)
menuChageDisplay :setAnchorPoint(cc. p(0, 0))
-- 换装中装备显示的Index
local displayIndex = 0
menuChageDisplay :registerScriptTapHandler(function ()
displayIndex = displayIndex + 1
if displayIndex > 2 then
displayIndex = 0
end
-- 换装
bone :changeDisplayWithIndex(displayIndex, true)
end)
-- 增加了一个用于调试的临时按钮
local menuReload = cc. MenuItemLabel:create(cc .Label: create("Reload", s_markerFeltFontPath, 20))
menuReload :setAnchorPoint(cc. p(0, 0))
menuReload :setPosition(0, 20)
menuReload :registerScriptTapHandler(function ()
dofile( "src/main.lua") -- 强行重载, 写法欠考虑, 大家别学我
end)
menu :setAnchorPoint(cc. p(0, 0))
menu :setPosition(cc. p(50, 60))
menu :addChild(menuChageDisplay)
menu :addChild(menuReload)
return menu
end
layerTest :addChild(createLayerMenu())
return layerTest
end
-- 添加我们的测试层到Scene
sceneGame :addChild(createTestLayer())