2016.12.2202:59

AI 立回技巧相关(Part.2)

Episode 11 立回技巧相关(Part.2)

最近沉迷屁股所以没时间更新了_(:3」∠)_

接着上一篇来讲,上一篇我们谈到了立回中如何对应大部分地波的记忆办法,记忆解决办法就是记录下地波的状态号和帧数和距离来确定大跳抓硬直,这次我们看看如何对应投技和当身问题(因为不想分第三块来讲就干脆搁到一起来说了)

方法和之前的办法是一样的,大家要做的事情就是实验和思考如何去正确的使用,当然如果是单人战的话没有必要考虑那么多,如果是双人对打那么就要考虑一下了,有时候你跳一下就可能成为一个很大的破绽,这样会给你的队伍带来很大的不利

先说投技,我们先要做的事就是把投技给记录下来,当然一般只记录平地投,对于投技一般有个特点就是无法抓空中对象(对正常向来说,如果是魔改(对某些人来说)请自重!),那么解决办法就是起跳然后JABCD或者空中特殊技等技能来抓破绽硬直(如果投技全程无敌也请自重)

;----------------------------------------------------------------------
[State 33000, Null]
Type = Null
TriggerAll = Time = 0
Trigger1 = var(20) := -1
Trigger1 = var(21) := -1
Trigger1 = var(22) := -1
Trigger1 = var(23) := -1
Trigger1 = var(24) := -1
Trigger1 = var(25) := -1
Trigger1 = var(26) := -1
Trigger1 = var(27) := -1
Trigger1 = var(28) := -1
Trigger1 = var(29) := -1
IgnoreHitPause = 1

;----------------------------------------------------------------------
;敵に投げステート記憶
;----------------------------------------------------------------------
[State 33000, VarSet]
Type = VarSet
Trigger1 = EnemyNear(Root,var(58)),Ctrl = 0 ;敌方不可控记录
Trigger1 = EnemyNear(Root,var(58)),MoveType = A ;显示判定为攻击
Trigger1 = EnemyNear(Root,var(58)),HitDefAttr = SC,NT,ST,HT ;所有投技
Trigger1 = Helper(33000+Root,ID),var(20) = -1
var(20) = EnemyNear(Root,var(58)),StateNo ;记下状态号
IgnoreHitPause = 1

......(方法和以前一样我就不再重复了)

[State 33000, VarSet]
Type = VarSet
Trigger1 = EnemyNear(Root,var(58)),Ctrl = 0
Trigger1 = EnemyNear(Root,var(58)),MoveType = A
Trigger1 = EnemyNear(Root,var(58)),HitDefAttr = SC,NT,ST,HT
Trigger1 = EnemyNear(Root,var(58)),StateNo != Helper(33000+Root,ID),var(20)
Trigger1 = EnemyNear(Root,var(58)),StateNo != Helper(33000+Root,ID),var(21)
Trigger1 = EnemyNear(Root,var(58)),StateNo != Helper(33000+Root,ID),var(22)
Trigger1 = EnemyNear(Root,var(58)),StateNo != Helper(33000+Root,ID),var(23)
Trigger1 = EnemyNear(Root,var(58)),StateNo != Helper(33000+Root,ID),var(24)
Trigger1 = EnemyNear(Root,var(58)),StateNo != Helper(33000+Root,ID),var(25)
Trigger1 = EnemyNear(Root,var(58)),StateNo != Helper(33000+Root,ID),var(26)
Trigger1 = EnemyNear(Root,var(58)),StateNo != Helper(33000+Root,ID),var(27)
Trigger1 = EnemyNear(Root,var(58)),StateNo != Helper(33000+Root,ID),var(28)
Trigger1 = Helper(33000+Root,ID),var(20) != -1
Trigger1 = Helper(33000+Root,ID),var(21) != -1
Trigger1 = Helper(33000+Root,ID),var(22) != -1
Trigger1 = Helper(33000+Root,ID),var(23) != -1
Trigger1 = Helper(33000+Root,ID),var(24) != -1
Trigger1 = Helper(33000+Root,ID),var(25) != -1
Trigger1 = Helper(33000+Root,ID),var(26) != -1
Trigger1 = Helper(33000+Root,ID),var(27) != -1
Trigger1 = Helper(33000+Root,ID),var(28) != -1
Trigger1 = Helper(33000+Root,ID),var(29) = -1
var(29) = EnemyNear(Root,var(58)),StateNo
IgnoreHitPause = 1

像这样,该helper内的var(20)~var(29)就负责记录10个投技状态,接下来要做的就是AI部分,考虑对策优先,对策部分先写上方,然后下面记录一般对策,所有关于投技对策的AI部分全部写在AI较为上面的部分,也就是优先的意思,在那之前,先算好你小跳的时间,比如小跳是18,中影跳是25,那么小跳的时间是小于中影跳的

;-----------------------------------------------------------------------
; 相手の特殊ステート(投げ)記憶
;-----------------------------------------------------------------------
[State -3, VarSet]
Type = VarSet
Trigger1 = fvar(8) != 0
FV = 8
Value = 0
IgnoreHitPause = 1

[State -3, 相手の特殊ステート]
Type = Null
TriggerAll = var(59) = 1
TriggerAll = NumHelper(33000+ID)
TriggerAll = EnemyNear(var(58)),MoveType = A
Trigger1 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(20)
Trigger1 = fvar(8) := fvar(8) + 1 || 1
Trigger2 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(21)
Trigger2 = fvar(8) := fvar(8) + 1 || 1
Trigger3 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(22)
Trigger3 = fvar(8) := fvar(8) + 1 || 1
Trigger4 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(23)
Trigger4 = fvar(8) := fvar(8) + 1 || 1
Trigger5 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(24)
Trigger5 = fvar(8) := fvar(8) + 1 || 1
Trigger6 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(25)
Trigger6 = fvar(8) := fvar(8) + 1 || 1
Trigger7 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(26)
Trigger7 = fvar(8) := fvar(8) + 1 || 1
Trigger8 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(27)
Trigger8 = fvar(8) := fvar(8) + 1 || 1
Trigger9 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(28)
Trigger9 = fvar(8) := fvar(8) + 1 || 1
Trigger10 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(29)
Trigger10 = fvar(8) := fvar(8) + 1 || 1
IgnoreHitPause = 1

像这样先记录下到一个var内,然后这个var不为0的时候代表对面是被记录下来的投技

[State -3, 小、中ジャンプ隙突き(対投げ用)]
Type = ChangeState
Value = ifelse(Abs(EnemyNear(var(58)),Pos X - Pos X) > D,(前中影跳state),ifelse(Abs(EnemyNear(var(58)),Pos X - Pos X) > C,(前小跳state),(上小跳state))) ; C < D,当然这个只是举例子,如果你喜欢用中影跳的话也没关系
TriggerAll = var(59) = 1
TriggerAll = RoundState = 2
TriggerAll = StateType != A
TriggerAll =!EnemyNear(var(58)),Ctrl
TriggerAll = EnemyNear(var(58)),StateType != A
TriggerAll = EnemyNear(var(58)),StateType != L
TriggerAll = EnemyNear(var(58)),MoveType = A
TriggerAll = EnemyNear(var(58)),StateNo >= 200
TriggerAll = EnemyNear(var(58)),AnimTime < -18
TriggerAll = EnemyNear(var(58)),HitDefAttr = SCA, NT, ST, HT || (fvar(8) != 0) ;代表记录下来的投技和检测到的投技(双保险)
TriggerAll = EnemyNear(var(58)),Time >= 50-var(59)*5 || var(59) > 9
TriggerAll = EnemyNear(var(58)),Facing != Facing || EnemyNear(var(58)),Facing = Facing && var(51) = 5 ;有关var(51)我在前面的双打部分提到过,var(51) = 5代表背后有敌人,也就是说是被夹击的状态,保持这种状态去攻击被对你的敌人可以救你的队友
TriggerAll = Ctrl || (StateNo = [20,22]) || (StateNo = [100,101]) || (StateNo = [120,149])
Trigger1 = Abs(EnemyNear(var(58)),Pos X - Pos X) = [A,B]

