2017.04.1800:34

人物制作技巧相关其一.击退篇

Episode 1 人物制作技巧相关其一.击退篇

很久没更新过博客了是时候也来更新一发

这次呢我们讲一讲有关人物受击击退技巧,该怎么改善才能做的完整

因为我们知道,原作向的东西,只要你给对手造成打击的距离是多远,那么同时你在版边攻击他你自己退步的距离也是多远

虽然说Mugen也自带这个,但是不要相信mugen能给你带来原作的效果,mugen在角落里击退放大的倍数是1.3倍(默认),然后自己可以设立ground.cornerpush.veloff或者air.cornerpush.veloff还有guard.cornerpush.veloff这三个,但是你给对手造成的版边击退(其实是自己击退的距离)是按照速度来缩小倍数的,这个倍数就是stand.friction或者crouch.friction来逐帧乘的,比如-10的速度,它是按照(-10)*1.3*(0.85)^n 来计算的,和原作不同的是,大部分原作是按照对面受击时间EnemyNear,GetHitVar(HitTime),或者判断对面有没有在受击状态内来判断的,所以我们给出下面这个代码

fvar(18)代表击退位移代表值,一般是负数,使用的时候,需要限制原本的击退效果,也就是说
要把ground.velocity.veloff和air.velocity.veloff给限制了才能用(感谢ikaruga氏)

首先我们需要标记一个东西,就是为了不让人物在超杀暂停中移动,那么我们给superpause加工一下

[State 2000, 超必殺技発動の時間停止]
type = SuperPause
trigger1 = AnimElem = 1,= 1
anim = -1
poweradd = -1000
time = 28
movetime = 28
darken = 0
p2defmul = 1.0

比如说本来是这样一个东西,暂停时间是28F,那么我们改一下

[State 2000, 超必殺技発動の時間停止]
type = SuperPause
trigger1 = AnimElem = 1,= 1
trigger1 = var(9) := 1 || 1
........
只是先加了一个var记下来这个是超杀暂停的意思,那么接下来-2下需要解除这个var,于是

;-----------------------------------------------------------------------------
[State -2, VarAdd]
type = VarAdd
trigger1 = var(9) >= 1
var(9) = 1

[State -2, VarSet]
type = VarSet
trigger1 = var(9) >= 28 ;因为我这个是28F所以这里是28
var(9) = 0

;-----------------------------------------------------------------------------
[State -2, 1]
Type = VarSet
Trigger1 = MoveContact = 1
FV = 18
Value = 0 ;这个说一下,因为读取方式是从下优先的,所以默认条件相当于&&1那样,除了最下面的条件以外的触摸都是0,所以不能装-3下
ignorehitpause = 1

[State -2, 2]
Type = VarSet
Trigger1 = FVar(18) >= 0
Trigger2 = EnemyNear(Var(58)),StateNo != [154,155]
Trigger2 = EnemyNear(Var(58)),MoveType != H || EnemyNear(Var(58)),GetHitVar(HitTime) = 0
Trigger3 = FVar(18) = [-1,0]
Trigger4 = EnemyNear(Var(58)),StateNo = [154,155]
Trigger4 = EnemyNear(Var(58)),Ctrl
Trigger5 = EnemyNear(Var(58)),StateNo = [5100,5119]
Trigger6 = EnemyNear(Var(58)),StateNo = [5200,5219]
Trigger7 = EnemyNear(Var(58)),StateNo = 5001 || EnemyNear(Var(58)),StateNo = 5011
Trigger7 = EnemyNear(Var(58)),Time >= EnemyNear(Var(58)),GetHitVar(SlideTime)
FV = 18
Value = 0 ;这些是取消位移值的条件,不多讲了,slidetime就是滑行时间,hitdef里面的

[State -2, 3]
Type = PosAdd
TriggerAll = FVar(18) < 0 && var(9) = 0
TriggerAll = StateType = S || StateType = C
TriggerAll = EnemyNear(Var(58)),GetHitVar(HitShakeTime) <= 0
Trigger1= EnemyNear(Var(58)),BackEdgeBodyDist <= 0 || EnemyNear(Var(58)),FrontEdgeBodyDist <= 0
X = (FVar(18)) ;在hitpausetime结束后来位移

