发信人: dennyzeng2() 
整理人: metalsolo(2001-08-02 17:16:23), 站内信件
 | 
 
 
III.e.2 Triggers
 ----------------
 
 i. Trigger逻辑
 
 第一个trigger一般是"trigger1",接着是"trigger2"、"trigger3"这样下去。
 决定controller激活的逻辑是:
 1. "trigger1"的条件是否为真?如果是,就yes,激活controller。
 2. 否则,接着测试"trigger2,",这样下去直到找不到更多的triggers。
 这之间可以被看作逻辑运算"OR"。
 
 小心!不连续的numbers会引起某些trigger被忽略。例如,如果有这些triggers:
 "trigger1"、"trigger2"和"trigger4"而没有"trigger3"。"trigger4"就会被忽略。
 
 如何让controller被激活需同时满足更多的条件呢?这里有一个常用的例子:测试
 在空中的人物是否到达地面。Triggers是:
 trigger1 = Vel Y > 0 ; 如果Y-velocity>0为真(往下动作)
 trigger1 = Pos Y > 0 ; 如果Y-position>0为真(低于地面)
 在这点上,不要被trigger的格式困惑。我们马上讲这部分。
 两个triggers是同样的号码。当几个triggers是同样的号码时,是执行逻辑
 运算"AND"。那就是说,controller中所有编号相同的trigger都满足时才为true。
 就算是有一个条件不满足就是false。
 
 这两个观念可以结合起来使用。例如:
 trigger1 = Vel Y > 0 ; 如果Y-velocity>0为真(往下动作)
 trigger1 = Pos Y > 0 ; 如果Y-position>0为真(低于地面)
 trigger2 = Time = 5 ; 如果state-time是5为真
 这controller将在人物着陆地面(Y-velocity和Y-Position都>0),或者state-time
 走到5。
 
 这里是摘要:
 - 相同编码的triggers仅在都是真时才激活controller。
 - 相同编码的triggers当一个或多个为真时就激活controller。
 
 Trigger的格式是:
 trigger? = trigger类型 条件表达式
 trigger类型是trigger的名字(请看triggers.txt中的完全列表)。
 
 条件表达式时一个检查是否为0的算术表达试。如果条件表达式为0,这trigger
 就是false。如果条件表达式是非0,trigger就是true。条件表达式一般都是象
 上面一样的简单相关表达式,但是可以根据需要写成简单和复杂的。
 
 可以在表达式中采用逻辑运算符。例如,这跟上面那段的效果是相同的。
 trigger1 = ((Vel Y > 0) && (Pos Y > 0)) || Time = 5
 请看exp.txt(表达式文件)中对算术表达式的详细解释。
 
 有一个有用的捷径就是用"triggerall"。这表明所有的trigger都必须同时满足
 它的条件才能为真,例如:
 
 triggerall = Vel X = 0
 trigger1 = Pos Y > -2
 trigger2 = AnimElem = 3
 trigger3 = Time = [2,9]
 
 在检测trigger1到trigger3时,triggerall的条件也要满足。
 condition must be true too. 照这样,当X-velocity不是0,state controller
 就不会激活。你只要需要,可以设定更多的triggerall条件。要注意的是至少要有
 一个trigger1存在,即使triggeralls都表达了。
 
 ii. Trigger持续效果
 
 如果是这种情况:你不想让每次trigger为真时都激活controller。你就要使用
 "persistent"参数。让我们从例子开始:
 
 [State 310, 1]
 type = PosAdd
 trigger1 = Vel Y > 1
 x = 10
 
 本state controller使P1当他的Y-velocity大于1时每tick向前移动10个象素。
 那就是说,所有满足trigger条件的时候,controller都要运行。如果要让
 controller只运行一次,就要加一行:
 
 [State 310, 1]
 type = PosAdd
 trigger1 = Vel Y > 1
 persistent = 0 ;<--加这行
 x = 10
 
 "Persistent"的默认值是1。意思是无论何时只要trigger为true,controller
 就要激活。把"persistent"设成0就使controller在本State里,满足条件的情
 况下只激活运行一次。这会保持到P1离开该state。如果P1以后再回到这个
 state,controller还是只能运行一次。
 
 参数"persistent"还能取0和1以外的数:
 
 [State 310, 1]
 type = PosAdd
 trigger1 = Vel Y > 1
 persistent = 2 ;<--改这行
 x = 10
 
 这种情况下,设定"persistent"意思是controller会在每两次trigger为true时
 运行一次。设为3就每三次满足条件激活一次controller,等等。
 
 iii. Trigger重定向
 
 可以检测人物攻击对象(target)的,和人物的主体(parent,如果人物是个援助)
 的statetime等。
 真是惜墨如金啊,能用哪些trigger也不提,难道都能用吗?这是0414版在本文件
 中新提到的。我也是最近才得Kyoung兄告知的。希望以后版本能详细说一下。不
 要弄成不传之秘啦。大致的用法是trigger1 = Target,Vel Y > 1这样。
 
 
 III.e.3 常用controllers
 ---------------------------------
 
 Controller—Null是在调试中用的。Controller—Null基本上什么也不做。你
 可以用它来临时关闭某个controller,用以代替在每行头上加分号。
 例如,你要让这个暂时失效:
 
 [State 300, 1] ;使P1向前加速的Controller
 type = VelAdd
 trigger1 = Time >= 0
 x = .8
 
 注释掉VelAdd,加上null:
 
 [State 300, 1] ;使P1向前加速的Controller
 type = null ;VelAdd
 trigger1 = Time >= 0
 x = .8
 
 以后要重新使其恢复功能的话就可以改回来。
 
 现在注意这个例子:
 
 [Statedef 200]
 type = S
 physics = S
 movetype = I
 ctrl = 0
 anim = 200
 velset = 0
 
 [State 200, 1]
 type = ChangeState
 trigger1 = AnimTime = 0
 value = 0
 ctrl = 1
 
 [State 200, 1]用了controller—ChangeState。顾名思义,是改变P1的state号
 的。参数value指出转向的State号。可选参数ctrl使P1的control标记改变。
 
 现在让我们做一个攻击State。首先,animation要有撞击块(collision boxes)。
 对air文件的一个快速复习:Clsn1是攻击的而Clsn2是人物哪里是可被攻击的。
 所以P1打中了P2是当P1的Clsn1块和P2的Clsn2块交叠。
 
 举个例子,假定P1 AIR文件中的animation action是这样的:
 
 [Begin Action 200]
 200,0, 0,0, 3
 200,1, 0,0, 4
 200,2, 0,0, 4
 200,3, 0,0, 3
 
 设定了范围后,看起来是这样:
 
 [Begin Action 200]
 Clsn2: 1
 Clsn2[0] = -10,0, 10,-80
 200,0, 0,0, 3
 Clsn1: 1
 Clsn1[0] = 10,-70, 40,-60
 Clsn2: 2
 Clsn2[0] = -10, 0, 10,-80
 Clsn2[1] = 10,-70, 40,-60
 200,1, 0,0, 4
 Clsn2Default: 1 ;最后两个element都用这个块
 Clsn2[0] = -10,0, 10,-80
 200,2, 0,0, 4
 200,3, 0,0, 3
 
 如你所见,每个element都有Clsn2块设定(最后两个element都用同一块)。
 第二个element是唯一有Clsn1块的。
 
 注意:Animation Action里每个element都加上Clsn1块也没关系。但是你把
 Clsn1块放在第一个element上,攻击就会变得瞬间启动,由此变的不可阻挡。
 所以,建议把Clsn1块放在以后的elements上。
 方可也碰到过这种情况,但是就我的经验来看。如果该State的movetype=A,
 该情况是不存在的。但当movetype=I时,P2即使ctrl=1又按了后向也来不及
 防御,从而变的不可阻挡。但是P2可以挡Clsn1块在以后element的攻击。
 具体事实如何,方可暂时无法印证,但请大家注意这一点,别作出赖招来啊。
 
 现在准备设置CNS中的State。我们会解释以下的修改。
 
 [Statedef 200]
 type = S
 physics = S
 movetype = A ;<--从"I"改到"A"
 ctrl = 0
 anim = 200
 velset = 0
 
 [State 200, 1] ;<--加上这个state controller
 type = HitDef
 trigger1 = AnimElem = 2
 attr = S, NA
 animtype = Light
 damage = 10
 guardflag = MA
 pausetime = 12,12
 sparkxy = 0,-55
 hitsound = 5,0
 guardsound = 6,0
 ground.type = High
 ground.slidetime = 12
 ground.hittime = 15
 ground.velocity = -5
 air.velocity = -2.5,-3.5
 
 [State 200, 2]
 type = ChangeState
 trigger1 = AnimTime = 0
 value = 0
 ctrl = 1
 
 StateDef里的参数movetype设成"A"是"attack"。记得在所有攻击state里做一下。
 正如以前,P1最后回到站立state。
 
 Controller--HitDef看起来象个大怪物!别担心,我们慢慢过他一遍。
 
 L1: type = HitDef(L1就是里面第一行的意思,下同)
 L2: trigger1 = AnimElem = 2
 指定的controller是"HitDef",代表"Hit Definition"(攻击定义)。在animation
 的第二个element触发。任何Clsn2块在这个"攻击定义"触发时起作用。(是Clsn1块
 吧)例如,假使人物在animation的第二、三个element都有Clsn1,在第二个element
 引发一个HitDef适用于这两个element。P1会打中至多一次:第二个element打中,
 第三个就miss。第二个element miss了,第三个还可以打中。要两个element都能打
 中就要对两个各做一个trigger。
 就是
 trigger1 = AnimElem = 2
 trigger2 = AnimElem = 3
 
 L3: attr = S, NA
 这是攻击的属性(attribute)。决定该攻击能否打到P2。本例中,是站立(S)普通
 (N)ormal攻击(A)ttack。
 "attr"的格式:
 attr = arg1, arg2
 Where:
 - arg1任为"S","C"或"A"。同StateDef的"statetype"一样,表明是在什么状态下
 的攻击。是站立,蹲态还是空中攻击。
 - arg2是双字节字符串。第一个字符是"N"普通攻击,"S"是必杀技,或"H"超必杀技
 中任一个。
 第二个字符是"A"攻击(打击式的攻击),"T"投技,或"P"飞行道具。
 
 L4: animtype = Light
 这设定如果P2遭到该攻击的效果。可选值"light","medium","hard"或"back"。
 因为作者没有更新这一段,其实现在有更多选择。详见sctrl.txt。
 
 L5: damage = 10
 P2如果遭到该攻击的伤害值。现在被防是不损血的。如果写成"damage = 10, 1",
 被防住的话也会损1点血。
 
 L6: guardflag = MA
 "Guardflag"决定P2在什么状态下可以防住这个攻击。本例是高段(站立),低段
 (蹲下)和在空中。选择为包含以下字符的字符串:"H"高段,"L"低段或"A"空中。"M"
 (mid)等同于"HL"。
 
 L7: pausetime = 12,12
 这是攻击成功双方的停滞时间。第一个值是使P1停顿的,单位为game-ticks。第二个
 值为P2在被攻击弹出前的震动时间。
 
 L8: sparkxy = 0,-55
 产生攻击/防御火花的位置。要以"x,y"的格式。x相对于P2的前方。负的x会令火花
 更深入P2。y相对于P1。负的y火花更高。
 
 L9: hitsound = 5,0
 L10: guardsound = 6,0
 这两段是播放攻击效果音。原文说是放fight.snd里的声音,要放你自己文件的要在
 值前加S,其实现在不加也默认为是你的文件里的。特别申明是fight.snd的在值前
 加F。
 
 L11: ground.type = High
 地面攻击的话攻击的类型(如果没有设"air.type = ?"则也设定空中攻击类型。本例中,
 是高段攻击。选择"High"会让P2被打得头后仰,"Low"的效果是打中P2的腹部,
 "Trip"是扫腿攻击,"None"是P2没有反应。
 如果的AnimType是"Back",P2对"High"和"Low"攻击的反应是一样的。
 
 L12: ground.slidetime = 12
 P2受到攻击后向后滑行的时间(game-ticks)(不包括pausetime)。只要P2在地上就有效。
 
 L13: ground.hittime = 15
 P2受到攻击后处于被击状态的时间。只要P2在地上就有效。
 
 L14: ground.velocity = -5
 P2受到攻击后的初速度。只要P2在地上就有效。也可以指定Y-velocity为第二个参数。
 使其被击向空中。例如:
 "ground.velocity = -3, -2"。
 
 L15: air.velocity = -2.5,-3.5
 P2受到攻击后的初速度。如果P2在空中被击。
 
 这是HitDef的一部分。Sctrls.txt里有详细内容。
 
  | 
 
 
 |