[State -3, バックステップ 投げ外し]
Type = ChangeState
Value = 105 ;代表44的意思,有些角色44下可以进行出招
TriggerAll = var(59) = 1
TriggerAll = RoundState = 2
TriggerAll = StateType != A
TriggerAll = BackEdgeBodyDist >= 30 ;只要不在墙角就行,如果你想跳离墙角的话就用大跳或者其他无敌闪避技能
TriggerAll =!EnemyNear(var(58)),Ctrl
TriggerAll = EnemyNear(var(58)),Vel Y >= 0 ;代表对手在平地的意思(大概不会有钻地龙吧)
TriggerAll = EnemyNear(var(58)),HitDefAttr = SCA, NT, ST, HT || (fvar(8) != 0)
TriggerAll = EnemyNear(var(58)),Time >= 50-var(59)*5 || var(59) > 9
TriggerAll = EnemyNear(var(58)),Facing != Facing || EnemyNear(var(58)),Facing = Facing && var(51) = 5
TriggerAll = Ctrl || (StateNo = [20,22]) || (StateNo = [100,101]) || (StateNo = [120,149])
Trigger1 = Abs(EnemyNear(var(58)),Pos X - Pos X) = [A,B]

44部分写在跳的下面也就是说,如果不满足跳跃成立的条件就赶紧44,甚至可以在墙角的时候进行大跳等判断迅速逃离墙角,以上投技的部分就先解释到这里,我们接下来看看当身,之前也有提到过当身的对应记录办法,这里也再提一下

;----------------------------------------------------------------------
;自分被ステート奪取記憶
;----------------------------------------------------------------------
[State 33000, VarSet]
Type = VarSet
TriggerAll = EnemyNear(Root,var(58)),Ctrl = 0
TriggerAll = EnemyNear(Root,var(58)),MoveType = A
TriggerAll = EnemyNear(Root,var(58)),StateNo >= 200
TriggerAll = EnemyNear(Root,var(58)),StateType != A
TriggerAll =(Root,StateNo != [120,159]) && (Root,StateNo != [5000,5500])
TriggerAll = Root,Movetype = H && Root,Time = 1
Trigger1 = Helper(33000+Root,ID),fvar(10) = 0
FV = 10
Value = EnemyNear(Root,var(58)),PrevStateNo
IgnoreHitPause = 1

.......

[State 33000, VarSet]
Type = VarSet
TriggerAll = EnemyNear(Root,var(58)),Ctrl = 0
TriggerAll = EnemyNear(Root,var(58)),MoveType = A
TriggerAll = EnemyNear(Root,var(58)),StateNo >= 200
TriggerAll = EnemyNear(Root,var(58)),StateType != A
TriggerAll = EnemyNear(Root,var(58)),PrevStateNo != Helper(33000+Root,ID),fvar(10)
TriggerAll = EnemyNear(Root,var(58)),PrevStateNo != Helper(33000+Root,ID),fvar(11)
TriggerAll = EnemyNear(Root,var(58)),PrevStateNo != Helper(33000+Root,ID),fvar(12)
TriggerAll = EnemyNear(Root,var(58)),PrevStateNo != Helper(33000+Root,ID),fvar(13)
TriggerAll = EnemyNear(Root,var(58)),PrevStateNo != Helper(33000+Root,ID),fvar(14)
TriggerAll = EnemyNear(Root,var(58)),PrevStateNo != Helper(33000+Root,ID),fvar(15)
TriggerAll = EnemyNear(Root,var(58)),PrevStateNo != Helper(33000+Root,ID),fvar(16)
TriggerAll = EnemyNear(Root,var(58)),PrevStateNo != Helper(33000+Root,ID),fvar(17)
TriggerAll = EnemyNear(Root,var(58)),PrevStateNo != Helper(33000+Root,ID),fvar(18)
TriggerAll =(Root,StateNo != [120,159]) && (Root,StateNo != [5000,5500])
TriggerAll = Root,Movetype = H && Root,Time = 1
Trigger1 = Helper(33000+Root,ID),fvar(10)!= 0
Trigger1 = Helper(33000+Root,ID),fvar(11)!= 0
Trigger1 = Helper(33000+Root,ID),fvar(12)!= 0
Trigger1 = Helper(33000+Root,ID),fvar(13)!= 0
Trigger1 = Helper(33000+Root,ID),fvar(14)!= 0
Trigger1 = Helper(33000+Root,ID),fvar(15)!= 0
Trigger1 = Helper(33000+Root,ID),fvar(16)!= 0
Trigger1 = Helper(33000+Root,ID),fvar(17)!= 0
Trigger1 = Helper(33000+Root,ID),fvar(18)!= 0
Trigger1 = Helper(33000+Root,ID),fvar(19) = 0
FV = 19
Value = EnemyNear(Root,var(58)),PrevStateNo
IgnoreHitPause = 1

;-----------------------------------------------------------------------
; 自分被ステート奪取記憶
;-----------------------------------------------------------------------
[State -3, VarSet]
Type = VarSet
Trigger1 = fvar(5) != 0
FV = 5
Value = 0
IgnoreHitPause = 1

[State -3, 自分被ステート奪取]
Type = Null
TriggerAll = var(59) = 1
TriggerAll = NumHelper(33000+ID)
TriggerAll = EnemyNear(var(58)),Ctrl = 0
TriggerAll = EnemyNear(var(58)),MoveType = A
TriggerAll = EnemyNear(var(58)),StateNo >= 200
TriggerAll = EnemyNear(var(58)),StateType != A
Trigger1 = EnemyNear(var(58)),StateNo = Helper(33000+ID),fvar(10)
Trigger1 = fvar(5) := fvar(5) + 2 || 1
Trigger2 = EnemyNear(var(58)),StateNo = Helper(33000+ID),fvar(11)
Trigger2 = fvar(5) := fvar(5) + 2 || 1
Trigger3 = EnemyNear(var(58)),StateNo = Helper(33000+ID),fvar(12)
Trigger3 = fvar(5) := fvar(5) + 2 || 1
Trigger4 = EnemyNear(var(58)),StateNo = Helper(33000+ID),fvar(13)
Trigger4 = fvar(5) := fvar(5) + 2 || 1
Trigger5 = EnemyNear(var(58)),StateNo = Helper(33000+ID),fvar(14)
Trigger5 = fvar(5) := fvar(5) + 2 || 1
Trigger6 = EnemyNear(var(58)),StateNo = Helper(33000+ID),fvar(15)
Trigger6 = fvar(5) := fvar(5) + 2 || 1
Trigger7 = EnemyNear(var(58)),StateNo = Helper(33000+ID),fvar(16)
Trigger7 = fvar(5) := fvar(5) + 2 || 1
Trigger8 = EnemyNear(var(58)),StateNo = Helper(33000+ID),fvar(17)
Trigger8 = fvar(5) := fvar(5) + 2 || 1
Trigger9 = EnemyNear(var(58)),StateNo = Helper(33000+ID),fvar(18)
Trigger9 = fvar(5) := fvar(5) + 2 || 1
Trigger10 = EnemyNear(var(58)),StateNo = Helper(33000+ID),fvar(19)
Trigger10 = fvar(5) := fvar(5) + 2 || 1
IgnoreHitPause = 1