[State -2, 4]
Type = VarSet
Trigger1 = FVar(18) < 0 && var(9) = 0
Trigger1 = EnemyNear(Var(58)),GetHitVar(HitShakeTime) <= 0
FV = 18
Value = FVar(18) * ((EnemyNear(Var(58)),StateType = S || EnemyNear(Var(58)),StateType = C) * 0.85) ;一般是0.85的摩擦系数,这个可以根据自己的系数不同来改

[State -2, 5]
Type = VarSet
Trigger1 = MoveContact = 1
FV = 18
Value = -EnemyNear(Var(58)),GetHitVar(XVel)*Facing * (EnemyNear(Var(58)),StateType = S || EnemyNear(Var(58)),StateType = C);先读取一下对方的受击初速度
ignorehitpause = 1

代码是有了但还没看出来到底和系统自带的有什么区别对不对?那么还是缺少一些可靠的证据,于是我们来证明一下,实验人物:JIN氏Kyo-XI(这里不知道为什么图片上传错误我就给大家报数据吧,具体的可以去我网盘里下载DOC文档来查看结果)
链接:https://1drv.ms/f/s!ApWw8WboJ3MYn194tObyHdQVovlY
[State 200, 僸僢僩掕媊]
type = HitDef
trigger1 = time = 0
attr = S, NA
damage = 58, 0
animtype = Hard
guardflag = MA
hitflag = MAF
priority = 3, Hit
pausetime = 10, 11
sparkno = s4010
guard.sparkno = s4110
sparkxy = -20, -65
hitsound = s1,1
guardsound = s2,0
ground.type = High
ground.slidetime = 18
ground.hittime  = 20
ground.velocity = -8.3
airguard.velocity = -2.3,-1.8
air.type = High
air.velocity = -2.5,-3
air.hittime = 12

这个是他的hitdef,我们看到,g.velocity是-8.3

首先是版中击退(我给你们先报个数据):49

那么我们来看看版边击退的距离(先报个数据):34
[State 200, 僸僢僩掕媊]
type = HitDef
trigger1 = time = 0
attr = S, NA
damage = 58, 0
animtype = Hard
guardflag = MA
hitflag = MAF
priority = 3, Hit
pausetime = 10, 11
sparkno = s4010
guard.sparkno = s4110
sparkxy = -20, -65
hitsound = s1,1
guardsound = s2,0
ground.type = High
ground.slidetime = 18
ground.hittime  = 20
ground.velocity = -8.3
airguard.velocity = -2.3,-1.8
air.type = High
air.velocity = -2.5,-3
air.hittime = 12
ground.cornerpush.veloff = 0
air.cornerpush.veloff = 0

接下来我们加上现在的新代码来看看(同样报数据):49

好了证明结束,我们看到了,新代码的击退距离=版中击退,那么也就是说效果就在这里,非常实用的一个代码希望大家能用得上

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

mizore@kotori.moe, 谢谢大家!
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.09.0417:39

お知らせ

お久しぶりですね,皆さん今は元気ですか~最近はちょっと忙しいし,オンラインはないし,ごめんなさいね *>.<*

お返事は遅すぎたことはすみません,俺はきっとお返事します(゚∀゚≡゚∀゚)

だからこそ,お返事ない時間のなかで,皆さんもっと試してみてください( ^ω^ )
2016.07.3021:53

AI HELPER-5 当身记忆归类(加强版)

Episode 5 当身记忆归类(加强版)

对于大多数AI作者来言,最困难最头疼的地方就是当身这块了,也就是让人头大的movereversed

为什么呢,它可以制造格挡,也可以制造p2state技能,但是二者共同特点是都有movereversed存在

所以我们记忆的时候要给定一个归类,判断是p2技还是单纯的格挡技(不带p1和p2)

话不多说我们来举例子,准备一个helper,并且准备30个未使用var

