奎特尔星球-雷神之锤(娱乐学习两不误)

-------------雷神之锤(上)----------------

奎特尔星球上有一件绝世神兵,就像是一把雷神之锤,在它的号令之下指挥着节点、组件和触摸事件,从而大量减少冗余代码与编辑器上的设置,他就是uikiller。uikiller指挥着英雄与魔灵杀敌无数,他的前身曾经在cocos2d-js星球上服役,名为UILoader。经过我潜心的改进,来到了奎特尔星球。

一、雷神之锤

uikiller只有一行需要被主动调用的函数:uikiller.bindComponent,他就像一把雷神之锤,为组件下所有的节点和组件注入了魔力。

cc.Class({
    ...
    onLoad() {
        /*绑定当前组件节点以及基下所有以“_”开头的节点*/
        uikiller.bindComponent(this); 
    }
});    

二、 杀、杀、杀—体验UI程序的快感

节点killer

image.png

在编辑器中以下划线“_”开头的节点,在雷神之锤的作用下,将会被自动绑定成当前组件实例的属性。

例如节点名:_labelName、_buttonOk

uikiller.bindComponent(this);  //使用bindComponent后即可访问子节点
this._labelName.active = true; //隐藏控件
this._buttonOk. x += 10; //设置 x 坐标

有没有一种很爽快的感觉,省去了定义和设置节点属性的动作,就上面三行代码来说,据我目测至少可以为你减少20个字节、两次的节点拖拽、30~60秒工作时间。

组件killer

在节点访问的基础上,使用**“$” + “组件名”**访问节点上挂载的组件对象。

例如节点名:_labelName 、_buttonOk

...
this._labelName.$Label.string = 'xxx'; //设置 Label的文本
this._buttonOk.$Button.interactable = false; //禁用按钮

访问组件属性同样很轻松,原来使用的getComponent(cc.Label)$Label所取代,再次为你省去5秒钟时间,代码量减少22个字节。

触摸事件killer

目前支持五个触摸事件

附赠很多人心仪以久的,触摸长按事件的支持

三、割草般的游戏体验—无双乱舞

1. 三国无双

2. uikiller中的无双技

3. 连锁闪电技

4. github源码地址

完整内容请点击以下面链接,如果喜欢可以点击文章结尾的爱心,这是对我莫大的鼓励

http://www.jianshu.com/p/174cc2160a7d

-------------雷神之锤(下)----------------

紧接上篇《奎特尔星球|雷神之锤(上)》,我给大家介绍了雷神之锤—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席上就坐。

插件代码略过

在编辑器中,当节点以名“@”开头,他下面的子节点都不能会被绑定了。如果你还想复杂点你可以尝试用正则表达式过滤节点名。

遇到复杂的情况可以使用bindNode或bindComponent上的最后一个参数,设置一个filter函数实现动态过滤。

3. 破刀式—Label的问题

Label是一个作战频次特别高的魔灵(component),但是问题也多,比如:字体、多语言特别的烦人,就像插在心口上的一把刀,这里介绍一种破多语言的方法。

插件代码略过

这种方法不用为装备有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) {
        此处代码略过
    }

战斗实操,领略一下如此整洁的战场,地雷没有了,只有动听的音效!

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法门。

3. 第二层

第二层心法是利用cc.Button的ClickEvents事件属性布置召唤阵法,请看下图:
部署Button事件

  1. 给Button英雄添加一个点击处理
  2. 给事件cc.Node属性设置为将要召唤出的神兽(prefab)的落脚点(父节点)
  3. 随便指定一个组件
  4. 组件方法上选择createNode(这是召唤核心)
  5. CustomEventData设置为召唤兽的名字(prefab的路径字符串)

需要注意,召唤兽(prefab)需要放到resources目录中。点击这个Button,就可以将召唤兽(prefab)释放出来了。

4. 第三层

有召唤必有降伏,将不需要的英雄(node)或召唤兽(prefab)叫回去睡觉觉。
image.png

  1. 给Button英雄添加一个点击处理
  2. cc.Node设置为想要休假的节点
  3. 随便指定一个组件即可
  4. 选择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. 第五层

第五层了,我们来看看乾坤大挪移的「转换阴阳二气」的能力,接下来越下越复杂了,要细心哦,小心走火入魔。

代码略过

上面的演示,相当于两个人同时一起驾驶了一部坦克,一起协作,他们之间遥相呼应,发动了一个大必杀技.
看到这里,你可能对曾经的信仰有些怀疑了,因为有这样一个古老的传说

在奎特尔星球上一切皆魔灵(一切皆组件)

此刻,这个传说被打uikiller给打破了。

7. 第六层

第六层已经是很高的境界了,既然**一切皆魔灵(一切皆组件)**的传说被打破了,那利用bindNode的复制对手武功、牵引挪移敌劲的能力,就不一定要构造一个魔灵(component)控制战斗。同时结合PureMVC + uikiller.bindNode将prefab做为mvc中的view,将view中的节点和组件挪移到meidator中,那将是开启另一种新的战斗模式!

8. 第七层

第七层MVVM,比第六层深了数倍,不好意思我也不得要领,还得继续修练,为了不至于走火入魔,我就不再介绍了!

四、写在最后

uikiller中关于上述大招的使用都放到github上了,欢迎把玩
https://github.com/ShawnZhang2015/uikiller

#完整内容请点击下面连接
http://www.jianshu.com/p/9ee11b1f71b9

26赞

哈哈,终于有人做出这样的东西了!

太疼么牛逼了

:grin:感谢引擎团队的大大们支持!

不要疼的太快了,后面还有更大的招!目前只是个入门!

美术太棒了

可以 这个不错 哈哈

这个真的可以有, 支持楼主!!!
getComponent被训练到行云流水不如一个$

:grinning:感谢你的建议,我把图片拿走了几张,娱乐性太强失去了它最本身的意义。

能减少一个字节的代码,就离生活更近了一步!

支持!

:+1:太强了,不过实时绑定开销太大,Creator打开复杂UI本身就比较慢,bindNode,bindTouchEvent,bindComponent里面多个foreach,造成了额外开销,话说使用const 1.6没有报错吗?:grin:

感谢你的建议和提醒,这个在1.5.2和1.6上都试过,都能正常使用
我刚才还在自己的项目中简单测试了一下主要界面单元绑定时的开销,大至如下:

  • chrome浏览器,基本是在5毫秒以内,大多数是0~2毫秒
  • creator模拟器,偶有出现10几毫秒的界面单元,也是在个位数
  • android手机,一台两年前的android手机,成绩稍微差一点,有零星的在50毫秒,大多数在15毫秒以下,绝大多数是个位数。
  • iphone5微信浏览器,大多数还是个位数,较大的界面在50毫秒以内

耗时多的基本上是那一两个大界面估计有上百个节点,小界面基本没什么感觉。
从上的测试都是在debug版本下看的,对游戏体验几乎没有影响,下来我可以增加一个性能测试的范例。

1赞

对的,有些界面不光节点多,而且层级深

遍历节点就是遍历的内存,速度非常快的,不用担心。
层级越深越能体会到他的方便性。

其中内置的有扩展,某些节点,比如动画,可以直接将它过滤掉。

不啰嗦,直接点星支持:clap:

配图叼爆了

我是雷神托尔
为了北方神的荣耀

2赞

你的雷神之锤,现在是奎特尔星球上的标配了!

1赞

新一波寓教于乐来了,uikiller教程更新,请看一楼
主要内容:独孤九剑、乾坤大挪移