;----------------------------------------------------------------------
[State 33000, Null]
Type = Null
TriggerAll = Time = 0
Trigger1 = var(0) := -1
Trigger1 = var(1) := -1
.......
Trigger1 = var(19) := -1
IgnoreHitPause = 1

;----------------------------------------------------------------------
;敵に当身ステート記憶 Part 1
;----------------------------------------------------------------------
[State 33000, VarSet]
Type = VarSet
Trigger1 = Root,MoveReversed
Trigger1 = EnemyNear(Root,var(58)),Ctrl = 0
Trigger1 = EnemyNear(Root,var(58)),MoveType = A
Trigger1 = Helper(33000+Root,ID),var(0) = -1
var(0) = EnemyNear(Root,var(58)),StateNo
IgnoreHitPause = 1

.......

[State 33000, VarSet]
Type = VarSet
Trigger1 = Root,MoveReversed
Trigger1 = EnemyNear(Root,var(58)),Ctrl = 0
Trigger1 = EnemyNear(Root,var(58)),MoveType = A
Trigger1 = EnemyNear(Root,var(58)),StateNo != Helper(33000+Root,ID),var(0)
Trigger1 = EnemyNear(Root,var(58)),StateNo != Helper(33000+Root,ID),var(1)
Trigger1 = EnemyNear(Root,var(58)),StateNo != Helper(33000+Root,ID),var(2)
Trigger1 = EnemyNear(Root,var(58)),StateNo != Helper(33000+Root,ID),var(3)
Trigger1 = EnemyNear(Root,var(58)),StateNo != Helper(33000+Root,ID),var(4)
Trigger1 = EnemyNear(Root,var(58)),StateNo != Helper(33000+Root,ID),var(5)
Trigger1 = EnemyNear(Root,var(58)),StateNo != Helper(33000+Root,ID),var(6)
Trigger1 = EnemyNear(Root,var(58)),StateNo != Helper(33000+Root,ID),var(7)
Trigger1 = EnemyNear(Root,var(58)),StateNo != Helper(33000+Root,ID),var(8)
Trigger1 = Helper(33000+Root,ID),var(0) != -1
Trigger1 = Helper(33000+Root,ID),var(1) != -1
Trigger1 = Helper(33000+Root,ID),var(2) != -1
Trigger1 = Helper(33000+Root,ID),var(3) != -1
Trigger1 = Helper(33000+Root,ID),var(4) != -1
Trigger1 = Helper(33000+Root,ID),var(5) != -1
Trigger1 = Helper(33000+Root,ID),var(6) != -1
Trigger1 = Helper(33000+Root,ID),var(7) != -1
Trigger1 = Helper(33000+Root,ID),var(8) != -1
Trigger1 = Helper(33000+Root,ID),var(9) = -1
var(9) = EnemyNear(Root,var(58)),StateNo
IgnoreHitPause = 1

;----------------------------------------------------------------------
;敵に当身ステート記憶 Part 2
;----------------------------------------------------------------------
[State 33000, VarSet]
Type = VarSet
Trigger1 = Root,fvar(5) = 2
Trigger1 = Root,MoveReversed
Trigger1 = EnemyNear(Root,var(58)),Ctrl = 0
Trigger1 = EnemyNear(Root,var(58)),MoveType = A
Trigger1 = Helper(33000+Root,ID),var(10) = -1
var(10) = EnemyNear(Root,var(58)),PrevStateNo
IgnoreHitPause = 1

.......

[State 33000, VarSet]
Type = VarSet
Trigger1 = Root,fvar(5) = 2
Trigger1 = Root,MoveReversed
Trigger1 = EnemyNear(Root,var(58)),Ctrl = 0
Trigger1 = EnemyNear(Root,var(58)),MoveType = A
Trigger1 = EnemyNear(Root,var(58)),PrevStateNo != Helper(33000+Root,ID),var(10)
Trigger1 = EnemyNear(Root,var(58)),PrevStateNo != Helper(33000+Root,ID),var(11)
Trigger1 = EnemyNear(Root,var(58)),PrevStateNo != Helper(33000+Root,ID),var(12)
Trigger1 = EnemyNear(Root,var(58)),PrevStateNo != Helper(33000+Root,ID),var(13)
Trigger1 = EnemyNear(Root,var(58)),PrevStateNo != Helper(33000+Root,ID),var(14)
Trigger1 = EnemyNear(Root,var(58)),PrevStateNo != Helper(33000+Root,ID),var(15)
Trigger1 = EnemyNear(Root,var(58)),PrevStateNo != Helper(33000+Root,ID),var(16)
Trigger1 = EnemyNear(Root,var(58)),PrevStateNo != Helper(33000+Root,ID),var(17)
Trigger1 = EnemyNear(Root,var(58)),PrevStateNo != Helper(33000+Root,ID),var(18)
Trigger1 = Helper(33000+Root,ID),var(10) != -1
Trigger1 = Helper(33000+Root,ID),var(11) != -1
Trigger1 = Helper(33000+Root,ID),var(12) != -1
Trigger1 = Helper(33000+Root,ID),var(13) != -1
Trigger1 = Helper(33000+Root,ID),var(14) != -1
Trigger1 = Helper(33000+Root,ID),var(15) != -1
Trigger1 = Helper(33000+Root,ID),var(16) != -1
Trigger1 = Helper(33000+Root,ID),var(17) != -1
Trigger1 = Helper(33000+Root,ID),var(18) != -1
Trigger1 = Helper(33000+Root,ID),var(19) = -1
var(19) = EnemyNear(Root,var(58)),PrevStateNo
IgnoreHitPause = 1

;-----------------------------------------------------------------------
; 相手の特殊ステート(当身)記憶
;-----------------------------------------------------------------------
[State -3, VarSet]
Type = VarSet
Trigger1 = fvar(2) != 0
FV = 2
Value = 0
IgnoreHitPause = 1

[State -3, 相手の特殊ステート]
Type = Null
TriggerAll = var(59) = 1
TriggerAll = NumHelper(33000+ID)
TriggerAll = EnemyNear(var(58)),MoveType = A
Trigger1 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(0)
Trigger1 = fvar(2) := fvar(2) + 1 || 1
Trigger2 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(1)
Trigger2 = fvar(2) := fvar(2) + 1 || 1
Trigger3 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(2)
Trigger3 = fvar(2) := fvar(2) + 1 || 1
Trigger4 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(3)
Trigger4 = fvar(2) := fvar(2) + 1 || 1
Trigger5 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(4)
Trigger5 = fvar(2) := fvar(2) + 1 || 1
Trigger6 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(5)
Trigger6 = fvar(2) := fvar(2) + 1 || 1
Trigger7 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(6)
Trigger7 = fvar(2) := fvar(2) + 1 || 1
Trigger8 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(7)
Trigger8 = fvar(2) := fvar(2) + 1 || 1
Trigger9 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(8)
Trigger9 = fvar(2) := fvar(2) + 1 || 1
Trigger10 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(9)
Trigger10 = fvar(2) := fvar(2) + 1 || 1
Trigger11 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(10)
Trigger11 = fvar(2) := fvar(2) + 2 || 1
Trigger12 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(11)
Trigger12 = fvar(2) := fvar(2) + 2 || 1
Trigger13 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(12)
Trigger13 = fvar(2) := fvar(2) + 2 || 1
Trigger14 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(13)
Trigger14 = fvar(2) := fvar(2) + 2 || 1
Trigger15 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(14)
Trigger15 = fvar(2) := fvar(2) + 2 || 1
Trigger16 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(15)
Trigger16 = fvar(2) := fvar(2) + 2 || 1
Trigger17 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(16)
Trigger17 = fvar(2) := fvar(2) + 2 || 1
Trigger18 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(17)
Trigger18 = fvar(2) := fvar(2) + 2 || 1
Trigger19 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(18)
Trigger19 = fvar(2) := fvar(2) + 2 || 1
Trigger20 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(19)
Trigger20 = fvar(2) := fvar(2) + 2 || 1
IgnoreHitPause = 1

