|
楼主 |
发表于 2013-1-29 22:41:56
|
显示全部楼层
【辅助型接收器FU、DO、I/E、VR】从之前的“触发器”与“接收器”的机械组装中脱身暂缓
这次讲到的辅助型接收器很特别,它们没有实际的修改能力
但是它们拥有让你的组装更加精细化、简洁化、便利化的能力
而且,这三个接收器对于毫无编程基础的新手而言,是看不懂的,从本质上就不同于一般的接收器,使用方法从根本上不同于积木的对接
但在说明它们的使用方法之前,先介绍下一个简单的功能:
!!IF:M^大家好,我是说明君!^; 这个功能就是弹出对话框,显示夹在^^之间的内容,总之这个环节要测试啥都依靠它了
【FU】
函数,这个取名很专业啊,而且它的说明也很让新手摸不着头脑 —— 什么叫虚拟触发器?
以及,!?FU#; 这种和触发器一样的格式到底有什么意义?要知道FU根本就没有触发时机,如果不人为的调用它,它一辈子也不可能触发。
它也就确实是必须调用的触发器,所以称作虚拟触发器吧?不过各位没有必要称之为触发器,为了避免混乱,还是直接叫它函数好了
所谓函数,在各大变成语言中莫不是“功能模块”的定位,你或称它为工具,不过函数更像是加工厂,你交给他原料&配方,他就给你制作产品
然而,函数也是一个空壳,正如帮助文档里面FU的内容看上去一大堆,其实少得可怜,只要理解了概念,它就并不是多么复杂的东西了
【FU使用方法】
建立函数:
!?FU#; 这就是一个开始,表示你建立了函数,这个函数的功能全部都在紧接着的!!里面
!!
!!
!!
!!
但是这个函数不会执行,除非你调用它
复杂的不说,函数FU里面就两个实用的功能E&P
!!FU:E; 是立即退出当前触发器,能够立即退出任何以!?开头的触发器,只要你将这个代码添加进去,轮到它就退出触发器,后面的!!就全部废了
!!FU#:P; 这个就是执行函数,注意,只是执行“#号”函数而已,虽然还有些附加功能,暂且不提。
那么,很明显了,FU只能通过P来执行,今后凡是用到函数,都是在某个地方编写!!FU#:P; 或者!#
那么,这有什么意义呢?
仅从目前我介绍的FU功能来看,也是有一定意义的
FU可以提供便利,假如你全篇代码有很多重复的内容,比如:
!!IF:M^我有个设想,版主帮我写一下!!^;
!!IF:M^版主快来嘛!快来帮我啊!^;
!!IF:M^我完全不会啊,版主帮我改一下啊!^;
每次都要复制粘贴多累,假如有了FU
!?FU233;
!!IF:M^我有个设想,版主帮我写一下!!^;
!!IF:M^版主快来嘛!快来帮我啊!^;
!!IF:M^我完全不会啊,版主帮我改一下啊!^;
之后你们就没有必要复制这么一大段话了,直接一句!!FU233:P; 就搞定了~~
比如:
!#!!FU233:P; 这样游戏开始的时候就会弹出这3个对话框。
【FU的高级应用】
下面介绍FU的另一个功能,其实在帮助文档的FU —— P 里面就有说明,只是我根本不觉得新手能明白是什么意思
即:
要获得参数请使用x# (#=1...16)语法
它们可以被用在函数内的标志变量使用的任何地方。当你使用其他函数时(见示例),所有没有被设置参数都将保存
总之我看的时候一片迷茫虽然迷茫的地方和不懂编程的人不太一样
那么开始介绍吧
函数FU是可以传递参数的,和之前说的那些参数没有本质区别,但是嘛……复杂的就不说了,FU函数的本体其实是:
!!FU#:P$1/$2/$3/$4/$5/$6/$7/$8/$9/$10/$11/$12/$13/$14/$15/$16;
只不过,后面的都可以忽略,如果你只用到2个参数,那就是
!!FU#:P$1/$2;
如果你要用到5个参数,那就是
!!FU#:P$1/$2/$3/$4/$5;
那些忽略掉的参数默认为0
问题在于接受,那是有同样数量的x变量来进行接受:
x1 对应 $1
x2 对应 $2
……
x16对应$16
所以,如果我这么写:
!!FU233:P3/16;
这个233号函数的x1就是3,x2就是16
来个实例:
ZVSE
!?FU11233;
!!IF:M^x1=%X1,x2=%X2^;
!#FU11233:P4/25;
空行
其结果应该是在载入地图的时候弹出1个对话框,显示:
至于这有什么用……各种方面都很有用,比如扳手可以开螺帽,扳手可以敲钉子,扳手还可以投掷出去打人
总之为了避免混乱,暂且不深入讨论用法,进入下一个环节
【DO】多次循环调用FU函数:这个说明很到位,也就是这个功能了
DO是第二个可以调用FU的,也只能用来调用FU
可能对于新手来说,循环这个概念很难理解,主要体现在:以怎样的方式循环 —— 直接查看帮助文档:
!!DO #1/ #2/ #3/ #4: XXXX; | 多次循环触发FU函数:
#1 函数的编号,
#2 (x16)起始值
#3 (x16)结束值
#4 步长
| 先不解释,大家应该注意到了,这个DO只有一个单字母员工:
P $/ $/ $...
up to 15#s. | 多次循环触发函数: P
通过获得函数来使用x# (#=1...15)语句
它们可用用作标准变量所使用的任何地方
当你使用另外的功能时(见示例),所有未被设置的参数都将被继承
| 也就是说,DO的格式永远都是!!DO #1/ #2/ #3/ #4: P $/ $/ $... ;
其实和!!FU#:P; 是一样的,只是因为还包括了循环功能所以才写成这样这个格式可以这么读:
循环执行#1号函数,从整数#2开始,到整数#3结束#,假设?代表现在值,循环的开始?=#2,每循环一次?=?+#4,当?大于#3的时候循环结束
P的参数比FU的P少了一个,即x16,其实,这个x16就是?,也就是说,x16代表了现在值,P后面和FU的P一样就不解释了,需注意只有15个参数即x1~x15
这个DO有什么用呢,和FU一样,用处挺多,不好介绍,也为了避免你们混乱,此处只举个简单的例子:
假设你要将所有的兵种攻击力翻十倍,你觉得你得写多长的代码?SOD197个兵,代码至少197行吧,但如果你使用DO
ZVSE
!?FU11233;
!!MA:Ax16/?y1;
!!VRy1:Sy1*10; VR 即变量,留在最后将,这里先用一下,我主要是演示同时改变所有的兵种攻击力翻十倍究竟需要多少代码
!!MA:Ax16/y1;
!#DO11233/0/196/1:P;
空行
效果如图:
好了,进入下一个环节
【I/E】
如果就,否则 —— 这就是介绍了老实说我没有想过这个功能这么简陋……
!!if&条件:;
!!el:;
!!en:;
!!如果满足条件
!!就执行这一系列工作
!!哪一系列呢
!!看你要执行多少行了
!!否则
!!执行另一个系列
!!另一个系列是什么呢
!!谁你便了
!!结束
I/E系列可以乱插入:
!!if&条件:;
!!if&条件:;
!!el:;
!!if&条件:;
!!el:;
!!en:;
!!en:;
!!el:;
!!if&条件:;
!!if&条件:;
!!el:;
!!en:;
!!el:;
!!en:;
!!en:;
意思应该很明显了,至于这个“&条件”究竟该怎么写,大多数时候是用来判断变量的值,所以介绍完变量你们也就知道该怎么写了
好了,进入下一个环节
【VR变量】
由于之前介绍到了一些,想必变量的概念多多少少还是有的吧
这里就要稍微详细一点介绍了
VR是对于变量进行操作的接收器在ERM中,变量本身存在,这点和正规的编程语言不同
那么,首先就介绍一下存在的所有变量:
变量的种类和它们的用途
所有的数字变量使用整数值且范围位于 -2147483647...+2147483647之间
a 不是一个变量
b 不是一个变量
c 增加“今天”的日期值
d 增加一个值
e1..e100 小数临时变量,可以输入小数,且计算时以小数表示
e-1...e-100 触发器的小数临时变量
从f到t 快捷变量
v1...v10000 标准变量
w1...w100 英雄变量(对于每个英雄都一组)
w101...w200英雄变量(对于每个英雄都一组),就像w1~100一样使用它们,除非是对于!!HT:W命令,你只能使用前100个。
x1...x16 函数变量(对于每一个函数触发器都有一组)
y1...y100 临时变量
y-1...y-100 触发器临时变量
z1...z1000 字符串变量(用于储存文本)
z-1...z-10 字符串临时变量(用于储存文本)
这一次的变量介绍也不打算告诉你们所有的变量种类究竟该怎么使用,用在哪个地方(本身我自己就不是太清楚)
主要目的是告诉大家这个事情大概就是这样的
好了,还记得我关于货车的类比么,这些不同类型的变量就是不同型号的货车,它们装运的货物不同
更重要的是,它们的运输范围也不同,例如两点一线的货车,例如城内运输,例如国际运输
这一次就拿最常用的变量:y 来结合VR说明一下
【VR&y】
关于VR,我并不打算介绍它所有的功能,也是只拿常用的介绍一下
其中有这么几个单字母很常用:S……
别吐槽我为什么只有S,因为用起来最简单也确实是最最常用的,偷懒神马的%……&*
!!VR#1:S#2; 针对整数变量
!!VR#1:S^#2^; 针对字符串变量
#1填入对应的变量,#2填入变量的内容,填错了自然也就报错了
差不多就是这个样子:
!!VRy1:S12; 设置临时变量y1的值为12
!!VRz1:S^yj3klr哦哦噢!^; 设置字符串变量z1的值为 yj3klr哦哦噢!
在字符串中插入整数:
!!VRz1:S^yj3klr哦%Y1哦噢!^; 设置字符串的变量z1的值为 yj3klr哦12哦噢! ,再次提醒,注意格式:%变量,变量的第一个字母要大写
【变量的对比】
= 等于> 大于
< 小于
>= or => 大于等于
<= or =< 小于等于
<> or >< 不等于
那么回到刚才&的话题,这里在帮助文档有解释:
4、在一个语句中使用多个条件:
当我们在一个命令中要使用多个条件时,需要将这些条件并列放到条件部分。格式从下:
1、在条件部分的最开头用一个” & ”作为前缀;
2、如果表示需要满足A和B条件,则用 ” / ” 并列,如果表示满足A或B条件,则用 ” | ” 并列;
3、可以用前缀” | “代替前缀” & ”,然后在后面的条件中使用” / ”并列,这样表示以下的所有条件都是“或”的关系。
拿!!IF:M^^;来举例
ZVSE
!?FU11233;
!!VRy1:S1;
!!VRy2:S2;
!!IF:M^y1=%Y1,y2=%Y2^; 显示y1、y2的值
!!IF&y1<y2:M^1***y1<y2***^; 当y1<y2的时候会弹出1号窗口
!!IF&y1=1/y2=2:M^2***y1=1 and y2=2***^; 当y1=1并且y2=2的时候会弹出2号窗口
!!IF&y1=1|y2=2:M^3***y1=1 or y2=2***^; 当y1=1或者y2=2的时候会弹出3号窗口
!!IF|y1=1/y2=2/y1>y2:M^4***y1=1 or y2=2 or y1>y2***^; 当y1=1或者y2=2或者y1>y2的时候会弹出4号窗口
!#FU11233:P;
空行
通过修改y1、y2的值,可以自行测试
【变量的域】
这是FU:P的示例1
- !?FU2;
- !!VRx2:Sx2+17;
- !!VRx3:Sx1+17;
- !?FU1;
- !!FU2:P13/?y-1/?y-2;
- !#IF:M^%Y-1,%Y-2^;
- !#FU1:P;
- !#IF:M^%Y-1,%Y-2^;
其结果显示16,30,实在令人想不通
首先,我读一遍
首先是y-1,y-2这两个变量,查看之前贴出来的列表,y-1~y-100都是触发器临时变量
这里的触发器临时变量和y1~y100域(即作用范围不同)不同,详细最后讨论
然后
!#IF:M^%Y-1,%Y-2^; 初始化弹出对话框,显示y-1、y-2的值
!#FU1:P; 初始化执行1号函数
- !?FU1; 1号函数
- !!FU2:P13/?y-1/?y-2; 执行2号函数,参数x1=13 , x2=?y-1 , x3=?y-2
- !?FU2; 2号函数
- !!VRx2:Sx2+17; 设置变量x2=x2+17=?y-1+17
- !!VRx3:Sx1+17; 设置变量x3=x1+17=13+17
!#IF:M^%Y-1,%Y-2^; 初始化弹出对话框,显示y-1、y-2的值
弹出了2次对话框,第一次0,0,第二次16,30
关于值的传递结果先不论,我得帮你们理清一下头绪,这到底是怎么传递的:
在这一步中:
- !?FU2; 2号函数
- !!VRx2:Sx2+17; 设置变量x2=x2+17=?y-1+17
- !!VRx3:Sx1+17; 设置变量x3=x1+17=13+17
FU2函数被调用,在此之前:
- !?FU1; 1号函数
- !!FU2:P13/?y-1/?y-2; 执行2号函数,参数x1=13 , x2=?y-1 , x3=?y-2
FU1函数里面并没有为y-1,y-2设置值,在次之前:
!#IF:M^%Y-1,%Y-2^; 初始化弹出对话框,显示y-1、y-2的值
!#FU1:P; 初始化执行1号函数
第一次弹出的对话框显示y-1,y-2的值为0,0,那么回到这一步:
- !?FU2; 2号函数
- !!VRx2:Sx2+17; 设置变量x2=x2+17=?y-1+17
- !!VRx3:Sx1+17; 设置变量x3=x1+17=13+17
!#IF:M^%Y-1,%Y-2^; 初始化弹出对话框,显示y-1、y-2的值
在FU2没有为y-1,y-2设置任何值的情况下,却由!#IF:M^%Y-1,%Y-2^;显示出了y-1,y-2的值为16,30
这就说明,肯定有地方设置了y-1,y-2的值
其实一开始就发现那个地方很奇怪了吧,为什么是?y-1,?y-2,而非y-1,y-2
这也就是说,很久以前我们学会的“读取”?变量在此处生效了,是不是找到了$这个符号的感觉?
我来进行一次读取过程的复述:
- !?FU2;
- !!VRx2:Sx2+17;
- !!VRx3:Sx1+17;
- !?FU1;
- !!FU2:P13/?y-1/?y-2;
- !#IF:M^%Y-1,%Y-2^;
- !#FU1:P;
- !#IF:M^%Y-1,%Y-2^;
这之中,!!FU2:P13/?y-1/?y-2; 这一个过程并非是给FU2:P设置参数,而是读取参数
准确的说,x1是设置13,而x2是读取值给y-1,x3是读取值给y-2
在函数FU2中
- !?FU2;
- !!VRx2:Sx2+17; 这里用VR给x2设置的值x2+17被y-1读取了,可是x2就是y-1,而y-1在此处赋值之前从未被赋值过,默认应该是0
- !!VRx3:Sx1+17; 这里用VR给x3设置的值13+17被y-2读取了
也就是说,按照期待,我们应当是判断第二次弹窗内容为17,30,然而真正的结果是16,30,非常诡异
从这里分析一下
- !!VRx2:Sx2+17; 设置变量x2=x2+17=?y-1+17 按道理来讲,x2=x2+17 之中x2=?y-1应该是0,
- 而这里?y-1+17却等于16,这就是说x2+17=16,所以x2=-1,而x2又对应?y-1,反应快的话就会发现:
- 如果此处写的是?y-16,那么x2就是-16,如果此处写的是?y-5,那么x2就是-5
- !!VRx3:Sx1+17; 设置变量x3=x1+17=13+17 按道理来讲,x3=30 这个值无误,在意料之内
得出的结论是:
!!FU2:P13/?y-1/?y-2; 此处的y-1,y-2不光会读取x2,x3,同时还会设置忽视掉“?变量首字母”之后剩下的数字给x2、x3
这是ERM语言很不严谨的地方
当然我要说的是,如果你们将通篇的y-1换成y1、y-2换成y2,那么两次弹窗的内容都将是0,0
这正是由于y1的域仅存在于每次的触发器之中,而y-1的域则存在于所有的函数之间,所以y-1才能用来作为函数间的设置&读取
【最后提一点Mods\WoG\Data\s中的erm文件的放置问题】
这其实是很简单的族谱关系
如果没有树,要怎么吃到树上的叶子?
erm文件开头都是ZVSE,结尾都有空行,但是其内容其实可以相互穿插:假如你将两个erm文件的内容合并到同一个文件中*(保证不混杂)那是没区别的
假如你在B.erm中编写了:
- ZVSE
- !?FU1;
- !!FU2:P13/?y-1/?y-2;
- !#IF:M^%Y-1,%Y-2^;
- !#FU1:P;
- !#IF:M^%Y-1,%Y-2^;
在A.erm中编写了:
- ZVSE
- !?FU2;
- !!VRx2:Sx2+17;
- !!VRx3:Sx1+17;
实际上和写在一起没区别,但是你要注意顺序,假如将刚才的内容于A、B两个文件中互换,你们就会发现弹窗为0,0,-1,-2
也就是说,A的字母排序先于B,所以A先诞生到了这个世界上,请联想亚当与夏娃,如果上帝不给亚当造一个夏娃,Make Love是不成立的
当然了,如果你给一个条件:
即,亚当被造出来之后,一旦满足数年之后上帝造出了夏娃,再执行Make Love的话就不会弹出-1,-2了
例如:
A.erm
ZVSE
!?FU1;
!!FU2:P13/?y-1/?y-2;
!#IF:M^%Y-1,%Y-2^;
!?PI; (这个玩意类似于!#,只是要晚一点点,这个时候大部分erm的重要设置都读取完了,当然也包括例子中的FU2)
!!FU1:P;
!!IF:M^%Y-1,%Y-2^;
B.erm
ZVSE
!?FU2;
!!VRx2:Sx2+17;
!!VRx3:Sx1+17;
告一段落,看情况要不要再教吧没人
[ 本帖最后由 清蒸猫锅 于 2013-2-1 20:44 编辑 ] |
|