---------------------------------------------------------------------------
写AI之前先说说语法之类跟计算机编程之类相关的东西。不过请放心,内容挺简单的。
因为Mugen本来就是给广大FTG爱好者一起玩的游戏引擎,所以其编写也是相当简单的。
另外学过计算机编程的同学这章可以看得快一点,毕竟很多都是学过的东西,注意一下某些跟C语言的区别就行了。
===========================================================================
3.1语法
===========================================================================
---------------------------------------------------------------------------
首先,分号;后面的是注释,也就是说;后面的东西是读不了的...
例子:
;例如这一句就是读不了的
;这一句也是...好神奇啊^ ^
分号前还是读得了 ; 分号后面就读不了了...T T
这句整句能读XD...好了不卖萌了
上面的例子计算机能读得到的就是“分号前还是读得了”和“这句整句能读XD...好了不卖萌了”,其他都读不到。
";"的用途主要是给自己/别人写注释,养成写注释的好习惯方便自己阅读,要不日后拿起来都不知道写了什么...
当然,有些不知道以后是否需要的代码,可以用";"把他们先屏蔽掉,以后有用再拿出来(这点很实用...)。
然后,要看一段语句是否运行,就要看里面的条件是否满足,也就是真或假。
与C语言相似,你的输入的值非0是真,0是假;系统返回值1是真,0是假。
呃,输入值和返回值是什么?
输入值是你告诉计算机的数值,而返回值是计算机处理一段代码后得到的结果,反过来告诉你。举些例子吧:
你告诉系统-1,不是0,系统就知道你说的是真,同理输入233也是真;
你告诉系统0,系统就知道你说的是假。
1+2=3,运算后系统发现这个是真,所以最后你得到一个1;
1+2=233,运算后系统发现这个是假,所以最后你得到一个0。
---------------------------------------------------------------------------
紧接着就是讲状态控制器(state controller或sctrl)和触发器(trigger)的格式了。
Cmd、St和Stcommon三种文件里都经常看到一种写法:
例子,Cmd里KFM的站轻拳(因为详细的trigger还没看过所以右边有文字注释):
;Stand Light Punch
[State -1, Stand Light Punch]
type = ChangeState;改变状态
value = 200;改变状态的值为200
triggerall = command = "x";按x键
triggerall = command != "holddown";没有按着↓键
trigger1 = statetype = S;站姿
trigger1 = ctrl;处于可控状态
trigger2 = stateno = 200;状态号为200
trigger2 = time > 6;时间大于6
其模板为:
[State XX, ...]
type = XXX
value = XXX
triggerall = ...
trigger1 = ...
trigger1 = ...
trigger2 = ...
trigger2 = ...
...
triggerN = ...
而这个模板就是sctrl的模板。
[State XX, ...]是整段的开始,其实没啥用途,但是你不能去掉...囧
XX其实可以随便填的,不过通常写在[Statedef XX]里就填XX,方便日后debug,例子中Cmd是[Statedef -1]。
中括号里逗号后面的省略号是文字注释,不影响运行。
type是你要做的事件类型,比如说例子里面ChangeState(即改变状态),
value是你要赋予的值,比如说例子里面就是200,
例子中结合type和value来看,就是改变状态到200号动作,即变为站轻拳。
紧接着就是一大串的trigger,即触发器,满足条件就触发这个状态控制器的事件,
学过编程的朋友可以理解为if语句。
trigger是按数字排序,编号为数字从1到N,按顺序从小到大检测是否满足,
一旦满足同编号trigger马上执行同数字的trigger要同时全部满足才算满足(当然同数字的只有一个的话只看那个就行了)。
如例子中trigger2就是状态号是200而且时间大于6两个条件同时满足才触发trigger2。
不过有一个特例,triggerall,是所有情况都需要满足的trigger,否则就不执行。
例子当中triggerall为你按x而且你没有按着向下方向键↓,否则下面的trigger1和trigger2满足了也没用。
如果从逻辑角度上来说,trigger的运作就是:
满足triggerall 而且 ( 满足全部trigger1
或者 满足全部trigger2
或者 ......
或者 满足全部triggerN)
另外trigger在Winmugen里有长度限制,太长会报错,但是貌似Mugen1.0里面没有。
反正就是不要写太长(不过初学者应该不会写得很长的)。
还有要注意至少要有一个后缀为数字的trigger(也就是trigger1),只有triggerall的话会报错哦。
...什么还是看不懂?引用四娘语录:
type =
吃饭
(干什么)
type =
value =
吃“一碗”饭
(量)
type =
trigger1 =
value =
“在中午”吃一碗饭
(什么时候)
果然四娘就是四娘简单暴力直接易懂的吃饭教学请允许在下跪拜OTL
---------------------------------------------------------------------------
语法例子若干:
继续使用上面的例子:
;Stand Light Punch
[State -1, Stand Light Punch]
type = ChangeState;改变状态
value = 200;改变状态的值为200
triggerall = command = "x";按x键
triggerall = command != "holddown";没有按着↓键
trigger1 = statetype = S;站姿
trigger1 = ctrl;处于可控状态
trigger2 = stateno = 200;状态号为200
trigger2 = time > 6;时间大于6
1.有按x键和↓键,站姿,处于可控状态,状态号不为200,时间大于6
满足command = "x",不满足command != "holddown",所以不满足triggerall,下面全部不满足trigger
2.有按x键,没有按着↓键,站姿,处于可控状态,状态号不为200,时间大于6
满足triggerall,满足所有trigger1,所以满足trigger,执行
3.有按x键,没有按着↓键,蹲姿,处于可控状态,状态号为200,时间大于6
满足triggerall,蹲姿不满足trigger1,满足trigger2,所以满足trigger,执行
4.有按x键,没有按着↓键,蹲姿,处于可控状态,状态号不为200,时间大于6
满足triggerall,但不满足trigger1和trigger2,不满足trigger,所以不执行
好,语法其实就是这么多,Cmd、St和Stcommon基本都是以这个格式写的。
其实前半部分是Sctrl,后半部分就是trigger。
做AI能用到的Sctrl的类型其实也只有ChangeState等为数不多的几种,
当然要做人物的话就要用到各种各样的type,不过在AI教程里面就不予赘述了。
trigger倒是需要多知道一些,毕竟写AI要考虑各种各样不同情况。
至于常用Sctrl与trigger,笔者会在下章讲。
想了解更多的建议多看看trigger表和Sctrl表,里面解释的挺清楚的。
===========================================================================
3.2运算符与表达式
===========================================================================
---------------------------------------------------------------------------
运算符就是各种各样的运算符号,跟数字之类的结合成为表达式。
毕竟mugen里面的AI还是与数学和计算机密切相关的,这些基础的东西还是要提及一下。
---------------------------------------------------------------------------
括号
( ) 括号,括号内优先运行,跟数学里的意义基本一样,不多说了
此外,有时在语句长、逻辑关系十分混乱或语句有歧义时,用括号分段会有很好的效果
---------------------------------------------------------------------------
算术运算符
+ - * / 加减乘除这四个就不解释了- -...不懂的朋友建议重新读小学XD...
% 取余,A % B,例如5 % 2余数就是1
** 乘方,A ** B,就是A的B次方,需要注意的是winmugen里面乘方运算有BUG,1.0被修复,使用时小心
---------------------------------------------------------------------------
逻辑运算符
! NOT,非,表示否定,!A,真假颠倒,即真的变成假,假的变成真
&& AND,并且,A && B,AB同时为真才为真,否则为假
|| OR,或者,A || B,AB同时为假才为假,否则为真
^^ XOR,异或,A ^^ B,AB只有一个为真才为真,否则为假
---------------------------------------------------------------------------
关系运算符
= 等于号,A = B,当AB同为整型或浮点型且相等的时候为真,否则为假。
!= 不等于号,A != B,当AB同为整型或浮点型且不相等的时候为真,否则为假。
< 小于号,A < B,当两边同为整型或浮点型且A小于B的时候为真,否则为假。
<= 不大于号,与小于号相似,A = B时亦为真
> 大于号,A > B,当两边同为整型或浮点型且A大于B的时候为真,否则为假。
>= 不小于号,与大于号相似,A = B时亦为真
以上判断大小关系运算符,若AB类型不同,系统会自动转化为浮点型再比较
=[,] 以下的都是A “=或!=” “[或(” B,C “]或)” 的形式,例如X=[Y,Z],表示区间
!=[,] 嘛,集合是高一数学的内容(我应该没记错吧...)
=[,) =和!=我就不多说了,[]是闭区间,包含区间端点,()是开区间,不包含区间端点,另外B <= C
!=[,)另外请注意这八种区间的表达如果不是用在这行的末端,会造成语句歧义而报错
=(,]解决方法是加括号,例:Trigger1 = (Power = [1000,2000]) && Life < 300
!=(,]
=(,)
!=(,)
---------------------------------------------------------------------------
赋值运算符
:= 赋值号,用于赋予变量值,以后讲到变量Var和浮点变量FVar再提及
---------------------------------------------------------------------------
二进制运算符
没学过二进制的朋友可能会比较难理解,而且应用面不广,这部分选读即可(拓展内容www)。
我们平时生活中应用的数字是十进制,数字从0~9一个十个数字,每逢十个就进一位。
二进制就是只由0和1两个数字组成,每逢两个就进一位,在计算机当中有广泛运用(用0/1表示关/开非常方便)。
例如十进制的6 = (2^2)*1 + (2^1)*1 + (2^0)*0 -> 二进制的110(1个2的2次方 加 1个2的1次方 加 1个2的0次方)。
mugen里面的运用多数用于大量的布尔型数据(即真或假)的储存,
注意进行二进制计算请用整型
! NOT,非,表示否定,!A,真假颠倒,即真的变成假,假的变成真
& AND,并且,A & B,AB同时为真才为真,否则为假
| OR,或者,A | B,AB同时为假才为假,否则为真
^ XOR,异或,A ^ B,AB只有一个为真才为真,否则为假
二进制的逻辑其实就是每个数位独立出来运算...
还是举个两个例子吧(下面的^符号代表数学运算中的乘方运算)...
6&5其实等价于((2^3)*0 + (2^2)*1 + (2^1)*1 + (2^0)*0) & ((2^3)*0 + (2^2)*1 + (2^1)*0 + (2^0)*1)
6|5其实等价于((2^3)*0 + (2^2)*1 + (2^1)*1 + (2^0)*0) | ((2^3)*0 + (2^2)*1 + (2^1)*0 + (2^0)*1)
0110
& 0101
--------
0100
一共四个字节,只有第三个字节是上下同为1,所以只有第三个字节是1,其他是0
返回((2^3)*0 + (2^2)*1 + (2^1)*0 + (2^0)*0) = 4
0110
| 0101
--------
0111
一共四个字节,只有第四个字节是上下同为0,所以只有第四个字节是0,其他是1
返回((2^3)*0 + (2^2)*1 + (2^1)*1 + (2^0)*1) = 7
---------------------------------------------------------------------------
运算符优先级
优先级从上到下排列,同一行的是同级运算。
如果同级的运算是按从左到右次序进行,多层括号由里向外。
! ~ -(负号)
**
* / %
+ -(减号)
> >= < <=
= !=
:=
&
^
|
&&
^^
||
---------------------------------------------------------------------------
表达式例子若干:
1.1
直接返回1,为真
2.1 && 0 || 1
根据运算符优先级可知,先考虑1 && 0,返回0;再考虑 0 || 1,返回1
3.1 + 1 = 2 && 1 + 2 != 3
根据运算符优先级可知,先考虑1 + 1 = 2,再考虑1 + 2 != 3,最后考虑两个的式子的关系
1 + 1 = 2为真,返回1;
1 + 2 != 3为假,返回0;
1 && 0为假,返回0
===========================================================================
课后作业:
1.
!((5 % 2) || (1 >= 2) && ((1 ** 233 + 2) * 3 != 10086) && (1 = [0,2)) && 0)
按步骤分析上述表达式并写出过程
2.
[State 233, 莫伸手]
type = 伸手党处理方法
triggerall = LZ伸手
trigger1 = 帖子问题与精品贴中某教程帖吻合
trigger1 = LZ没翻过置顶/精品贴
trigger2 = 借话题水
triggerX = YYY
value = ifelse(吧务心情不好, 删帖, 不删放着让大家水)
分别给以下两种情况,赋予YYY适合的触发条件
a). X = 2
b). X = 3
3.
如何利用二进制运算符有效地储存布尔型数据?理论上可以储存多少个布尔型数据?
附加题,难度较大,对二进制运算感兴趣的同学可以试试,不过对计算机专业的朋友来说应该是小菜一碟-w-
以上教程由口水轩撰写