同样这里也不多解释,看不明白的看前面的当身对应篇有说明,这里只是回顾部分,接下来就要想想如何用跳和44来逃避当身了,先举个跳跃的例子

[State -3, ハイジャンプ 逃げる]
Type = ChangeState
Value = (大跳state)
TriggerAll = var(59) = 1
TriggerAll = RoundState = 2
TriggerAll = StateType != A
TriggerAll = BackEdgeBodyDist < 30 ;前提条件是在墙角内想逃离墙角
TriggerAll =!EnemyNear(var(58)),Ctrl
TriggerAll = EnemyNear(var(58)),StateType != A
TriggerAll = EnemyNear(var(58)),StateType != L
TriggerAll = EnemyNear(var(58)),MoveType != H
TriggerAll = EnemyNear(var(58)),StateNo >= 200
TriggerAll = EnemyNear(var(58)),Facing != Facing && P2Dist X > 0 || fvar(5) = 2
TriggerAll = EnemyNear(var(58)),Time >= 50-var(59)*5 || var(59) > 9
TriggerAll =!Enemy,NumProj && fvar(9) = 0 && (!InGuardDist || fvar(5) = 2) ;fvar(9) = 0是前篇讲的有关地波记录state的变量
TriggerAll = Ctrl || (StateNo = [20,22]) || (StateNo = [100,101]) || (StateNo = [120,149])
Trigger1 = EnemyNear(var(58)),AnimTime < -38 || Abs(EnemyNear(var(58)),Pos X - Pos X) < A && EnemyNear(var(58)),AnimTime < -18 ;大概一个小跳的时间并且距离更近的时候就按小跳时间计算,距离太远则要防止对面的对空技能
Trigger1 = (fvar(2) != 0 && fvar(5) = 2 || fvar(2) = 2) && Abs(EnemyNear(var(58)),Pos X - Pos X) < B ;B > A

[State -3, バックステップ/中後ジャンプ 逃げる]
Type = ChangeState
Value = ifelse(P2BodyDist X > 60,(后影中跳state),105)
TriggerAll = var(59) = 1
TriggerAll = RoundState = 2
TriggerAll = StateType != A
TriggerAll = BackEdgeBodyDist >= 30 ;这里条件和上面相反,不在墙角内
TriggerAll =!EnemyNear(var(58)),Ctrl
TriggerAll = EnemyNear(var(58)),StateType != A || EnemyNear(var(58)),StateType = A && EnemyNear(var(58)),Vel X >= 0 ;这里把空中当身也算进去了
TriggerAll = EnemyNear(var(58)),StateType != L
TriggerAll = EnemyNear(var(58)),MoveType != H
TriggerAll = EnemyNear(var(58)),StateNo >= 200
TriggerAll = EnemyNear(var(58)),Facing != Facing && P2Dist X > 0 || fvar(5) = 2
TriggerAll = EnemyNear(var(58)),Time >= 50-var(59)*5 || var(59) > 9
TriggerAll =!Enemy,NumProj && fvar(9) = 0 && (!InGuardDist || fvar(5) = 2)
TriggerAll = Ctrl || (StateNo = [20,22]) || (StateNo = [100,101]) || (StateNo = [120,149])
Trigger1 = EnemyNear(var(58)),AnimTime < -10 || EnemyNear(var(58)),StateType = A && EnemyNear(var(58)),Vel X >= 0 ;(只需要极短的时间来确认或者对面是空中当身的情况)
Trigger1 = (fvar(2) != 0 && fvar(5) = 2 || fvar(2) = 2) && Abs(EnemyNear(var(58)),Pos X - Pos X) < C

以上是举例说明内容,更多的应对还需要各位自己去实践运用

好了,今天的课就先到这,如果您有什么问题的话可以私信我,我会第一时间给您答复,或者把问题发到我的邮箱

mizore@kotori.moe, 谢谢大家!
2016.11.0512:20

AI 立回技巧相关(Part.1)

Episode 10 立回技巧相关(Part.1)

各位好久不见,我又回来了,这次我们谈谈立回的某些技巧

众所周知,立回是什么,一个人在战斗中的位置移动,走路,跑步,跳跃等等之类的,这些都是立回,怎么样才能做到所谓的精准,发挥到极致呢?其实这个也是根据这个角色的性能而决定的,比如你有当身,可以主动进攻空振当身什么的,这样比较赚,如果你拳脚和硬直属于比较变态的那种,你可以主动进攻,猛压的那种,也就是前跳,跑步和攻击的概率可以写高一点,如果你属于下位机,不妨把防御写好一点,然后等破绽抓硬直来进攻,格斗的精髓,记住,如果你有龟的资本的话,那么能龟就龟,因为你在开场时不知道对面是什么样的性能,所以如果能三十六计走为上策的话是不错的选择,当然也看作者的风格

我们今天的正题主要谈谈大前跳的作用,大家知道,大前跳是跳的很高,很远,适合打逆和突进这种的跳跃,非常实用,它的作用除了进攻以外也可以用来抓硬直,那么怎么做到呢

首先,我们先看看自己的大跳性能,比如说我举个例子,大前跳是跳跃,也是要经过state 40-50-52 这么一个变化的,打开DEBUG,比如40这个状态是4帧,然后进入50,按下pause后按scrool lock数帧数,或者截取得到最后1帧,再看DEBUG显示时间是多少,比如显示的是34,因为是从0开始数的,所以时间一共是4+35,也就是39,那么取得了这个数据,大跳的时间是39帧

接下来要怎么用呢,之前我们学过用helper记录的方法,这里也举个例子

;----------------------------------------------------------------------
[State 33000, Null]
Type = Null
TriggerAll = Time = 0
Trigger1 = var(30) := -1
Trigger1 = var(31) := -1
Trigger1 = var(32) := -1
Trigger1 = var(33) := -1
Trigger1 = var(34) := -1
Trigger1 = var(35) := -1
Trigger1 = var(36) := -1
Trigger1 = var(37) := -1
Trigger1 = var(38) := -1
Trigger1 = var(39) := -1
IgnoreHitPause = 1

;----------------------------------------------------------------------
;敵に飛び道具ステート記憶
;----------------------------------------------------------------------
[State 33000, VarSet]
Type = VarSet
TriggerAll = EnemyNear(Root,var(58)),NumProj = 1
TriggerAll = EnemyNear(Root,var(58)),Ctrl = 0
TriggerAll = EnemyNear(Root,var(58)),MoveType = A
TriggerAll = EnemyNear(Root,var(58)),AnimTime < EnemyNear(Root,var(58)),Time - 35 (先记录好跳跃全程时间)
Trigger1 = Helper(33000+Root,ID),var(30) = -1
var(30) = EnemyNear(Root,var(58)),StateNo
IgnoreHitPause = 1

; Abs(EnemyNear(Root,var(58)),Time - EnemyNear(Root,var(58)),AnimTime) 这个代表对面状态总时间
....