;----------------------------------------------------------------------
;自分被ステート奪取記憶 ;10个var来记忆下自己被p2的情况,给定helper的ID比如说是33000+ID
;----------------------------------------------------------------------
[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]) ;普通受击在5000-5500之间,一般不会超过这里,防御为120-155
TriggerAll = Root,Movetype = H && Root,Time = 1 ;被打的第一时间记下来,如果对面给你的p2不是movetype = H那只好GG
Trigger1 = Helper(33000+Root,ID),var(0) = 0
V = 0
Value = EnemyNear(Root,var(58)),PrevStateNo ;因为你是在被p2时候记录下来的。所以他前一个动作就是给你拉p2的动作
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),var(0)
TriggerAll =(Root,StateNo != [120,159]) && (Root,StateNo != [5000,5500])
TriggerAll = Root,Movetype = H && Root,Time = 1
Trigger1 = Helper(33000+Root,ID),var(0)!= 0
Trigger1 = Helper(33000+Root,ID),var(1) = 0
V = 1
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),var(0)
TriggerAll = EnemyNear(Root,var(58)),PrevStateNo != Helper(33000+Root,ID),var(1)
TriggerAll = EnemyNear(Root,var(58)),PrevStateNo != Helper(33000+Root,ID),var(2)
TriggerAll = EnemyNear(Root,var(58)),PrevStateNo != Helper(33000+Root,ID),var(3)
TriggerAll = EnemyNear(Root,var(58)),PrevStateNo != Helper(33000+Root,ID),var(4)
TriggerAll = EnemyNear(Root,var(58)),PrevStateNo != Helper(33000+Root,ID),var(5)
TriggerAll = EnemyNear(Root,var(58)),PrevStateNo != Helper(33000+Root,ID),var(6)
TriggerAll = EnemyNear(Root,var(58)),PrevStateNo != Helper(33000+Root,ID),var(7)
TriggerAll = EnemyNear(Root,var(58)),PrevStateNo != Helper(33000+Root,ID),var(8)
TriggerAll =(Root,StateNo != [120,159]) && (Root,StateNo != [5000,5500])
TriggerAll = Root,Movetype = H && Root,Time = 1
Trigger1 = Helper(33000+Root,ID),var(0)!= 0
Trigger1 = Helper(33000+Root,ID),var(1)!= 0
Trigger1 = Helper(33000+Root,ID),var(2)!= 0
Trigger1 = Helper(33000+Root,ID),var(3)!= 0
Trigger1 = Helper(33000+Root,ID),var(4)!= 0
Trigger1 = Helper(33000+Root,ID),var(5)!= 0
Trigger1 = Helper(33000+Root,ID),var(6)!= 0
Trigger1 = Helper(33000+Root,ID),var(7)!= 0
Trigger1 = Helper(33000+Root,ID),var(8)!= 0
Trigger1 = Helper(33000+Root,ID),var(9) = 0
V = 9
Value = EnemyNear(Root,var(58)),PrevStateNo
IgnoreHitPause = 1 ;这是10个var,记录下来你被p2的情况

下面继续,这10个var在-3里面显示一下标记

;-----------------------------------------------------------------------
; 自分被ステート奪取記憶
;-----------------------------------------------------------------------
[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 ;一般这时候只要记录地面的p2就好了
Trigger1 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(0)
Trigger1 = fvar(5) := fvar(5) + 1 || 1
Trigger2 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(1)
Trigger2 = fvar(5) := fvar(5) + 1 || 1
Trigger3 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(2)
Trigger3 = fvar(5) := fvar(5) + 1 || 1
Trigger4 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(3)
Trigger4 = fvar(5) := fvar(5) + 1 || 1
Trigger5 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(4)
Trigger5 = fvar(5) := fvar(5) + 1 || 1
Trigger6 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(5)
Trigger6 = fvar(5) := fvar(5) + 1 || 1
Trigger7 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(6)
Trigger7 = fvar(5) := fvar(5) + 1 || 1
Trigger8 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(7)
Trigger8 = fvar(5) := fvar(5) + 1 || 1
Trigger9 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(8)
Trigger9 = fvar(5) := fvar(5) + 1 || 1
Trigger10 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(9)
Trigger10 = fvar(5) := fvar(5) + 1 || 1
IgnoreHitPause = 1 ;当检测到p2时候,fvar(5)变为1

接下来就是带p2的当身记忆

;----------------------------------------------------------------------
;敵に当身ステート記憶 Part 1
;----------------------------------------------------------------------
[State 33000, VarSet]
Type = VarSet
Trigger1 = Root,fvar(5) = 1 ;首先检测到对面是带p2的技能
Trigger1 = Root,MoveReversed ;本体触摸当身,有一个前提,必须自己存在hitpausetime,不然没法记下来
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) = 1
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

