麒麟子Cocos Creator实用技巧八:回合战棋类RPG战斗效果
HELLO,大家好,我是麒麟子。作为Cocos社区高产用户,今天又给大家带来了一个看起来很酷,但实际上大多数人用不到的DEMO。
不知道大家是否记得梦幻西游、问道、英雄无敌、仙剑奇侠传、神仙道、神曲OL。
不知道大家是否最近在玩自走棋(哎哟,不错哟,最近特别火)
然而,他们从技术上讲,没有本质的区别,他们的战斗都是回合制。
回合制的游戏就像棋牌一样,每一个回合,同一时间,只有一个人能操作。 等这个人表演完。再交给下一个。
DEMO内容:
这个DEMO展示了一个战斗场景,玩家可以控制一个英雄去攻击目标。 英雄有6个技能,当玩家点击某个技能的时候,英雄会冲到目标跟前,翻云覆云一番,再退回自己的位置。
有在线演示可以看哦:https://qilinzi.ukylin.net/?lesson=08
当然,还有,源码:https://gitee.com/qilinzi/qlz_ccc_tips
一、动作与特效
在这个例子中,英雄的动作和特效是在同一张图上的。显然,这样的方式不适合像传奇这样的MMORPG。 但是对于不换装的游戏,是完全没有问题的。还能省下不少DrawCall。
值得注意的是,我们在这个例子中,并没有使用Cocos Creator中的Animation来编辑英雄动画。 因为一个游戏有上百上千种动画,如果一个个手工编辑的话,是要死人的。 SO。。。 我们自己手写了一个。 请看大屏幕。
//动画信息配置
var AnimConfig = { }
AnimConfig['0001'] = {'attack':{frames:8,fps:8},'attacked':{frames:1,fps:8},'combat_idle':{frames:4,fps:8},'idle':{frames:4,fps:8},'ride_idle':{frames:4,fps:8},'ride_run':{frames:8,fps:8},'run':{frames:8,fps:8},'rush':{frames:1,fps:8},'spell1':{frames:8,fps:8},'spell2':{frames:8,fps:8},'spell3':{frames:14,fps:8},'spell4':{frames:8,fps:8},'spell5':{frames:4,fps:8},'spell6':{frames:10,fps:8},
}AnimConfig['0003'] = {'attack':{frames:8,fps:8},'attacked':{frames:1,fps:8},'combat_idle':{frames:4,fps:8},'idle':{frames:4,fps:8},'ride_idle':{frames:4,fps:8},'ride_run':{frames:8,fps:8},'run':{frames:8,fps:8},'rush':{frames:1,fps:8},'spell1':{frames:8,fps:8},'spell2':{frames:8,fps:8},'spell3':{frames:14,fps:8},'spell4':{frames:8,fps:8},'spell5':{frames:4,fps:8},'spell6':{frames:10,fps:8},
}export default class NewClass {public static getRoleInfo(roleId){return AnimConfig[roleId];}}
上面的类用于配置我们对应角色的动画,每一个动画,有动画名,帧数,帧率 三个属性。 每一个角色都有一个编码,如0001,0003。
import AnimConfig from './08_anim_config';const {ccclass, property} = cc._decorator;@ccclass
export default class NewClass extends cc.Component {@propertyroleId:string = '0001';@propertydefaultAnim:string = 'idle';// LIFE-CYCLE CALLBACKS:private _spriteFrames:Array<cc.SpriteFrame> = [];private _lastStartTime = 0;private getAnimInfo(animName:string):any{var info = AnimConfig.getRoleInfo(this.roleId);return info[animName];}onLoad () {}playAnim(animName:string){var aniInfo = this.getAnimInfo(animName);if(!aniInfo){return null;}this.defaultAnim = animName;this._lastStartTime = Date.now();var folder = 'roles/' + this.roleId + '/';var arr = [];for(var i = 0; i < aniInfo.frames; ++i){var url = folder + animName + '/frame' + i;arr.push(url);}cc.loader.loadResArray(arr,cc.SpriteFrame,function(err,arr){this._spriteFrames = arr;}.bind(this));}start () {this.playAnim(this.defaultAnim);}update (dt) {if(!this._lastStartTime || !this._spriteFrames.length){return;}var fps = this.getAnimInfo(this.defaultAnim).fps;var index = Math.floor((Date.now() - this._lastStartTime) / 1000 * fps);if(index > this._spriteFrames.length){this.playAnim('combat_idle');return;}index %= this._spriteFrames.length;this.node.getComponent(cc.Sprite).spriteFrame = this._spriteFrames[index];}
}
在上面的代码中,playAnim被调用的时候,我们首先获取到动画的信息,然后使用cc.loader.loadResArray来加载动画所需要使用到的图片。待加载完毕后,放入对象变量中缓存。
update里,我们根据时间计算出当前帧。
通过这样的方式,我们就可以基于配置和文件命名规则来实现大量的角色动画和NPC动画。 减少动画编辑的工作量。
二、攻击过程
回合制游戏,最大的特点就是玩家不需要控制角色位置。 所以,近身攻击是需要系统主动移动位置到目标跟前的。 攻击完毕后,又要移回来。 我们在这里,使用了cc.Action组合来做。先欣赏一下代码。
onCastSpell(event){var animName = event.target.__meta;if(this._isSpelling){return;}this._isSpelling = true;var arr = [];//切换成冲刺动画,并移动到目标跟前 arr.push(cc.spawn(cc.moveTo(0.3,this.target.node.position.sub(cc.v2(120,0))),cc.callFunc(function(){this.hero.playAnim('rush');},this)) );//播放攻击动画arr.push(cc.callFunc(function(){this.hero.playAnim(animName);},this));var animInfo = AnimConfig.getRoleInfo(this.hero.roleId)[animName];var playTime = animInfo.frames / animInfo.fps;//等待攻击完成arr.push(cc.delayTime(0.5 + playTime));//移回原来位置arr.push(cc.moveTo(0.1,this.hero.node.position));arr.push(cc.callFunc(function(){this._isSpelling = false;},this));var act = cc.sequence(arr);this.hero.node.runAction(act);}
1、冲刺到目标面前
为了实现冲刺到目标面前,我们需要在切换动画的同时,移动角色位置。 Cocos Creator提供了cc.spawn,构建出能够同时执行多个Action的组合Action。cc.callFunc我们理解为自定义Action,你可以在回调函数里编写你期望的逻辑。
2、攻击
我们只需要简单的使用cc.callFunc写一个自定义Action,进行攻击动作的播放即可。
3、等待播放完成
由于我们自己写的动画播放类,还未处理播放完成事件,所以在这里,我们使用了一个cc.delayTime来做等待,等待的时间,是根据动画帧率*帧数 + 一个固定值
4、回到原来位置
这个用cc.moveTo即可实现
5、把它们串起来
我们把所有的Action放入一个数组中,再使用cc.sequence,即可以构建出一个按顺序执行的cc.Action。 并把这个Action交给目标节点执行即可
6、其它
大家会看到一个this._isSpelling的变量,和这个相关的代码,均是为了防止用户在攻击过程中,多次点击出现BUG。
三、技能图标与池
技能图标的实现相当简单,就是把他们放到了一个Layout里面,只不过,我们是动态添加的节点。 在这里,麒麟子使用了一套常用的辅助函数
public static removeItemToPool(listRoot){for(var i = 0; i < listRoot.childrenCount; ++i){listRoot.children[i].active = false;}};public static addItemFromPool(listRoot){for(var i = 0; i < listRoot.childrenCount; ++i){var child = listRoot.children[i];if(child.active == false){child.active = true;return child;}}var newChild = cc.instantiate(listRoot.children[0]);listRoot.addChild(newChild);return newChild;};
removeItemToPool 会把所有的layout子节点标记为active = false;
addItemFromPool 会从layout子节点中选择一个active为false的节点,若没有可用的,则复制0号节点来用。
上面这个套路,麒麟子用了很久了,既简单明了,又能够控制对象池。 大家在做背包,或者其它大量子元素界面的时候可以试试。可以很任性的随意刷新,完全不用担心效率和内存问题。
四、结束语
有在线演示:https://qilinzi.ukylin.net/?lesson=08
源码:https://gitee.com/qilinzi/qlz_ccc_tips
大家朋什么不明白的,或者想了解但麒麟子没有写的。在本博客中留言即可,也可以直接在交流群里@麒麟子,或者私聊麒麟子。 谢谢大家的支持!
麒麟子Cocos Creator实用技巧八:回合战棋类RPG战斗效果相关推荐
- 麒麟子Cocos Creator实用技巧
麒麟子Cocos Creator实用技巧 大家好,我是麒麟子, 开源棋牌<幼麟棋牌-四川麻将>(泄漏版叫 <达达麻将>)作者,成都幼麟科技创始人. 自09年进入游戏行业以来,不 ...
- 麒麟子Cocos Creator实用技巧五:技能CD效果制作
今天带给大家的是一个关于技能CD的效果制作. 此效果不仅可以用于技能CD,一些按钮的CD也是可以用的. 为了照顾大家迫不及待(猴急)的心情,我写了一个DEMO给大家.DEMO上面做了5个英雄的技能和一 ...
- 麒麟子Cocos Creator实用技巧六:游戏背景拖拽实现
麒麟子做了一个DEMO给大家,这个DEMO很简单,大家可以按下鼠标,或者在手机上按住不放. 拖拽背景,背景会根据拖拽移动. 同时会保证背景边缘不会越过父节点的上下左右边界 在线演示:https://q ...
- 麒麟子Cocos Creator实用技巧七:方向与角度转换
麒麟子做了一个Demo给大家,向大家演示了方向转角度,角度转方向的应用. Demo中有两个坦克,中间的坦克锁定了另一个坦克,始终把自己的炮口对准它,并且会不停地发朝另一个坦克发射炮弹. 发出来的炮弹会 ...
- 麒麟子Cocos Creator实用技巧一:如何正确地显示微信头像
不管是游戏App,还是H5,又或者是微信小游戏.但凡接入了微信登录的应用,都可能需要显示微信头像. 在Cocos Creator中,我们常见的显示方法像下面这样 var headimg = 'http ...
- 麒麟子Cocos Creator实用技巧十:function this self ()={}详解
先说一声对不起,这篇文章本应该是昨天写的.(强行假装有很多人在等着看) 昨天聚众饮酒去了,喝醉了,可能喝了有两百多瓶吧. 有人就说啦,唉麒麟子,你怎么老爱吹牛*,动不动就两百多瓶,你真当自己是牛么. ...
- 麒麟子Cocos Creator实用技巧二:微信名字截断(支持表情)
在我们日常游戏开发中,经常会面临将玩家名字截断的需求. 假如玩家是在我们游戏中创建的名字,那么可以简单粗暴地禁止玩家使用手机表情输入即可. 但如果我们是第三方账号登录,且使用了第三方账号的用户昵称,那 ...
- 麒麟子Cocos Creator实用技巧四:打包原生App截图白屏解决方案
大家在做棋牌App或者一些特定需求的时候,需要截取当前游戏屏幕内容保存. 我们一般是采用cc.RenderTexture来截图并保存到游戏的可写目录 有时候会遇上,截出来的图片是白屏,或者部分白屏. ...
- 麒麟子Cocos Creator 3D研究笔记八:3D坐标转2D人物血条
夜深了,咱就直接进入正题吧,容麒麟子先上张图. 截自cc.d.ts 我们主要用到的就是这个CameraComponent中的converToUINode函数.它这个注释有点问题. 第一个参数 wpos ...
最新文章
- 「预警」尽快升级FastJson版本,避免恶意请求导致OOM!
- [译] 基于事件流构建的服务
- POJ 1833 排列【STL/next_permutation】
- java虚拟机和javaGC_Java虚拟机(三):GC算法和种类
- startup,startup mount,startup nomount之间的区别
- mosquitto源码分析(二)
- 图书排行:计算机书籍每周销量排行榜
- 对称加密算法和非对称加密算法的区别
- 【个人总结版】实验报告书写指导
- QT 基于Libvlc的视频播放器
- html调色板快捷键,12款web前端最佳调色板工具
- 一条机器“龙”,堪称史上最快异形机器人!
- MATLAB 中有哪些命令,让人相见恨晚?
- 台达0.4KW伺服上电报AL013
- Ardupilot固件之Flightgear模拟仿真
- 基于PreSCAN Matlab/Simulink的智能驾驶联合仿真【详细图文】
- JAVA的基本数据类型以及数值范围
- 如何在ftp服务器编辑文件,ftp服务器怎么编辑文件
- 安卓桌面软件_银河麒麟桌面操作系统V10
- 系统试运行报告如何写