[State 33000, VarSet]
Type = VarSet
TriggerAll = EnemyNear(Root,var(58)),NumProj = 1
TriggerAll = EnemyNear(Root,var(58)),Ctrl = 0
TriggerAll = EnemyNear(Root,var(58)),MoveType = A
TriggerAll = EnemyNear(Root,var(58)),AnimTime < EnemyNear(Root,var(58)),Time - 35
TriggerAll = EnemyNear(Root,var(58)),StateNo != Helper(33000+Root,ID),var(30)
TriggerAll = EnemyNear(Root,var(58)),StateNo != Helper(33000+Root,ID),var(31)
TriggerAll = EnemyNear(Root,var(58)),StateNo != Helper(33000+Root,ID),var(32)
TriggerAll = EnemyNear(Root,var(58)),StateNo != Helper(33000+Root,ID),var(33)
TriggerAll = EnemyNear(Root,var(58)),StateNo != Helper(33000+Root,ID),var(34)
TriggerAll = EnemyNear(Root,var(58)),StateNo != Helper(33000+Root,ID),var(35)
TriggerAll = EnemyNear(Root,var(58)),StateNo != Helper(33000+Root,ID),var(36)
TriggerAll = EnemyNear(Root,var(58)),StateNo != Helper(33000+Root,ID),var(37)
TriggerAll = EnemyNear(Root,var(58)),StateNo != Helper(33000+Root,ID),var(38)
Trigger1 = Helper(33000+Root,ID),var(30) != -1
Trigger1 = Helper(33000+Root,ID),var(31) != -1
Trigger1 = Helper(33000+Root,ID),var(32) != -1
Trigger1 = Helper(33000+Root,ID),var(33) != -1
Trigger1 = Helper(33000+Root,ID),var(34) != -1
Trigger1 = Helper(33000+Root,ID),var(35) != -1
Trigger1 = Helper(33000+Root,ID),var(36) != -1
Trigger1 = Helper(33000+Root,ID),var(37) != -1
Trigger1 = Helper(33000+Root,ID),var(38) != -1
Trigger1 = Helper(33000+Root,ID),var(39) = -1
var(39) = EnemyNear(Root,var(58)),StateNo
IgnoreHitPause = 1

这样就可以记录10个地波状态了,确保先有35帧以上,然后开始写AI,花费一个var

;-----------------------------------------------------------------------
; 相手の特殊ステート(飛び道具)記憶
;-----------------------------------------------------------------------
[State -3, VarSet]
Type = VarSet
Trigger1 = fvar(9) != 0
FV = 9
Value = 0
IgnoreHitPause = 1

[State -3, 相手の特殊ステート]
Type = Null
TriggerAll = var(59) = 1
TriggerAll = NumHelper(33000+ID)
TriggerAll = EnemyNear(var(58)),MoveType = A
Trigger1 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(30)
Trigger1 = fvar(9) := fvar(9) + 1 || 1
Trigger2 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(31)
Trigger2 = fvar(9) := fvar(9) + 1 || 1
Trigger3 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(32)
Trigger3 = fvar(9) := fvar(9) + 1 || 1
Trigger4 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(33)
Trigger4 = fvar(9) := fvar(9) + 1 || 1
Trigger5 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(34)
Trigger5 = fvar(9) := fvar(9) + 1 || 1
Trigger6 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(35)
Trigger6 = fvar(9) := fvar(9) + 1 || 1
Trigger7 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(36)
Trigger7 = fvar(9) := fvar(9) + 1 || 1
Trigger8 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(37)
Trigger8 = fvar(9) := fvar(9) + 1 || 1
Trigger9 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(38)
Trigger9 = fvar(9) := fvar(9) + 1 || 1
Trigger10 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(39)
Trigger10 = fvar(9) := fvar(9) + 1 || 1
IgnoreHitPause = 1

现在,fvar(9)如果变为1就代表符合要求可以大跳

[State -3, 大ジャンプ 対飛び道具]
Type = ChangeState
Value = 36
TriggerAll = var(59) = 1
TriggerAll = RoundState = 2
TriggerAll = StateType != A
TriggerAll =!EnemyNear(var(58)),Ctrl
TriggerAll = EnemyNear(var(58)),StateType != A
TriggerAll = EnemyNear(var(58)),StateType != L
TriggerAll = EnemyNear(var(58)),MoveType != H ;上面是基本属性不多解释了
TriggerAll = EnemyNear(var(58)),AnimTime <= -39 ;39帧跳跃
TriggerAll = EnemyNear(var(58)),StateNo = [1000,2000) ;2000以上可能是超杀最好别去抓
TriggerAll = EnemyNear(var(58)),Facing != Facing ;面对面
TriggerAll = EnemyNear(var(58)),Time >= 50-var(59)*10 || var(59) > 9 ;反应相关
TriggerAll = Random < EnemyNear(var(58)),Time*ifelse( var(59) > 9,25,20) ;概率相关
TriggerAll =!InGuardDist || Abs(EnemyNear(var(58)),Pos X - Pos X) > 190 ;如果默认guarddist = 160的话,190大概就是无法检测在GuardDist内的范围,但是确认攻击,也当成InGuardDist就行了
Trigger1 = Abs(EnemyNear(var(58)),Pos X - Pos X) = [A,B] ;这里需要自己算,配合空中拳脚立回自己实际测量
Trigger1 = !Enemy,NumProj && (fvar(9) != 0 || var(59) < 10) ;因为出现波可能就晚了,你不知道波是什么样的,所以要赶在没有地波出来之前出跳跃最好,同时也可以排除0帧波什么的恐怖技能,但是已经确认状态,当然也可以加一个低级AI

大概过程就是这样,希望各位能够自己亲身体会

好了,今天的课就先到这,如果您有什么问题的话可以私信我(只要是我会的,不管什么问题),我会第一时间给您答复,或者把问题发到我的邮箱

mizore@kotori.moe, 谢谢大家!
2016.06.2309:55

AI 双打部分浅谈

Episode 9 双打部分浅谈

一个比较完整的AI,是要包含双打部分的,里面的概念其实很好理解,队友被打了你看情况去救队友,其中比较远程的话可以大跳或者突进过去救,如果你有飞行道具就出飞行道具技能去救队友,再比如还有队友在打对面两个对手的时候,你去补刀,队友把两个敌人拉了个P2,你可以做一个蓄气的动作来给己方攒气,或者你也可以装逼出个嘲讽啥的,反正用法很多,自己按照实际来理解

下面切入正题,今天用到两个var来记录全部双打情况,var(51)和var(52),如果被占用了就换别的

;━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
; タッグ用 ;TAG(双打模式)下使用
;━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
[State -3, 敵が1人] ;对手只有1个人的情况,有两种情况,对手有队友但是队友死了,也可能是本来就1个人
Type = VarSet
Trigger1 = NumEnemy != 2
Trigger2 = !(EnemyNear(0),Alive && EnemyNear(1),Alive)
V = 51
Value = 0

[State -3, 敵が2人かつ前方のみ] ;两个敌人都在你面前的情况
Type = VarSet
TriggerAll = NumEnemy = 2
TriggerAll = EnemyNear(0),Alive
TriggerAll = EnemyNear(1),Alive
Trigger1 = ifelse(Facing = 1,EnemyNear(0),Pos X - Pos X > 0,EnemyNear(0),Pos X - Pos X < 0)
Trigger1 = ifelse(Facing = 1,EnemyNear(1),Pos X - Pos X > 0,EnemyNear(1),Pos X - Pos X < 0)
V = 51
Value = 1