这样一来,20个var就能把当身技能记录下来了,但是有个缺点,你第一次吃当身不知道对面是p2,所以得吃两次才能记下来(囧)

然后再说说格挡,比刚才简单很多,但同时也有些不足的地方

;----------------------------------------------------------------------
;敵に当身ステート記憶 Part 2
;----------------------------------------------------------------------
[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(20) = -1
var(20) = EnemyNear(Root,var(58)),StateNo ;原理同上,但是这里记下来的是当前stateno,有两种情况,1个是p2stateno,另一个就是格挡技能,不拉P1也不拉P2
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(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

这里的缺陷,就是会把p2技和格挡技记录在一块,但是要明白一点,你被拉P2的时候是肯定不能动的,所以剩下来的就是格挡技了

然后把两个当身技能归类在var里面

;-----------------------------------------------------------------------
; 相手の特殊ステート(当身)記憶
;-----------------------------------------------------------------------
[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(10)
Trigger1 = fvar(2) := fvar(2) + 1 || 1
Trigger2 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(11)
Trigger2 = fvar(2) := fvar(2) + 1 || 1
Trigger3 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(12)
Trigger3 = fvar(2) := fvar(2) + 1 || 1
Trigger4 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(13)
Trigger4 = fvar(2) := fvar(2) + 1 || 1
Trigger5 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(14)
Trigger5 = fvar(2) := fvar(2) + 1 || 1
Trigger6 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(15)
Trigger6 = fvar(2) := fvar(2) + 1 || 1
Trigger7 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(16)
Trigger7 = fvar(2) := fvar(2) + 1 || 1
Trigger8 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(17)
Trigger8 = fvar(2) := fvar(2) + 1 || 1
Trigger9 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(18)
Trigger9 = fvar(2) := fvar(2) + 1 || 1
Trigger10 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(19)
Trigger10 = fvar(2) := fvar(2) + 1 || 1
Trigger11 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(20)
Trigger11 = fvar(2) := fvar(2) + 2 || 1
Trigger12 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(21)
Trigger12 = fvar(2) := fvar(2) + 2 || 1
Trigger13 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(22)
Trigger13 = fvar(2) := fvar(2) + 2 || 1
Trigger14 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(23)
Trigger14 = fvar(2) := fvar(2) + 2 || 1
Trigger15 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(24)
Trigger15 = fvar(2) := fvar(2) + 2 || 1
Trigger16 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(25)
Trigger16 = fvar(2) := fvar(2) + 2 || 1
Trigger17 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(26)
Trigger17 = fvar(2) := fvar(2) + 2 || 1
Trigger18 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(27)
Trigger18 = fvar(2) := fvar(2) + 2 || 1
Trigger19 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(28)
Trigger19 = fvar(2) := fvar(2) + 2 || 1
Trigger20 = EnemyNear(var(58)),StateNo = Helper(33000+ID),var(29)
Trigger20 = fvar(2) := fvar(2) + 2 || 1
IgnoreHitPause = 1

这里就很明确了,fvar(2) = 1时代表带P2的当身技,fvar(2) = 2时代表格挡技和已被拉的p2state,当然被拉的p2state以外的就是格挡技了

然后接下来的AI怎么写,如果对面出当身带P2技能,你已经记下来知道了,那么不在版边你可以选择后跳和44,然后如果你被卡版边了,你可以选择闪身或者大跳(千万别手贱点嘲讽不然会死得很惨- -+),但是格挡技能因为不确定是升龙还是单纯的格挡,所以闪身和防御是最好的选择,然后剩下来的你只要抓最后几帧硬直就可以了(EnemyNear(var(58)),AnimTime = -X,X为某招触发判定帧数)

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

mizore@kotori.moe, 谢谢大家!

アクセス

オンライン