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战斗效果相关推荐

  1. 麒麟子Cocos Creator实用技巧

    麒麟子Cocos Creator实用技巧 大家好,我是麒麟子, 开源棋牌<幼麟棋牌-四川麻将>(泄漏版叫 <达达麻将>)作者,成都幼麟科技创始人. 自09年进入游戏行业以来,不 ...

  2. 麒麟子Cocos Creator实用技巧五:技能CD效果制作

    今天带给大家的是一个关于技能CD的效果制作. 此效果不仅可以用于技能CD,一些按钮的CD也是可以用的. 为了照顾大家迫不及待(猴急)的心情,我写了一个DEMO给大家.DEMO上面做了5个英雄的技能和一 ...

  3. 麒麟子Cocos Creator实用技巧六:游戏背景拖拽实现

    麒麟子做了一个DEMO给大家,这个DEMO很简单,大家可以按下鼠标,或者在手机上按住不放. 拖拽背景,背景会根据拖拽移动. 同时会保证背景边缘不会越过父节点的上下左右边界 在线演示:https://q ...

  4. 麒麟子Cocos Creator实用技巧七:方向与角度转换

    麒麟子做了一个Demo给大家,向大家演示了方向转角度,角度转方向的应用. Demo中有两个坦克,中间的坦克锁定了另一个坦克,始终把自己的炮口对准它,并且会不停地发朝另一个坦克发射炮弹. 发出来的炮弹会 ...

  5. 麒麟子Cocos Creator实用技巧一:如何正确地显示微信头像

    不管是游戏App,还是H5,又或者是微信小游戏.但凡接入了微信登录的应用,都可能需要显示微信头像. 在Cocos Creator中,我们常见的显示方法像下面这样 var headimg = 'http ...

  6. 麒麟子Cocos Creator实用技巧十:function this self ()={}详解

    先说一声对不起,这篇文章本应该是昨天写的.(强行假装有很多人在等着看) 昨天聚众饮酒去了,喝醉了,可能喝了有两百多瓶吧. 有人就说啦,唉麒麟子,你怎么老爱吹牛*,动不动就两百多瓶,你真当自己是牛么. ...

  7. 麒麟子Cocos Creator实用技巧二:微信名字截断(支持表情)

    在我们日常游戏开发中,经常会面临将玩家名字截断的需求. 假如玩家是在我们游戏中创建的名字,那么可以简单粗暴地禁止玩家使用手机表情输入即可. 但如果我们是第三方账号登录,且使用了第三方账号的用户昵称,那 ...

  8. 麒麟子Cocos Creator实用技巧四:打包原生App截图白屏解决方案

    大家在做棋牌App或者一些特定需求的时候,需要截取当前游戏屏幕内容保存. 我们一般是采用cc.RenderTexture来截图并保存到游戏的可写目录 有时候会遇上,截出来的图片是白屏,或者部分白屏. ...

  9. 麒麟子Cocos Creator 3D研究笔记八:3D坐标转2D人物血条

    夜深了,咱就直接进入正题吧,容麒麟子先上张图. 截自cc.d.ts 我们主要用到的就是这个CameraComponent中的converToUINode函数.它这个注释有点问题. 第一个参数 wpos ...

最新文章

  1. 「预警」尽快升级FastJson版本,避免恶意请求导致OOM!
  2. [译] 基于事件流构建的服务
  3. POJ 1833 排列【STL/next_permutation】
  4. java虚拟机和javaGC_Java虚拟机(三):GC算法和种类
  5. startup,startup mount,startup nomount之间的区别
  6. mosquitto源码分析(二)
  7. 图书排行:计算机书籍每周销量排行榜
  8. 对称加密算法和非对称加密算法的区别
  9. 【个人总结版】实验报告书写指导
  10. QT 基于Libvlc的视频播放器
  11. html调色板快捷键,12款web前端最佳调色板工具
  12. 一条机器“龙”,堪称史上最快异形机器人!
  13. MATLAB 中有哪些命令,让人相见恨晚?
  14. 台达0.4KW伺服上电报AL013
  15. Ardupilot固件之Flightgear模拟仿真
  16. 基于PreSCAN Matlab/Simulink的智能驾驶联合仿真【详细图文】
  17. JAVA的基本数据类型以及数值范围
  18. 如何在ftp服务器编辑文件,ftp服务器怎么编辑文件
  19. 安卓桌面软件_银河麒麟桌面操作系统V10
  20. 系统试运行报告如何写

热门文章

  1. 诺基亚n1 android 64位,诺基亚N1开始推送安卓5.0.2系统更新
  2. Chrome 护眼插件
  3. oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
  4. matlab——GUI概念
  5. 公司U13 资本成本 习题解读
  6. iOS开发系列--地图与定位
  7. 关于利率的c语言程序,【c语言】储蓄利息的计算
  8. 前田约翰《简单法则》十条
  9. 局域网监控软件有哪些功能
  10. 单片机中如何将BCD码拆开_单片机中 BCD码转换