[State -3, 自分、パートナー、敵、敵] ;场上4人分布情况从左到右:自己,队友,两位敌人
Type = VarSet
TriggerAll = NumEnemy = 2
TriggerAll = NumPartner
TriggerAll = EnemyNear(0),Alive
TriggerAll = EnemyNear(1),Alive
TriggerAll = Partner,Alive
Trigger1 = ifelse(Facing = 1,EnemyNear(0),Pos X - Pos X > 0,EnemyNear(0),Pos X - Pos X < 0)
Trigger1 = ifelse(Facing = 1,EnemyNear(1),Pos X - Pos X > 0,EnemyNear(1),Pos X - Pos X < 0)
Trigger1 = ifelse(Facing = 1,EnemyNear(0),Pos X - Partner,Pos X > 0,EnemyNear(0),Pos X - Partner,Pos X < 0)
Trigger1 = ifelse(Facing = 1,EnemyNear(1),Pos X - Partner,Pos X > 0,EnemyNear(1),Pos X - Partner,Pos X < 0)
V = 51
Value = 2

[State -3, 自分、敵、パートナー、敵] ;分布情况:自己,敌人,队友,敌人,此时队友可能有危险,因为队友被两个敌人夹住了
Type = VarSet
TriggerAll = NumEnemy = 2
TriggerAll = NumPartner
TriggerAll = EnemyNear(0),Alive
TriggerAll = EnemyNear(1),Alive
TriggerAll = Partner,Alive
Trigger1 = ifelse(Facing = 1,EnemyNear(0),Pos X - Pos X > 0,EnemyNear(0),Pos X - Pos X < 0)
Trigger1 = ifelse(Facing = 1,EnemyNear(1),Pos X - Pos X > 0,EnemyNear(1),Pos X - Pos X < 0)
Trigger1 = ifelse(Facing = 1,EnemyNear(0),Pos X - Partner,Pos X < 0,EnemyNear(0),Pos X - Partner,Pos X > 0)
Trigger1 = ifelse(Facing = 1,EnemyNear(1),Pos X - Partner,Pos X > 0,EnemyNear(1),Pos X - Partner,Pos X < 0)
V = 51
Value = 3

[State -3, 自分、敵、敵、パートナー] ;分布情况:自己,两位敌人,队友,此时为优势
Type = VarSet
TriggerAll = NumEnemy = 2
TriggerAll = NumPartner
TriggerAll = EnemyNear(0),Alive
TriggerAll = EnemyNear(1),Alive
TriggerAll = Partner,Alive
Trigger1 = ifelse(Facing = 1,EnemyNear(0),Pos X - Pos X > 0,EnemyNear(0),Pos X - Pos X < 0)
Trigger1 = ifelse(Facing = 1,EnemyNear(1),Pos X - Pos X > 0,EnemyNear(1),Pos X - Pos X < 0)
Trigger1 = ifelse(Facing = 1,EnemyNear(0),Pos X - Partner,Pos X < 0,EnemyNear(0),Pos X - Partner,Pos X > 0)
Trigger1 = ifelse(Facing = 1,EnemyNear(1),Pos X - Partner,Pos X < 0,EnemyNear(1),Pos X - Partner,Pos X > 0)
V = 51
Value = 4

[State -3, 背後に敵有り] ;这个就比较尴尬了,背后有敌人的情况,通常背后有敌人的情况就代表你前面还有一个敌人,也就是说你被两位敌人卡住了(苦笑)
Type = VarSet
TriggerAll = NumEnemy = 2
TriggerAll = EnemyNear(0),Alive
TriggerAll = EnemyNear(1),Alive
Trigger1 = ifelse(Facing = 1,EnemyNear(0),Pos X - Pos X < 0,EnemyNear(0),Pos X - Pos X > 0)
Trigger2 = ifelse(Facing = 1,EnemyNear(1),Pos X - Pos X < 0,EnemyNear(1),Pos X - Pos X > 0)
V = 51
Value = 5

;---------------------------------------------------------------------------
[State -3, パートナー不在] ;双打模式,但是队友不在或者队友已经死亡
Type = VarSet
TriggerAll = TeamMode = Simul
Trigger1 = !NumPartner
Trigger2 = !Partner,Alive
V = 52
Value = 0

[State -3, パートナー後衛] ;双打模式下队友在你后面当后卫
Type = VarSet
TriggerAll = TeamMode = Simul
TriggerAll = NumPartner
TriggerAll = Partner,Alive
Trigger1 = ifelse(Facing = 1,Partner,Pos X - Pos X < 0,Partner,Pos X - Pos X > 0)
V = 52
Value = 1

[State -3, パートナー前衛] ;双打模式队友给你当前锋
Type = VarSet
TriggerAll = TeamMode = Simul
TriggerAll = NumPartner
TriggerAll = Partner,Alive
Trigger1 = ifelse(Facing = 1,Partner,Pos X - Pos X > 0,Partner,Pos X - Pos X < 0)
V = 52
Value = 2

[State -3, パートナー被ダメージ] ;双打模式下队友被打,而且这里代表的是普通的被打或者被打防御的状态,可以救
Type = VarSet
TriggerAll = TeamMode = Simul
TriggerAll = NumPartner
TriggerAll = Partner,Alive
TriggerAll = Partner,MoveType = H
TriggerAll = ifelse(Facing = 1,Partner,Pos X - Pos X > 0,Partner,Pos X - Pos X < 0)
Trigger1 = Partner,StateNo = [5000,5100)
Trigger2 = Partner,StateNo = [120,159]
V = 52
Value = 3

[State -3, パートナー攻撃中] ;队友在打敌人的情况,近敌显示被打
Type = VarSet
TriggerAll = TeamMode = Simul
TriggerAll = NumPartner
TriggerAll = Partner,Alive
TriggerAll = Partner,MoveType = A
TriggerAll = Partner,MoveType != H
TriggerAll = EnemyNear(var(58)),MoveType = H
TriggerAll = ifelse(Facing = 1,Partner,Pos X - Pos X > 0,Partner,Pos X - Pos X < 0)
Trigger1 = EnemyNear(var(58)),StateNo = [5000,5100)
V = 52
Value = 4

[State -3, パートナー被ステート奪取] ;这个比较危险,因为是队友被抓了个P2,这个时候如果你有波的话就发波吧,最好别靠近对手,说不定你也会被卷进去
Type = VarSet
TriggerAll = TeamMode = Simul
TriggerAll = NumPartner
TriggerAll = Partner,Alive
TriggerAll = Partner,MoveType = H
TriggerAll = ifelse(Facing = 1,Partner,Pos X - Pos X > 0,Partner,Pos X - Pos X < 0)
Trigger1 = Partner,StateNo != [5000,5500]
Trigger1 = Partner,StateNo != [120,159]
V = 52
Value = 5

[State -3, パートナーステート奪取] ;队友给别人拉了个P2,此时为近敌被拉P2的状态
Type = VarSet
TriggerAll = TeamMode = Simul
TriggerAll = NumPartner
TriggerAll = Partner,Alive
TriggerAll =(Partner,StateNo = [2000,4999]) || Partner,StateNo > 5500
Trigger1 = EnemyNear(var(58)),MoveType = H
Trigger1 = EnemyNear(var(58)),StateNo != [5000,5500]
Trigger1 = EnemyNear(var(58)),StateNo != [120,159]
V = 52
Value = 6

好了先记下来这么多,接下来要怎么用呢

举个例子:比如说你要装逼对吧,我们就说195,挑衅这个动作,什么时候用呢?

考虑下情况,肯定是两个对手都被打,而且都被拉了P2,首先要考虑到的肯定是var(52) = 6的情况

