6.11 代码效率

处理表达式不是向电脑收费,所以你代码的可读性比微优化表达式更重要.
然而,下面的某些好的做法将提高效率同时不影响最终的效果.

MUGEN在状态控制器中计算条件型触发器遵循如下原则:
首先计算triggerall,从上到下顺序计算.
如果任何triggerall计算出0,则剩余的触发器将被跳过且将计算下一个控制器.
如果所有triggerall计算结果都是非0,则引擎开始计算trigger1,也是从上到下顺序计算.
如果它们中任何一个计算出0,则跳过所有剩下的trigger1转而计算第一个trigger2,诸如此类等等.
如果一个块中的所有trigger(除了triggerall)都计算出非0,则将开始计算状态控制器参数且控制器被触发.

换句话说,触发器计算的逻辑是类似短路型的.在类似C语言的标记法中,这种方式也许被记为
triggerall,1 && triggerall,2 && ... && ((trigger1,1 && trigger1,2 && ...) || (trigger2,1 && trigger2,2 && ...) || ... )
这里 trigger1,2 记作 trigger1 第2行; trigger2,1 记作 trigger2 第1行,等等.
这个trigger组的逻辑计算将是短路型的,就像C一样.

(注:通过那个逻辑关系式,表示了triggerall组与后面trigger1,trigger2等所有组关系是'&&',也就是说只要triggerall组一个是0,就不能触发.
通俗说法就是triggerall里面只要有1个是0就不能触发,要触发必须triggerall全部非0.
逻辑关系式还能看出trigger1组和trigger2组...之间都是'||',也就是这些组中只要有一个组为1就能触发(前提是triggerall已经检测为非0.)
而在每个trigger组中,他们之间的关系是'&&',比如trigger1组中,要保证trigger1的情况下触发,必须每个trigger1都非0.
控制器被触发的通俗说法就是:首先每个triggerall都要非0,然后每个 triggerN组 中最少要有1个非0,triggerN组 要非0,必须每个triggerN都非0. )

由于这个系统,可以通过 组织好表达式以便条件型触发器里的数字尽可能的即小又少 来实现大大提高效率.
状态控制器参数可以减少工作量(代码量),这些参数在触发时仅计算一次,而不是玩家在状态中每帧都计算.例如

[State -1]
type = ChangeState
trigger1 = command = "a"
trigger1 = power < 1000
value = 3000

[State -1]
type = ChangeState
trigger1 = command = "a"
trigger1 = power >= 1000
value = 3001

[State -1]
type = ChangeState
trigger1 = command = "a"
trigger1 = power >= 2000
value = 3002
可以进一步简化为:

[State -1]
type = ChangeState
trigger1 = command = "a"
value = 3000 + (power >= 1000) + (power >= 2000)
你同时能为引擎排忧解难,通过把最容易计算出false的triggerall放在triggerall块的顶部.(可以减少引擎计算量)
同样,trigger1块应该是最可能被触发的块,但是在trigger1块内部,最有可能计算出0的trigger1应该放置在顶部.
对于有很多包含重复条件trigger的状态控制器,最好将这个控制器打断为2个独立的块,每个块独立设置triggerall.

如果你有一个复杂的条件,这个条件是许多连续状态控制器的触发条件,你可以把这个条件的值存储到一个变量中,然后把这个变量作为后面触发器的控制条件.
例如:

trigger1 = (command="abc" && command!="holddown" && power>=1000) || (command="abc" && command!="holddown" && var(5)) || ((command != "abc" || command = "holddown") && power>=2000)
可以被写成 (直接给 var(0) 赋值是可行的):

trigger1 = (var(0):=(command="abc" && command !="holddown") && power>=1000) || (var(0) && var(5)) || (!var(0) && power>=2000)
这里,你必须权衡提高可读性.(在使用子表达式和使用:=运算符这两种情况中权衡,这2种情况都会降低可读性)
(或者使用varset控制器:
[State -1]
type = varset
...
var(0) = command="abc" && command !="holddown"
然后:
trigger1 = var(0)&&power>=1000 || var(0)&&var(5) || !var(0)&&power>=2000
由于&&运算等级高于||,所以这么写不违背原意.)