————————————————————
如果你是个新手,现在讲一些复杂的触发器,基本上你会看不懂,所以咱们这章主要讲思想,这种抽象的东西可能会改变你未来的触发器风格,鲁迅曾经说过:“触发器要从娃娃抓起”,触发器风格一旦形成,在后天将难以改变,所以此章将带领各位新手走到正确的方向上,这对于你们以后的发展是大有裨益的。
触发器技术分为两个大类,一个是函数的运用,一个是算法与数据结构。前者是形,后者是神,只有形神兼备,才能打造顶级的触发器。形,即外在,这里指函数的运用,这是新手期作者主要的研究内容,只有熟悉各种函数的使用,才能在这个架子上搭载我们的“神”,即内在,它看不见,但是却是打破触发器瓶颈的那把唯一的锤子,就像内功一样,虽然无形,但却有质,这种东西需要在不断的作图中形成,而本教程将直接将这些知识灌输给你,希望你可以从中获得一点点启发。
本章讲的特殊玩法,是比较广义的,包含Boss、耐久和纯特殊玩法等等需要使用大量触发器的地图,关于Boss制作的教程,网上也有不少,我们这里就不做讲解了。
这里给出官方文档的Boss教程:
https://easydoc.net/s/85829661/USXlrH6u/jomA211r
好了,接下来看看本章咱们的知识点:
· 触发器的数据流
· 封装思想
· 数学
· 算法
· 数据映射
· 输入层、逻辑层、显示层
触发器的数据流
在研究数据流之前,我们先思考一下触发器的本质是什么,它有事件、有条件、有动作,综合来看,它是一种在指定时机下能自动执行的脚本(也就是动作)。事件和条件选择符合的时机,动作提供操作,所以触发器的数据运行全在动作中,这里的数据,指的是咱们上一章讲过的所有数据类型。
你会发现其实动作里写的函数,大多都是对数据进行操作,比如单位、漂浮文字、字符串、整数、二维向量等等,触发器的动作里可以创建数据、修改数据、查找数据以及删除数据,而不同触发器之间可能也因为处理相同的数据而造成关联性,而从数据本身的角度来看,它被多个触发器控制,所以就肯定会在触发器之间来回流动,这就是触发器的数据流。
以上是新手制作触发器的数据流,其中红线表示数据之间存在关联,很显然,这些数据的流动非常的复杂,只要改动其中的一个数据,就可能牵一发而动全身,这种数据流结构非常难以控制,而且也极易出现bug,所以我们的触发器一定要“高内聚、低耦合”,意思是数据在单个触发器内部集成流动,触发器之间的数据交流要尽量的少,下面我们来看看“高内聚、低耦合”的数据流是啥样子的。
触发器之间的数据流动很少,但是触发器内的动作里的数据交流频繁,这样的流结构有助于提高触发器运行的稳定性,也更容易排查bug。
封装思想:
前面提到的“高内聚”实际上就是封装思想了,也就是将触发器当做一个盒子,把动作装进去,让数据流在其中流动,而这个盒子对外只有输入接口和输出接口,这种对触发器进行封装的思想,在特殊玩法中尤其重要。
上图就是一个封装结构,其中的接口实际上就是全局变量,因为全局变量在各个触发器中都能获取和改变,所以全局变量在触发器中充当着重要的角色,是触发器之间交流的桥梁。当然了,以这种结构思想来写触发器,就必须将触发器分块写,争取一个触发器只干一件事,这种方法可以让你的触发器看起来更多一点(???才不是),这样写的触发器结构层次清晰,bug的可能性会减小,如果出现了bug,由于触发器之间的低耦合性,所以在找bug时会很方便。
但是!由于触发器和编程不同,编程上可以很好的应用这套标准,而触发器毕竟是不同于编程的,所以比如一些无需对外做信息交流的触发器则不需要输出,当然输入一般得有。而且更妙的是,多个触发器可以共同封装,封装也可以嵌套(套娃),如下图所示:
触发器的封装更需要灵活运用,有的时候不需要封装,有的时候就必须要用,这种能判断该如何封装触发器的思想只能通过实战来获得,根据应用场景的不同,选择也不同。
以下举例封装形式的触发器:
初始化时定义一个整数作为输入:
当事件触发,则接收输入,并执行操作,最后运行下一个触发器,将输出传递过去:
“触发器1”被执行,接收上一个触发器的输出,并当做自己的输入,经过处理后,输出最终结果:
这里封装了两个触发器,当然了,咱们的例子是没有什么实际意义的,只是想通过这种方式来展示结构,实际应用中的封装会复杂的多。
数学:
计算机为啥叫计算机?顾名思义,它能做的事就是计算,它干的最主要的事也就是对数字进行加减乘除(CPU)和存取(ROM/RAM),任意的程序或应用软件,都是基于数学的,一个程序,实际上本质就是对数字做运算,所以说,触发器也是如此,玩触发器到达比较高的层次后,基本上都是在玩数学。
千万不要觉得数学是枯燥的,因为你可能只是受到了9年义务教育的鞭挞,“享受”着数学课本里那些复杂的公式以及晦涩难懂的专业性语句(简称:不说人话)的熏陶,而这只是应试教育泛滥的结果。实际上,数学是非常美妙的,美的有时候你都不知道为什么会这么巧,有些公式虽然难以记忆,但是公式之间竟然有着出奇的一致性,即使它们的推导过程并不相同。生活在互联网时代,或者说是数字化时代,数学,是每个人都应该了解的一门“必修课”,如果你有幸在未来成为了触发器大佬,你也一定会感受到数学的强大魅力,因为强大的触发器,往往需要一些数学知识,你在以前学习的数学知识,可能真的可以在编辑器中得到应用,而不是仅仅被考试所践踏!
使用数学最多的玩法是耐久,耐久中的各种花式弹幕,其实就是一个个的数学函数描绘的。
比如爱心曲线的参数方程(其中,t为从0到2π):
应用到游戏中(其实就是将子弹(玩家)单位创建在数学函数所对应的坐标上):
Look!数学是多么美妙的东西啊!接着看看其他的数学函数表现出的样子:
当然了,数学函数还远远不止有上面的这些,耐久的制作,其实更像是一场数学盛宴,每一个弹幕都经过精密的数学计算,在其出生的那一刻,就被规划好了移动的路径、速度以及各种形态变化。
算法:
算法,即计算方法,常用于纯特殊玩法中,当然算法一听名字就知道又是和数学相关,算法的百度解释是:解题方案的准确而完整的描述。这又是什么不当人的话??简单来说,算法就是根据一定的输入,经过一系列的计算流程,得到最终的输出结果,其实就跟解数学题目类似,题中给出已知条件,我们通过一系列的计算,能得到一个准确的答案,这个答案就是由已知的数据推导出来的输出,而算法,就是你的那些计算步骤。
借用Nicklaus Wirth博士的著名公式:程序 = 数据结构 + 算法。
数据结构是指数据之间的逻辑关系,这个在我们上面讲数据流时其实就已经描述了这一点,而算法是用来求解特定问题的步骤和方法。
可见算法是相当重要的东西,但其实在ic中,使用算法的地图并不多,因为大多数作者并不是专业的程序员,而实际上,如果会使用算法来做特殊玩法的作者,基本上都是大佬,因为算法是触发器的内功,学会再多的函数(招式),也不可能比得过具有深厚内功的。
那么算法在触发器里到底是个啥呢?现在,Konux还是以我的斗地主触发器为例子,给你们看看最简单的一种算法:
这个触发器实际上做的就是把牌给排好序(这里有变量套娃,因为我把握的住,新手千万别学),其实这个问题的本质就是将一个含有很多个整数的数组根据从小到大的顺序排好,就像下面这样:
排好序之后,要求变成这样
将数组里的数字排好序,就是最简单的算法问题,在这个触发器中,使用的是冒泡排序(BubbleSort)算法,所以在这里介绍一下这种算法:
1.遍历原始数据,从第一个数开始,到倒数第二个数结束,比较这个数和下一个数的大小,如果这个数比下一个数大,则交换这两个数。这样便可以将数据中最大的数转移到数组的最后。
2.之后再次遍历原始数据,但是变为从第一个数开始,到倒数第三个数结束,比较这个数和下一个数的大小,如果这个数比下一个数大,则交换这两个数。这样便可以将第二大的数转移到数组的倒数第二位。
3.重复执行上述过程,一直到从第一个数开始,到第二个数结束,从而完成排序过程。
由于这个循环过程就像泡泡上浮的过程,所以被称为冒泡排序法。
可能不太好理解,我们接下来用上面的例子来演示整个排序过程。
当然了,由于我们这里的例子不是那么乱,所以排序到第二轮的时候就已经排好了,上面是为了描述完整的冒泡排序过程,所以继续将接下来的轮次都画出来了,实际上我们可以通过一个变量来检测排序是否完成,然后提前终止掉循环,下面给出触发器:
首先我们把数组造出来,并用一个变量表示数组里的变量个数
然后我们开始写一个简单的BubbleSort
OK!写完了,我们在底下写个for循环把这个数组打印出来看看:
完美排好序了!但是我们刚才说了,如果提前就排好序了,轮次如果还继续下去就会很蠢,所以我们要用一个变量来控制轮次在排好序后能直接结束
OK!这就是一个完整的冒泡排序算法,这也是最基础的交换排序算法,在编程中排序算法有很多,比如选择排序、插入排序、希尔排序、归并排序、快速排序、堆排序、桶排序、计数排序、基数排序,加上我们的冒泡排序共同组成十大排序算法,如果大家感兴趣,可以自行学习相关算法。排序算法只是简单的算法,在IC中,有不少触发器大佬做出了随机迷宫(Prim)算法、自动寻路算法(基于A-star)、五子棋人机算法、斗地主牌型识别算法、RSA加密解密算法等等(啊,没错,我都有写过)!
算法的世界是非常神奇的,希望你们能够加入其中,并享受实现算法的一瞬间带来的快感!
数据映射:
啥是数据映射?比如现在我们要做一个扫雷,该怎么入手呢?
你或许最先想到的是先寻找数字、雷、雷爆炸、标旗等素材,并且创建搭载这些素材的单位,用这些单位摆好扫雷的盘面,因为你会想着如果素材都不弄好就去做,最后做出来了成品,想要再去改单位或者素材就会非常麻烦了。
其实产生这种思维很正常,因为大多数人都是“面向单位写触发器”,也就是你做一个游戏,特别依赖于单位,但实际上,我做的扫雷根本不依赖单位运行,我一开始就没有找素材、摆单位,我直接就开始做扫雷的游戏逻辑了,那么这是怎么做到的呢?这就是通过数据映射的方式,我使用纯数学逻辑,构造了一个虚空的扫雷盘面,它只以数字的形式出现,使用触发器,操控的就是这些数据以进行游戏,正是因为这些数据是虚空运行,所以外界的环境对它造不成干扰,它一定是绝对正确的,除非是算错了。
我们来看看如何做数据映射:
如上,我首先定义了扫雷的盘面大小(15指盘面为15*15)和这个盘面的左上角坐标,定义这两个量的好处是,即使我们做完了扫雷,也可以很方便的通过改这两个变量的值来调整扫雷的盘面大小和位置,可以让扫雷放在自己想放的任何位置。
还记得二维数组的形状吗?二维数组就是天然的矩形数据,所以二维数组就可以作为盘面的数据的载体了!(拿出上一章的图)
接着我就用两层for循环开始做盘面了,先是设置了名为“雷”的整数二维数组,此数组中,值为0表示无雷,为1表示有雷,但是我们这是在初始化盘面,所以先全设置为0,也就是不放雷;接着我们设置了一个名为“数”的整数二维数组,这个数组是用来记录每一个格子上的数字的,其实就这两个二维数组,就已经完成了数据映射,将盘面数字化为了二维数组,这样我们就只需要对二维数组做操作即可完成游戏的运行,但是数据需要载体来呈现,所以我接着造了单位作为盘面的显示,这些单位我使用数学计算出了每一个单位的相应坐标,当然,我们也用一个二维数组将这些单位给获取了,这样,这些单位也被数据化了,我们以后不会对单位进行直接操作,只需要对二维数组做操作即可。
初始数据化完毕之后,我就紧接着开始用这些数据布雷(不需要看懂):
可以看到,我使用的函数全是数学或变量,根本没有使用单位。
然后我们可以对这些数据做输出,看看效果
也没有单位,只有数学和漂浮文字(用于显示)
看看结果:
是不是非常酷炫呢?我们的场景上并没有摆放任何单位,全是触发器制作的:
好了,数据映射就讲到这里,希望你们在做纯特殊玩法的时候,思维一定要打开,在触发器的世界里,你就是上帝,将游戏的数据数字化,将会使你的触发器高级很多!
输入层、逻辑层、显示层:
这一部分将是上一个部分的延伸,数据映射是干了啥?其实它就是游戏的虚拟主体,游戏的玩法通过操控数据的方式运行,对数据做数学运算操作的层级叫做逻辑层,而一个特殊玩法,整体也需要封装为几个模块,分别就是输入层、逻辑层、显示层,接下来请看层级结构图。
输入层用来接收玩家的操作(游戏运行取决于玩家的操作),逻辑层负责将玩家的操作对应的数据做逻辑运算处理,当处理完毕之后,将逻辑结果输出到单位上(或图片、文字),这就是显示层,显示层的单位只充当显示图片的作用,并不需要用到单位的功能。特殊玩法的这种结构,将会大大的提高你触发器的稳定性和层次性,使触发器能尽然有序的进行。
好了,这就是本章的所有内容,希望看完后,你能对触发器产生颠覆性的认识,从而以后能更好的驾驭触发器!
编辑器新手入门交流与讨论可加入官方二群,群号:979717879