;装逼装逼装逼
[State -3, Taunt]
Type = ChangeState
Value = 195
TriggerAll = var(59) = 1
TriggerAll = StateNo != 195 && PrevStateNo != 195 ;因为有些人195是带ctrlset的,而且不要和前一个动作重复
TriggerAll = RoundState = 2 && EnemyNear(var(58)),Life > 0
TriggerAll = Random <= 150 ;概率你可以自己定,这里是15%概率装个逼
TriggerAll = StateType != A
TriggerAll =!Enemy,NumProj ;对面没有飞行道具
TriggerAll =!InGuardDist && !Helper(31000+ID),InGuardDist ;确保是InGuarddist
TriggerAll = Ctrl || (StateNo = [20,22]) || (StateNo = [100,101]) || (StateNo = [120,149])
Trigger1 = var(52) = 6 && var(51) < 5 ;确定对手是被P2了而且不能被两位队友夹住
Trigger1 = EnemyNear(0),MoveType = H && (EnemyNear(0),StateNo != [120,159]) && (EnemyNear(0),StateNo != [5000,5100))
Trigger1 = EnemyNear(1),MoveType = H && (EnemyNear(1),StateNo != [120,159]) && (EnemyNear(1),StateNo != [5000,5100)) ;上面的2行,因为要同时确保两位敌人同时被打,近敌和远敌,分别代表0,1
Trigger1 = Abs(EnemyNear(var(58)),Pos X - Pos X) > 120; (大概距离可以自己定,Abs(EnemyNear(var(58)),Pos X - Pos X)与P2BodyDist X的换算标准是前者比后者大32)

除了装逼之外,你有可以帮助对手的东西也可以用,比如蓄气,这个换个状态号就行了,不多讲

不要成天只知道装逼,学着点去救队友和自救

先说,比如发个波去辅助队友,或者去营救

;地波
[State -3, Proj]
Type = ChangeState
Value = (地波状态号,如果你有强弱地波的话按照距离选择强弱,远了就强,稍微近一点就弱)
TriggerAll = var(59) = 1
TriggerAll = var(52) = [2,3] ; var(52) = 2代表队友给你当前锋,3代表队友在被普通的攻击
TriggerAll = var(51) < 5 ;首先要确保自己的安全,不能被夹住
TriggerAll = RoundState = 2 && EnemyNear(var(58)),life > 0
TriggerAll = Random <= 100 ;10%概率,自己可以改
TriggerAll = StateType != A
TriggerAll = NumProjID(1000) = 0
TriggerAll = EnemyNear(var(58)),StateType != A
TriggerAll = Ctrl || (StateNo = [20,22]) || (StateNo = [100,101]) || (StateNo = [120,149])
Trigger1 = P2BodyDist X >= 200 ;多远出,自己算好距离

还有一点,就是你被两位对手夹住了怎么办,如果有闪避或者AB之类的技能赶紧闪出去,因为对你来说是大劣势,以AB为例
,尽量以耗气后AB或者无敌闪避技能为主,比如原版KOF的后AB是有挺大责任的,但耗1气防御下AB就是无敌的话,那么

[State -3, 後転]
Type = ChangeState
Value = (后AB状态)
TriggerAll = var(59) = 1
TriggerAll = var(51) = 5 && (var(52) > 0 || Power >= 1000) ;你队友在的时候或者有气就AB出去,没有的话你就认命吧
TriggerAll = RoundState = 2
TriggerAll = StateType != A
Trigger1 = Ctrl || (StateNo = [20,22]) || (StateNo = [100,101]) || (StateNo = [120,149])
Trigger1 = Abs(EnemyNear(var(58)),Pos X - Pos X) <= 100 ;保持一定距离
Trigger1 = EnemyNear(var(58)),StateNo >= 1000 && !EnemyNear(var(58)),Ctrl ;对手攻击状态,通常1000以上为必杀,趁这个时候赶紧跑掉
Trigger1 = var(52) = 5 && BackEdgeBodyDist >= 40 (你和队友都被夹了,此时队友被P2了,你赶紧跑远了,别卖了自己)
Trigger2 = StateNo = 150 || StateNo = 152 ;消耗1气赶紧跑出去,不要管太多
Trigger2 = Power >= 1000 && var(42) >= 120 && BackEdgeBodyDist >= 20 ;自己背离墙角有一段距离
Trigger2 = ifelse(Facing = 1,(EnemyNear(0),Pos X - Pos X = [-100,0]),(EnemyNear(0),Pos X - Pos X = [0,100])) ;记得算好距离,facing = 1表示脸朝右边看,-1表示脸朝左边
Trigger2 = EnemyNear(0),BackEdgeBodyDist >= 40 ;敌人背离墙角有一段距离,不然你AB出不去的,AB完了还是被卡住
Trigger2 = EnemyNear(0),Facing = Facing ;背对敌人
Trigger3 = StateNo = 150 || StateNo = 152 ;同上面的道理
Trigger3 = Power >= 1000 && var(42) >= 120 && BackEdgeBodyDist >= 20
Trigger3 = ifelse(Facing = 1,(EnemyNear(1),Pos X - Pos X = [-100,0]),(EnemyNear(1),Pos X - Pos X = [0,100]))
Trigger3 = EnemyNear(1),BackEdgeBodyDist >= 40
Trigger3 = EnemyNear(1),Facing = Facing

这里提一下,enemynear,或者你用enemynear(var())这种的,只能指定近敌的动作,而不能代表2位敌人,所以判断2位敌人要用到enemynear(0)和enemynear(1),0代表近的那位,1代表远的那位

除了这些外,双打的想法还有很多的,比如创造人工墙角,可以配合相应的队友做出相应的反应,比如你知道你指定的队友哪个动作做出来了,比如知道是可以追打的P2StateNo,而且两位敌人同时被打,赶紧大跳或者闪避到对手后面去用2A点对面,总之好墙角自己造嘛蛤蛤蛤

好了,今天的课就先到这,如果您有什么问题的话可以私信我,我会第一时间给您答复,或者把问题发到我的邮箱

mizore@kotori.moe, 谢谢大家!
2016.05.2809:00

AI 记录硬直时间进行压制和确反

Episode 8 记录硬直时间进行压制和确反

首先看到一招的hitdef,来看看他的ground.hittime,guard.hittime,还有pausetime和guard.pausetime

我先举个例子

[State 200, ヒット定義]
type = HitDef
trigger1 = time = 0
attr = S, NA
damage = 23, 0
animtype = Light
guardflag = MA
hitflag = MAF
priority = 3, Hit
pausetime = 9, 10
sparkno = s4050
guard.sparkno = s4100
sparkxy = -20, -80
hitsound = s1,0
guardsound = s2,0
ground.type = High
ground.slidetime = 8
ground.hittime = 10
ground.velocity = -4.5,0
air.animtype = Back
air.velocity = -4.5,-4
airguard.velocity = -5.5,-2.5
air.hittime = 0
getpower = 35,35
givepower = 16,16

可以看到hittime(包括guard.hittime)是10,pausetime(这里包括guard.pausetime)是9,10

什么意思呢?就是说这一招打中了会给对手造成10帧的被打时间还有10帧的暂停时间,同时还会给自己造成9帧的暂停时间

也就是说,给自己一个11帧的有利时间,我们要这个有什么用呢?

花费两个var记下来hittime和hittime+真实造成的pausetime

比如你可以这么写

[State -3, AI与硬直時間カウント]
type = VarSet
Trigger1 = MoveContact = 1
var(47) = 11+1;(因为是movecontact = 1的时候计算的,所以要多加1帧,这个记录在当前statedef下,后面的statedef也是如此)

这里记录在-3下

;-----------------------------------------------------------------------
; ヒット硬直カウント
;-----------------------------------------------------------------------
[State -3, VarSet]
Type = VarSet
Trigger1 = var(49) != 0
V = 49
Value = 0
IgnoreHitPause = 1

