Cocos2d-JS中使用CocosStudio资源——帧动画(2)
在本篇博客中,我们将通过一个在Cocos2d-JS中使用从CocosStudio导出的帧动画资源的例子,来简要介绍以下内容:利用ActionTimeLine进行动画切割,如何使用导出的帧动画资源。关于帧动画,由于内容繁杂。我们将分为两篇进行介绍。在上一篇中,我们已经做好了前期的资源准备和CocosCodeIDE中的简单处理,本篇将主要介绍资源的使用问题。
一、使用CocosStudio资源
做好了前期的准备工作,终于到我们的重头戏(FrameAnimationScene.js)了,下面,我们将要来学习如何获取CocosStudio中导出的资源等。
第一步:加载FrameAnimationScene界面的JSON资源分析,并获取FrameAnimationScene对象。将FrameAnimationScene对象加入到layer中。具体代码如下:
//加载frameAnimation界面的JSON资源分析,并获取frameAnimationScene对象。
frameAnimationScene = ccs.load(res.frame_animation_json).node;
//将frameAnimationScene对象加入到layer中。
this.addChild(frameAnimationScene);
第二步:从FrameAnimationScene中查找相应的控件对象,包括button控件和Shark动画节点所依附的那个节点,查找方法相似。具体代码如下:
//从frameAnimationScene中获取动画节点依附的节点对象
//通过该对象可以实现对动画节点的一些移动等操作,如:MoveBy,MoveTo等。
sharkNode = frameAnimationScene.getChildByName("ProjectNode_1");
//获取三个Button
attackButton = ccui.helper.seekWidgetByName(frameAnimationScene, "attackButton");
deadAttackButton = ccui.helper.seekWidgetByName(frameAnimationScene, "deadattackButton");
deadButton = ccui.helper.seekWidgetByName(frameAnimationScene, "deadButton");
第三步:添加事件监听,方法类似,具体代码如下:
//三个Button注册事件处理函数
attackButton.addTouchEventListener(this.buttonTouchEvent);
deadAttackButton.addTouchEventListener(this.buttonTouchEvent);
deadButton =
deadButton.addTouchEventListener(this.buttonTouchEvent);
第四步:运行动画前的准备工作,包括获取ActionTimeLine对象等,具体代码如下:
//从动画节点中获取ActionTimeLine。
shark = ccs.load(res.shark_json).action;
frameAnimationScene.runAction(shark);
第五步:设置帧事件监听。注意,此处有大坑!
//设置帧事件监听,每一帧一次监听。
//正常情况下应该使用如下语句:
//shark.setFrameEventCallFunc(this.frameAnimationEvent);
//但是,有Bug!!!不能用。
//换个角度解决问题,每一帧动画都会触发update事件。然后在update中写事件处理内容。
this.scheduleUpdate();
第六步:定义相应监听事件的具体处理信息,具体代码如下:
update:伪帧事件监听处理函数。
update:function(){
//换个角度解决问题,现在在这里处理每一帧的事件。
//判断动画是否在播放,如果在播放,则使所有按钮处于“禁用状态”
//从而来模仿“技能冷却”的使用。
if(!shark.isPlaying()){
//如果动画不在播放状态,则将处于禁用的技能激活。
if(!attackButton.isBright()){
attackButton.setBright(true);
attackButton.setTouchEnabled(true);
}
if(!deadAttackButton.isBright()){
deadAttackButton.setBright(true);
deadAttackButton.setTouchEnabled(true);
}
if(!deadButton.isBright()){
deadButton.setBright(true);
deadButton.setTouchEnabled(true);
}
}
},
PS:如果没有Bug的话,帧事件处理应该写在这里:
frameAnimationEvent:function(frame){
//正常情况下,应该在这里处理每一帧的事件。
cc.log("Frame Animation Event");
}
Button控件触发的事件处理,在这个事件处理里面,我们会展示游戏设计中常用的帧动画处理的相关方法具体代码如下:
buttonTouchEvent:function(sender,type){
//三个按钮的事件处理函数
switch (type) {
case ccui.Widget.TOUCH_ENDED:
switch (sender.getName()) {
//可以通过两种方式设置动画的播放。
//推荐第二种!!!!
case "attackButton":
//第一种
//通过设置开始帧,结束帧,是否循环播放等进行播放动画
shark.gotoFrameAndPlay(0,30,false);
//将按钮设为禁用状态。
self.changeButtonBright();
break;
case "deadattackButton":
//第二种
//通过player函数播放指定名称的动画
shark.play("DAttack",false);
self.changeButtonBright();
break;
case "deadButton":
shark.play("Dead",false);
self.changeButtonBright();
//死的时候,先往前走几步,倒下死亡,再滑回来。
sharkNode.runAction(cc.Sequence(cc.MoveBy(0.5,cc.p(-100, 0)),cc.MoveBy(2,cc.p(100, 0))));
break;
default:
break;
}
break;
default:
break;
}
},
PS:changeButtonBright函数的具体代码:
changeButtonBright:function(){
//将各个按钮设为禁用状态。禁用触摸响应。
attackButton.setBright(false);
deadAttackButton.setBright(false);
deadButton.setBright(false);
attackButton.setTouchEnabled(false);
deadAttackButton.setTouchEnabled(false);
deadButton.setTouchEnabled(false);
},
代码简介:
上面的代码都有注释,看了应该很明白。这里就简单介绍一下:
1.整体思路:
通过点击三个技能按钮,分别为普通攻击,大招攻击,死亡。每个技能释放过程中,所有技能都会进入冷却状态,只有等技能释放完毕后,才能释放下一个技能。释放死亡技能时(额,这个不能算作技能。),人物会向前走几步,再倒地死亡,然后再滑回来(只是为了让人物保持原来位置,所以加个滑回来的动作。)。2.技能冷却设计:
我想这个应该是游戏设计中经常会用到的功能。首先,我们在每次释放技能的时候,调用changeButtonBright方法,将所有技能按钮禁用(类似于进入冷却)。由于帧事件回调函数shark.setFrameEventCallFunc(this.frameAnimationEvent);
不能用,所以,我们采用update方法,每一帧都更新一次,检查一下,现在是否在释放技能,如果不在释放技能,就激活处于冷却状态的技能。通过上面的过程就可以顺利地完成技能的冷却和激活操作,当然了你可以进一步在update函数处理中,对更细节的地方进行处理。操作和思路应该都相似。
PS:貌似isDone()方法也不能用,求官方早日解决!!!!当然了,如果是我使用姿势不对,还欢迎各位朋友指点一二。
3.边放动画边移动:
我想这也是大多数游戏设计中所必须的功能,你想如果你的人物在不停地奔跑,却在屏幕中只停留于原地,这得是多么悲哀的事情!!!!
本文提供了一种解决方案,那就是:获取动画节点所依附的节点,通过操作此节点可以实现边移动(MoveBy)边播放动画。在这个例子中,我们是在人物死亡时,让他向前走几步再死,然后滑回去。
二、运行效果
到这里,对于FrameAnimationScene界面的分析和使用就介绍完毕了。你可以运行一下。我的部分运行效果如下:
大招效果图
死亡效果图
三、补充说明
为了方便大家学习研究,下面提供本教程项目文件的百度网盘下载链接:
LoginScene.js的完整源码如下:
var LoginLayer = cc.Layer.extend({
loginScene:null,
loginButton:null,
nameTextField:null,
passwordTextField:null,
saveCheckBox:null,
name:null,
password:null,
ctor:function () {
//////////////////////////////
// 1. super init first
this._super();
/////////////////////////////
// 2. add a menu item with "X" image, which is clicked to quit the program
// you may modify it.
//加载login界面的JSON资源分析,并获取loginscene对象。
loginScene = ccs.load(res.login_json).node;
//将loginscene对象加入到layer中。
this.addChild(loginScene);
//从loginScene中获取控件并注册监听事件。
this.dealWidgets();
return true;
},
//从loginScene中获取控件并注册监听事件。
dealWidgets:function(){
//LoginButton控件
loginButton = ccui.helper.seekWidgetByName(loginScene, "login");
loginButton.addTouchEventListener(this.buttonTouchEvent);
//nameTextField输入框控件
nameTextField = ccui.helper.seekWidgetByName(loginScene, "name");
nameTextField.addCCSEventListener(this.textFieldEvent);
//passwordTextField输入框
passwordTextField = ccui.helper.seekWidgetByName(loginScene, "password");
passwordTextField.addCCSEventListener(this.textFieldEvent);
//checkBox控件
saveCheckBox = ccui.helper.seekWidgetByName(loginScene, "save");
saveCheckBox.addCCSEventListener(this.selectedStateEvent);
},
//CheckBox控件触发的事件处理
selectedStateEvent: function (sender, type) {
switch (type) {
case ccui.CheckBox.EVENT_SELECTED:
cc.log("Event Selected");
break;
case ccui.CheckBox.EVENT_UNSELECTED:
cc.log("Event Unselected");
break;
default:
break;
}
},
//TextField控件触发的事件处理
textFieldEvent:function(sender,type){
//根据触发事件的类型进行分情况处理,从控制台输出cc.log();
switch (type) {
case ccui.TextField.EVENT_ATTACH_WITH_IME:
cc.log("TextField Event Attach With Ime");
break;
case ccui.TextField.EVENT_DETACH_WITH_IME:
cc.log("TextField Event Detach With Ime");
break;
case ccui.TextField.EVENT_INSERT_TEXT:
cc.log("TextField Event Insert Text");
break;
case ccui.TextField.EVENT_DELETE_BACKWARD:
cc.log("TextField Event Delete Backward");
break;
default:
break;
}
},
//Button控件触发的事件处理
buttonTouchEvent:function(sender,type){
//根据触发事件的类型进行分情况处理,从控制台输出cc.log();
switch (type) {
case ccui.Widget.TOUCH_BEGAN:
cc.log("loginButton Touch Began");
//获取用户在name和password输入框的输入。使用getString()方法获得内容。
cc.log("username : " + nameTextField.getString());
cc.log("password : " + passwordTextField.getString());
//获取用户是否勾选CheckBox,使用isSelected()方法获取,返回boolean。
cc.log("saveState : " + saveCheckBox.isSelected());
break;
case ccui.Widget.TOUCH_MOVED:
cc.log("loginButton Touch Moved");
break;
case ccui.Widget.TOUCH_ENDED:
cc.log("loginButton Touch Ended");
break;
case ccui.Widget.TOUCH_CANCELED:
cc.log("loginButton Touch Canceled");
break;
default:
break;
}
}
});
var LoginScene = cc.Scene.extend({
onEnter:function () {
this._super();
var layer = new LoginLayer();
this.addChild(layer);
}
});
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。