Cocos2d-x 3.3 GAF动画教程
在Cocos2d-x 3.4的发布日志中,偶然发现了GAF这个动画库。经过一番研究,下面将详细介绍Cocos Package Manager的使用方法,以及如何为项目添加GAF扩展。
1. Cocos Package Manager简介
Cocos Package Manager是一个引擎扩展模块化框架,主要服务于Cocos2d-x扩展的开发和使用流程。扩展开发完成后,可上传至服务器,供游戏开发使用。其使用引擎扩展的工作流十分清晰,以GAF为例,具体步骤如下:
- 创建工程:在命令行中执行
cocos new -l cpp命令,创建一个C++语言的Cocos2d-x工程。 - 下载并安装GAF扩展:运行
cocos package install gaf命令,下载并安装GAF扩展。 - 进入游戏目录:切换到刚才创建的游戏工程目录。
- 添加GAF扩展:执行
cocos framework add gaf命令,将GAF扩展添加到项目中。
完成以上步骤后,GAF扩展就会被安装到包文件夹中,可用于游戏工程开发。
2. 版本适配问题
我的项目使用的是Cocos2d-x 3.3,而非3.4。GAF官方网址为 http://gafmedia.com/,官方提供的转换工具最新版本是4.3(GAF Converter Version 4.3)。但使用 cocos package install gaf 安装的似乎是解析3.x版本的库。
我目前使用的GAF Converter版本是4.0,在撰写此博客时,顺便将其升级到了4.3。4.3版本的一大优势是界面支持中文。这里提一下,如果有大神能搞出GAF Converter破解版就好了,不过实际上免费版已完全满足需求。
在GitHub上,我使用的是 gaf_4_develop 分支,经测试,master 分支无法在Cocos2d-x 3.3中编译通过。在开始使用前,应先查看Cocos2d-xGAFPlayer项目 gaf_4_develop 分支的 readme.md 文件。
支持的平台和版本
- Windows:Cocos2d-x v3.3、v3.4
- Mac OS X:Cocos2d-x v3.3、v3.4
- iOS:Cocos2d-x v3.3、v3.4
- Android:Cocos2d-x v3.3、v3.4
- Windows Phone 8:Cocos2d-x v3.3、v3.4
- 即将支持:Linux项目
将GAF加入Cocos2d-x的方法
将GAF加入Cocos2d-x很简单,可将其拷贝或创建一个符号链接(仅在类Unix系统,如Mac下可行,Windows下不支持)到 cocos2d-x/external/ 目录下。
在我的项目中,为避免加入过多无关文件,仅添加了以下两个文件夹(一个是C++库,一个是Lua绑定库。不过不推荐这种做法,因为其中的 tests 和 sample 文件夹很有用,如果团队其他成员未下载完整的Cocos2dxGAFPlayer,将这些全部加入项目后,他们就无需再去其他地方查找GAF的使用方法)。
Cocos2dxGAFPlayer为Cocos2d-x提供了强大支持,包含VS项目文件(Cocos2dxGAFPlayer\Library\GAFPlayer.vcxproj、Cocos2dxGAFPlayer\lua_bindings\proj.win32\libGAFLuaBinding.vcxproj)、android.mk 文件以及Xcode工程文件(GAFPlayer.xcodeproj、gaf_lua_bindings.xcodeproj)。只需将这些项目文件添加到项目中即可。此外,还有 GenerateProjectFiles.py 文件,从文件名推测,它可能是一个用于生成带GAF扩展新项目的脚本。
与tolua相关的注意事项
Cocos2dxGAFPlayer\lua_bindings\conversions.yaml.diff文件是一个Git补丁,用于在lua/conversions.yaml文件中加入"gaf::": "gaf.",实现C++命名空间与Lua的对应。- 在Android中添加Lua绑定需要修改的地方,这里暂不详细展开。
3. GAF使用教程
免费版GAF功能限制
免费版的GAF用户支持元件动画,但不支持从Flash元件中提取动画序列。下面通过图片进行说明:
- 元件动画:免费版GAF用户无法使用。
- 场景动画:可通过label标签创建动画序列,如
seq1和seq2。播放效果如下,第一个GIF是seq1,第二个是seq2。这里展示了一个logo砸下去的动画和一个“文字遮罩特效”动画。对于“文字遮罩特效”动画,可参考 【Cocos2d-x 3.2】裁剪节点(ClippingNode)总结,若想偷懒,可让美术人员实现。
代码实现
C++代码
以下是创建和播放一遍动画,并设置播放结束回调的代码:
auto org = Director::getInstance()->getVisibleOrigin();
auto size = Director::getInstance()->getVisibleSize();
auto m_asset = gaf::GAFAsset::create("gafanim/logo_anim/logo_anim.gaf");
auto animation = m_asset->createObjectAndRun(false);
this->addChild(animation, 10);
animation->setPosition(Vec2(-size.width/2+200, org.y+size.height));
animation->setAnimationFinishedPlayDelegate(CC_CALLBACK_1(LayerLogo::onLogoAnimEnd, this));
在动画播放结束的回调函数中,去除回调并循环播放 seq2 动画:
void LayerLogo::onLogoAnimEnd(gaf::GAFObject* obj)
{
obj->setAnimationFinishedPlayDelegate(nullptr);
obj->playSequence("seq2", true);
}
Lua代码
在Lua中使用GAF的代码如下:
-- 玩家回合动画
local asset = gaf.GAFAsset:create("gafanim/player_round/player_round.gaf")
local animation = asset:createObject()
self:addChild(animation, 10)
local origin = cc.Director:getInstance():getVisibleOrigin()
local size = cc.Director:getInstance():getVisibleSize()
animation:setPosition(cc.p(origin.x, origin.y+size.height))
self.player_round_animation_ = animation
上述代码创建了一个动画,但未立即播放。在代码的特定位置,可通过以下代码播放动画:
self.player_round_animation_:setLooped(false, true)
self.player_round_animation_:start()
由于项目中暂时未涉及使用GAF动画序列的情况,因此未编写 tolua 相关代码。需要注意的是,由于不支持Lua的Lambda绑定,setAnimationStartedNextLoopDelegate、setAnimationFinishedPlayDelegate 等 setXXXDelegate 函数需要手动编写 tolua 文件,可参考Cocos2dx其他设置Lua回调的函数来实现。