独孤九剑与乾坤大挪移—uikiller插件系统
上篇《雷神之锤》介绍了uikiller的基本用法,有人说长按功能可以取名为蓄力攻击、重击,我觉得还真是可以的,但就是感觉招数名字不够大气。在这里还要给大家道个歉,上篇中我说了这一样句话:
uikiller只有一行需要要被主动调用的函数:uikiller.bindComponent
不好意思,在这里我可能隐瞒了大家,除了uikiller.bindComponent以外,还有一行可以被主动调用的函数
uikiller.bindNode(node, target)
这次希望我能把uikiller全部秘密给抖动出来,请各位不要太过惊讶!
一、独孤九剑
之前的篇幅主要介绍了uikiller的一系的招数、连击等,接下来讲讲uikiller的另一种绝技,它是争对敌人不同的招数一一破解的功法:独孤九剑(插件系统)
1. 总决式
总决式中体现插件类的写法,主要的属性和事件函数名
let UIKillerPlugin = {name: '插件名字',onRegister() {//当插件注册时响应},onCheckNode(node, target) {//当一个node将要被绑定时响应,返回false将不会绑定该节点下的子节点},onBeforeHandleEvent(node, event, hasEventFunc) {//当一个节点的事件处理函数执行前响应},onAfterHandleEvent(node, event, hasEventFunc, eventResult) {//当一个节点的事件处理函数执行后响应 }
};//注册插件
uikiller.registerPlugin(UIKillerPlugin);
uikiller的插件是一组事件勾子函数,这些勾子函数不一定都要实现,但一般至少要实现一个才有意义,了解了总决式,我们来看看能做些什么。
2. 破剑式—过滤节点
在一些战斗中,英雄与魔灵只需要站在那里,摆摆pose就够了,不需要被指挥(无需调用节点或组件上的方面)。可以将这些英雄们请到VIP席上就坐。
let UIKillerBindFilter = {name: 'UIKillerBindFilter',onCheckNode(node, target) {if (node === target.node) {return true;}//过滤掉首字母为“@”的节点下的子节点if (node.name[0] === '@') {return false;}/*在bindNode\bindComponent的最后一个参数是一个options对象*//*调用options上的过滤函数,进行节点过滤*/let options = target.$options;if (uikiller.isFunction(options.filter)) {if (options.filter(node)) {return false;}} }
};
uikiller.registerPlugin(UIKillerBindFilter);
在编辑器中,当节点以名“@”开头,他下面的子节点都不能会被绑定了。如果你还想复杂点你可以尝试用正则表达式过滤节点名。
遇到复杂的情况可以使用bindNode或bindComponent上的最后一个参数,设置一个filter函数实现动态过滤。
//组件代码
onLoad() {uikiller.bindComponent(this, { filter: (node) => {//在此可以根据node名字、类型等属性进行过滤 }})
}
3. 破刀式—Label的问题
Label是一个作战频次特别高的魔灵(component),但是问题也多,比如:字体、多语言特别的烦人,就像插在心口上的一把刀,这里介绍一种破多语言的方法。
const UIKillerLabelLanguage = { name: 'UIKillerLabelLanguage',onCheckNode(node, target) {//检查节点是否有label组件 let label = node.getComponent(cc.Label);if (!label) {return;}//以节点名上的$为多语言key,如果不存在以name为多语言keylet key = node.$ || node.name;//使用i18n获取多语言文本 label.string = i18n.t(key);}
};
这种方法不用为装备有Label的英雄(node)部署一个魔灵(component),直接在英雄的名字上做文章是不是更直接一些呢?除了Label外,还可以应用到EditBox\RichText之上,更多招数自己去发明创造!
4. 破枪式—音效控制
英雄、魔灵们奋勇作战,在战场上各种机枪、手枪、来福枪此起彼伏,喊杀声中还有带上背景音乐,可是在奎特尔上英雄是不能直接发出声音的,那是怎么办的呢?看下面最常见的一种做法
onButtonTouchEnd() {//处理一堆业务...//播放音效cc.audioEngine.play(url);
}
这种做法是到处埋地雷,稍微不注意把自己给炸了,还有可能地雷弄错了或要换地雷时,就惨了。
看看uikiller的破枪式,先定义一个音效配置
//用英雄节点的名字作key或者$名字也行const SOUND_CONFIG = {_attack: '3002.mp3',_expedition: '3006.mp3', click: 'click.mp3',
}
破枪式心法
const UIKillerTouchSound = {name:'UIKillerTouchSound',/*** 事件处理函数执行完毕后触发此函数* @param {*} node 触摸事件节点* @param {*} event 触摸事件对象* @param {*} hasEventFunc 是否有事件处理函数 * @param {*} eventResult 事件处理函数返回值*/onAfterHandleEvent(node, event, hasEventFunc, eventResult) {//在TouchEnd事件时,而且事件处理函数返回值不能为falseif (event.type !== cc.Node.EventType.TOUCH_END || eventResult === false) {return;}//获取声音文件名,没有的话统一的click声音let soundName = SOUND_CONFIG[eventResult] || //优先取事件返回值SOUND_CONFIG[node.$] || //其次取$名字SOUND_CONFIG[node.name] || //再次为节点名SOUND_CONFIG.click; //没有统一的click声音//播放音效let url = cc.url.raw(`resources/sound/${soundName}`);cc.audioEngine.play(url);}
};
战斗实操,领略一下如此整洁的战场,地雷没有了,只有动听的音效!
onLoad() {this.bindComponent(this);
},//有个_button节点,且写了这个函数,不做事也会有默认音效播放
_onButtonTouchEnd() {
},//有个_button1节点,事件函数返回了false,不会有声音出现
_onButton1TouchEnd() {return false;
},//有个_attack节点,音效配置中对应“3002.mp3”,将自动播放此音效,这里不用再费心了
_onAttackTouchEnd() {//如果返回一个音效配置字符串,将会改变声音的播放//return "_expedition";
},
破刀式可以作用于任何节点,不仅仅是Button,再此招式启示下,你可以可以推演出点击时的动画播放,比如爆炸一个粒子等等。
5. 无招胜有招
独孤九剑以无招胜有招,是敌强我愈强,使用“独孤九剑”,除了精熟javascript和奎特尔的世界外,还需要依赖使剑者的灵悟,一到自由挥洒、更无规范的境界,便如是大诗人灵感到来,作出了一首好诗一般。
二、乾坤大挪移
在讲解乾坤大挪移之前,需要做一点点铺垫,那就是在创造奎特尔星球上除了创世之主(程序员)以还,还存在两类物种分别是:
神机军师(策划)
幻灵法师(美术)
1. 谋士与法师的烦恼
谋士与法师也是构建奎特尔不可缺少的人物,他们通常都是高输出、低防御的特质,同时谋士与法师大多都不会使用咒语(编写代码)与英雄(node)和魔灵(component)做心灵沟通。
但有时谋士需要尝试下派兵布阵(UI布局),法师想预览下刚研制出的幻术(美术效果),在没有创世之主的帮助下,经常是做的得过且过,如何解决这个问题呢?
不使用任何一句咒语(代码),就能让谋士和法师任意放出或收回召唤兽(prefab)
经过我对javascript咒语和奎特尔的潜心研究,创造了新的招式:乾坤大挪移心法
2. 第一层
「乾坤大挪移」第一层心法,是对javascript运用,利用原型给魔灵们增加一个createNode、destroyNode法门。
//召唤一个英雄
cc.Component.prototype.createNode = function() {
...
}//给英雄放个假
cc.Component.prototype.destroyNode = function() {
}
这里就不帖那么多咒语(代码)了,请上github领取你的武器。
3. 第二层
第二层心法是利用cc.Button的ClickEvents事件属性布置召唤阵法,请看下图:
给Button英雄添加一个点击处理
给事件cc.Node属性设置为将要召唤出的神兽(prefab)的落脚点(父节点)
随便指定一个组件
组件方法上选择createNode(这是召唤核心)
CustomEventData设置为召唤兽的名字(prefab的路径字符串)
需要注意,召唤兽(prefab)需要放到resources目录中。点击这个Button,就可以将召唤兽(prefab)释放出来了。
4. 第三层
有召唤必有降伏,将不需要的英雄(node)或召唤兽(prefab)叫回去睡觉觉。
给Button英雄添加一个点击处理
cc.Node设置为想要休假的节点
随便指定一个组件即可
选择destroyNode方法
点击这个Button,节点就自己乖乖回家了!
乾坤大挪移的一大特点就是「激发最大潜力」,有此功夫谋士(策划)与法师(美术)的小宇宙也可以被激发起来,同时也激发了创世之主(程序员)做更有创意的事情。
5. 第四层
很轻松的就来到练乾坤大挪移的第四层,这一层不再是谋士(策划)和法师(美术)能轻易习得的了!前面我提到了uikiller中还有一个主动调用的函数: bindNode,它是修习后面几层的基础,功能非同小可,先看看最简单的演示:
onLoad() {//定义一个target对象,交UI编辑器上的节点和组件挪移到它上面去this.target = {//处理节点的触摸事件_onLabelTouchEnd() {//_label补绑定到target对象上了,可以用this直接访问 this._label.$Label.string = 'yyy'; }};uikiller.bindNode(this.node, this.target);//_label属性已经被挪移到this.target上了,在target变量上访问this.target._label.x = 100;this.target._label.$Label.string = 'xxx';
}
其实上面的演示中bindNode并不能展示他的威力,不过它体现了乾坤大挪移的精髓之一:「牵引挪移敌劲」,将一个组件上的节点和事件牵引到别的对象上。
6. 第五层
第五层了,我们来看看乾坤大挪移的「转换阴阳二气」的能力,接下来越下越复杂了,要细心哦,小心走火入魔。
创建一个傀儡魔灵,并绑定到一个prefab的根节点上
------------------XXXComponent.js--------------------
let Ctrl = require('Ctrl');
cc.Class({extends: cc.Component,onLoad() {//创建一个控制器this.ctrl = new Ctrl(this.node);//使用bindComponent注入乾坤大挪移的阳刚之气uikiller.bindComponent(this); },/*** 在此控制界面逻辑*/ _onButtonTouchEnd(sender) {//360度旋转起来this._button.runAction(cc.rotateBy(3, 360).repeatForever()); }
});
再制造一个幕后黑手一起操纵英雄(node)
let uikiller = require('uikiller');function Ctrl(node) {//使用bindNode注入乾坤大挪移的阴柔之力uikiller.bindNode(node, this); //同样方式访问节点与组件this._label.$Label.string = 'xxx';
};//定义成员函数
Ctrl.prototype = {/*** 在此控制业务逻辑*/_onButtonTouchEnd(//处理业务逻辑...//发起网络请求net.request(url, param, (data) => {//数据来了,停止旋转this._button.stopAllActions();this._button.rotation = 0;});}
}
上面的演示,相当于两个人同时一起驾驶了一部坦克,一起协作,他们之间遥相呼应,发动了一个大必杀技:激无双乱舞
看到这里,你可能对曾经的信仰有些怀疑了,因为有这样一个古老的传说
在奎特尔星球上一切皆魔灵(一切皆组件)
此刻,这个传说被打uikiller给打破了。
7. 第六层
第六层已经是很高的境界了,既然一切皆魔灵(一切皆组件)的传说被打破了,那利用bindNode的复制对手武功、牵引挪移敌劲的能力,就不一定要构造一个魔灵(component)控制战斗。同时结合PureMVC + uikiller.bindNode将prefab做为mvc中的view,将view中的节点和组件挪移到meidator中,那将是另一种全新的战斗模式!
7. 第七层
第七层MVVM,比第六层深了数倍,不好意思我也不得要领,还得继续修练,为了不至于走火入魔,我就不再介绍了!
四、写在最后
uikiller中关于上述大招的使用都放到github上了,欢迎把玩
https://github.com/ShawnZhang2015/uikiller
欢迎关注「奎特尔星球」微信公众号,有代码、有教程、有视频、有故事,一起来玩吧!
独孤九剑与乾坤大挪移—uikiller插件系统相关推荐
- SharpDevelop插件系统创建过程全面分析
前言 2005年2月,我申报了一个学校组织的大学生SRTP项目,项目的题目是数据结构动画演示系统.当初在做项目之前,我无意中买了一本书,书名为<SharpDevelop软件项目开发全程剖析> ...
- NET插件系统之四——提升系统搜索插件和启动速度的思考
一. 面临的问题 开发插件系统的主要优势是扩展性,我们不需要为系统模块的集成再多费脑筋,但这也带来了额外的问题.通常,系统需要在每次启动时搜索固定目录下的符合要求的插件.但是,当系统变得越来越庞大,所 ...
- 基于python3写的源码剖析_Python 极简插件系统 pluggy 源码剖析
前言 本长文不适合手机端阅读,请酌情退出 公司架构组基于 pytest 自研了一套测试框架 sstest,目的是为了让业务组(也就是我在的组)更好的写单元测试,从而提高代码质量,单元测试的目的是为了回 ...
- 浅谈C#中一种类插件系统编写的简单方法(插件间、插件宿主间本身不需要通信)...
文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/. 1.背景 三年多前还在上研时,用C#+反射机制写过插件系统,后来又用M ...
- web应用插件开发_Web应用程序的简单插件系统
web应用插件开发 我们需要制作多个具有很多共享功能的基于Web的项目. 为此,某种插件系统将是一个不错的选择(作为粘贴粘贴内容的替代方法). 有些框架(例如grails)可以选择制作Web插件,但大 ...
- Web应用程序的简单插件系统
我们需要制作多个具有很多共享功能的基于Web的项目. 为此,某种插件系统将是一个不错的选择(作为复制粘贴内容的替代方法). 有些框架(例如grails)可以选择制作Web插件,但大多数没有,因此需要实 ...
- .NET简谈插件系统开发模式
今天跟大家分享一下我们在日常开发中并不常用的开发模式"插件系统模式",什么叫插件从大一点的概念讲就是我们开发的软件是由很小的模块组成,每一块都能成功的装卸,使我们的软件成为一个有机 ...
- 做一个计算器_如何设计一个JavaScript插件系统,编程思维比死磕API更重要
WordPress有插件. jQuery有插件.Gatsby.Eleventy和Vue也是如此. 插件是库和框架的常见功能,并且有一个很好的理由:它们允许开发人员以安全,可扩展的方式添加功能.这使核心 ...
- Go 插件系统,一个凉了快半截的特性?
大家好,我是煎鱼. 在 Go 语言中,有一个好像很好用,但却比较少人提及的功能,那就是 Go Plugin. 目前在 Go 工程中普遍还没广泛的使用起来,覆盖率不高.在 Go issues 上吐槽挺多 ...
最新文章
- Chrome现在也能编辑pdf文件了!64位安卓版上线,网页加载快10%,还有良心标签管理功能...
- python if语句多个条件-Python 条件语句(if..elif..else)
- Intel Realsense D435 python multiprocessing 摄像头多进程流传输
- Python Django 文件上传代码示例
- JavaScript学习备忘
- Android为TV端助力 post带数据请求方式,传递的数据格式包括json和map
- Android Studio3.2经常用的一些依赖(以后再加)
- python机器学习实战_Python机器学习实战案例
- FPGA入门——1位全加器设计
- 数学建模-非线性优化模型
- DS18B20使用说明
- Java网络爬虫(七)--实现定时爬取与IP代理池
- 惠普打印机,打印状态:需要注意,打印时显示:需要用户干
- 【无标题】工商银行科技菁英岗笔经面经
- crmeb多商户公测版发布
- 陈立杰的励志演讲. 充满动力地走下去吧!
- 魅族手机调试出现is waiting for debugger的问题解决
- [改善Java代码]由点及面,一叶知秋----集合大家族
- 全新剪映专业版140内测版!等你体验!
- PTA 帅到没朋友 (20分)