[State -3, ヒット硬直時間]
Type = VarSet
TriggerAll = EnemyNear(var(58)),Ctrl = 0
TriggerAll = EnemyNear(var(58)),StateType != A
TriggerAll = EnemyNear(var(58)),StateType != L
TriggerAll = EnemyNear(var(58)),MoveType = H
Trigger1 = EnemyNear(var(58)),StateNo = [120,160)
Trigger2 = EnemyNear(var(58)),StateNo = [5000,5100)
V = 49
Value = EnemyNear(var(58)),GetHitVar(hittime) + 1 ;这里也是一样的道理
IgnoreHitPause = 1

然后取得了这个var的值有什么用呢?

接下来就可以做到比如一些空中特殊技命中来精准压制的玩意

比如空中特殊技-跑-技能 这样的压制或者确认动作

举个例子,statedef 100(跑步状态号)是4帧以后才开始出现速度,那么你可以这么写

;ダッシュ
[State -3, RUN]
Type = ChangeState
Value = 100
TriggerAll = var(59) = 1
TriggerAll = var(49) > 4 || var(47) > 4 ;确认对面有4帧以上的硬直出跑
TriggerAll = RoundState = 2
TriggerAll = StateNo != 100 ;不能是跑步动作时候出跑
TriggerAll = StateType != A
TriggerAll = EnemyNear(var(58)),StateType != A
TriggerAll = EnemyNear(var(58)),StateType != L
TriggerAll = EnemyNear(var(58)),MoveType = H
TriggerAll = Abs(EnemyNear(var(58)),Pos X - Pos X) <= 110 ;大概多少距离自己算,跑步内部AI里面要保证对面在被打(防御和真被打)情况下一直跑而不停
TriggerAll =!InGuardDist
Trigger1 = Ctrl || (StateNo = [20,22]) || (StateNo = [120,149])

然后跑过去了,可以根据硬直时间出不同的技能,比如5C是3帧的可以这么写

[State -3, Stand Strong Punch]
Type = ChangeState
Value = (5C状态号)
TriggerAll = var(59) = 1
TriggerAll = var(47) > 2 || var(49) > 2 ;时间是大于起手时间,也就是>= 3
TriggerAll = RoundState = 2
TriggerAll = StateType != A
TriggerAll = EnemyNear(var(58)),StateType != A
TriggerAll = EnemyNear(var(58)),StateType != L
TriggerAll = EnemyNear(var(58)),MoveType = H
TriggerAll =!InGuardDist || EnemyNear(var(58)),Facing = Facing
TriggerAll = P2BodyDist X = [-10,ifelse(var(47) = 3 || var(49) = 3),30,0)] ;在硬直时间足够的情况下和对手贴脸了再出,如果刚好是最后一帧了就用可以出这招的最大距离出,比如5C最大距离是30,那么就用ifelse写30
Trigger1 = Ctrl || (StateNo = [20,22]) || (StateNo = [100,101]) || (StateNo = [120,149])

还有一些其他中段,上段,下段就不一一描述了,在硬直够的情况下可以连续小跳压制,尽量使用下段技或者中段技来干扰对面防御,最快的技能留着保险比较小的硬直时间

好了,今天的课就先到这,如果您有什么问题的话可以私信我(只要是我会的,不管什么问题),我会第一时间给您答复,或者把问题发到我的邮箱

mizore@kotori.moe, 谢谢大家!
2016.03.3123:08

AI 辅助器 记录对手滞空时间

Episode 7 记录对手滞空时间

今天的内容可能会略复杂,嗯,所以没看懂的也不太要紧,会用就行了

于是,不谈其他的闲话了,直接进入正题,需要用到的有yaccel计算器,TAG计算器,这两个前面都有讲过这里就不谈了

那么给出辅助器,(不知道的看前面,fvar(20)是记录yaccel的变量,var(58)为TAG变量)

;--------------------------------------------------------------------
; 相手の滞空時間、超絶やっつけ 对手滞空时间
;--------------------------------------------------------------------
[State -3, VarSet]
Type = VarSet
Trigger1 = 1
fvar(1) = 0
IgnoreHitPause = 1 ;还原

[State -3, VarSet]
Type = VarSet
Trigger1 = EnemyNear(var(58)),StateType = A && fvar(20) != 0
Trigger1 = ((floor(EnemyNear(var(58)),Vel Y))**2-2*(fvar(20))*(floor(EnemyNear(var(58)),Pos Y))) >= 0
fvar(1) = floor(((-EnemyNear(var(58)),Vel Y)+(((floor(EnemyNear(var(58)),Vel Y))**2-2*(fvar(20))*(floor(EnemyNear(var(58)),Pos Y)))**0.5))/(fvar(20)))+1
IgnoreHitPause = 1 ;记录

条件略复杂,我们假设一下元,计算的时候把floor忽略

令EnemyNear(var(58)),Vel Y = v, fvar(20) = a, EnemyNear(var(58)),Pos Y = h

trigger1等价代换一下,v**2(y方向v的平方) - 2ah >= 0,也就是v**2 >= 2ah

我们知道,h = 1/2*a*t**2 ,v = at 两式子合并,消去t,得到 v**2 = 2ah,而v**2 = 2ah只是临界条件,v**2 - 2ah >= 0就是说在临界条件之上,这是第一个公式的来源

我们要得到的数据是时间,令fvar(1) = t,那么把公式代换一下,同样的,忽略掉floor,((xxx**0.5)代表对xxx开平方)

((-v)+(v**2-2ah)**0.5)/a + 1 = t, (t-1)*a = -v+(v**2-2ah)**0.5, 令(t-1) = T

aT+v = (v**2-2ah)**0.5, v**2 + 2avT + (a**2)*(T**2) = v**2 - 2ah

舍去两边v**2,舍掉一个a, 2vT + 2ah + aT**2 = 0,这是最终结果

证明结论,令h = 0,也就是说对手在地面被击飞,刚刚pausetime结束的时候,此时pos y = 0

2vT = -aT**2, 2v = -a*T , v = -(1/2)*a*T = -(1/2)*a*(t+1),+1为起始值

那么来图证明一下结论吧,这招的打击速度为 -2,-10,yacce = 0.5
LR~(S)8FQ5P4FAD[)4_$IUX

可以看到下面的打击时间,因为是1起始,所以是40+1 = 41,所以刚才的公式成立
GPDVR802S`JG2VTYET2{2T3

对手在此过程中,如果不受外力,那么对手做匀加速曲线运动,a一定,y方向v随着T变化,x方向的v不变,那么对手做的是抛物线运动,可以看到下图,对手的滞空时间在减少A3EET3X9`{1_NC~HI9SW{P

好的,对手现在着地了,我们也能看到fvar(1)的值变为0了,说明对手不再浮空
_7(H$V~(9Q[68ICA}2NR927

此变量因为有floor的限制,所以会有一定的小误差,但不会超过4,那么,记录对手这个数据有什么用呢?这个变量,在对手Pausetime未消失的时候,虽然有ignorehitpause,但对手没有vel和yaccel,那么我们只能记录下对手pausetime以外的滞空时间

这个变量,给弹幕起手的角色比较好用,能计算对手滞空还有多少时间,来确认进行接下来的连招,如果是比较朴素的角色,还是建议不要用这个了,还省了你一个变量,但是给弹幕起手角色的再合适不过了,当然,如果有援护招式的话,也是很合适的,来判断对手还剩下多少滞空时间进行出招判断

好了,今天的课就先到这,如果您有什么问题的话可以私信我(只要是我会的,不管什么问题),我会第一时间给您答复,或者把问题发到我的邮箱

mizore@kotori.moe, 谢谢大家!

アクセス

オンライン