• 按键公众号 :
按键精灵电脑版
立即下载

软件版本:2014.06
软件大小:22.9M
更新时间:2021-12-03

按键精灵安卓版
立即下载

软件版本:3.7.2
软件大小:46.2M
更新时间:2023-05-10

按键精灵iOS版
立即下载

软件版本:1.8.0
软件大小:29.2M
更新时间:2023-03-21

按键手机助手
立即下载

软件版本:3.8.0
软件大小:262M
更新时间:2023-05-30

快捷导航

登录 后使用快捷导航
没有帐号? 注册

发新话题 回复该主题

[技术交流] 【院刊】-【201502期】拳皇战斗脚本——模拟招式成功率百分百 [复制链接]

1#

拳皇战斗脚本——模拟出招成功率百分百

本文按键学院提供技术支持


按键学院交流群(1群已满):376122403

零基础学按键精灵群(2群):372671254




目前官方正在举办的 “第二届脚本大赛”已经结束。
这次的大赛主题是“拳皇”
看小伙伴们脚本写的火热,我们风骚的06工程师也忍不住写了个战斗脚本
据说,此脚本非常牛逼,能成功模拟拳皇里百分之百的招式动作


有没有这么厉害啊?
小伙伴们和小编一起去来欣赏下06老湿的骚姿吧~






前言

拳皇游戏里的招式,按键的情况大致分为三种:

1、
  1. keyDown方向键
  2. keypress 技能键
  3. keyup方向键
复制代码
2、
  1. keypress 方向键
  2. keypress 技能键
复制代码
3、
  1. keydown 技能键1
  2. keydown 技能键2
  3. keyup 技能键1
  4. keyup 技能键2
复制代码
而且,招式不同,延时也是不一样的,这个招式50毫秒可以连贯发出,那个招式可能需要100毫秒
有这么多状况,那么怎样才能写出兼容性百分百的出招脚本呢?我们继续往下看。



脚本流程

您所在的用户组无法下载或查看附件





绑定游戏
脚本使用了大漠插件,先注册大漠插件之后进行绑定游戏


查找游戏窗口句柄

使用大漠的 FindWindow 命令来查找游戏窗口句柄
FindWindow命令是模糊查找
当要查找的窗口句柄,类名或者标题有一部分不固定会变化的时候,我们可以使用FindWindow命令进行模糊查找

例如许多类名为Afx:¥%#¥……%#¥ 的窗口,Afx后面的值通常都是变化的
研究了下,拳皇里的这个类名倒是不会变化,但是为了安全起见,咱们还是模糊查找吧。

您所在的用户组无法下载或查看附件




角色定位
角色在左边和角色在右边时,出招里的方向键是不一样的,所以需要判断下角色当前是在什么位置。那么,要如何判断呢?




我们观察游戏里的角色动作,站着、蹲着、或者摆一个招式的时候,总有一些地方是不会变化的。
这里我们选择蹲着,因为蹲着相较于其他动作静态,便于识别。


您所在的用户组无法下载或查看附件



八神蹲着的时候,上半身是会动的,所以截取八神大腿部分的一小块图片。
同理,我们把角色移动到右边,蹲下,截取一张八神大腿图。
启动脚本之后,我们先按下下蹲键也就是S,蹲下后进行找图判断,

如果找到的是左边截取到的八神大腿图,那么就说明八神在左边,
如果找到的是右边截取到的八神大腿图,那么就说明八神在右边。


小技巧
当我们测试的时候,游戏里的人物如果会反抗的话,非常影响调试,所以我们可以按下 Alt+c组合键

您所在的用户组无法下载或查看附件


p2设置为攻击无效,这样我们就可以毫无顾忌进行调试了



调用InputKeys函数


InputKeys函数用于分析按键,是按下按住还是松开
用键盘 WASD来操作方向,很多招戳不出来。为什么呢?
键盘WASD和摇杆不同,例如:
禁千二百十一式·八稚女:↓↘→↘↓↙←+A或C
八神的这一招八稚女,用摇杆摇就是 下、右下、右、右下、下、左下、左、A或者C
但是,在键盘上操作的话,右下这个操作我们需要同时按下S和D,左下需要同时按下WA
既然键盘WASD操作起来这么麻烦
我们就来模拟摇杆




您所在的用户组无法下载或查看附件



我们将5想象成摇杆的杆子
您所在的用户组无法下载或查看附件

那么,4、6、8、2就分别是左、右、上、下 (键盘操作:A、 D 、W 、S)
7、9、1、3 对应左上、右上、左下、右下
键盘操作:WA、WD、 AS、DS)
技能键为:A、B、C、D
对应轻拳、轻脚、重拳、重脚 (键盘操作:J、K、L、U)
注意:我们并不是要在小键盘上按键,而是借用小键盘来更好的理解模拟摇杆的操作
而实际上,我们应用到的只是 1到9的这几个数字
当输入4的时候,经过函数的判断处理,按下的则是A键

当按下A键时,经过函数的判断处理,则按下J键




InputKeys函数
语法: Call InputKeys("+/-方向键,+/-技能键,延时")
方向键和技能键前
加上+号:按住方向键或者技能键不放
加上-号 :松开方向键或者技能键
无符号 :按下方向键或者技能键

如果有多个操作,操作于操作之间用|线连接
例如八神的横踢动作:
您所在的用户组无法下载或查看附件

这个动作需要按住方向键S不放,再按下技能键U,按完技能键U之后再松开S键
如果,按下S键马上放开再去按J键,招式就发不出。


好了,我们前面说用数字1到9来模拟摇杆的方向
用 ABCD模拟技能键JKLU


那么,我们调用InputKeys函数:
Call InputKeys("+2,,100|,D,800|-,,0")
第一个动作下蹲:
+2,,100:第一个参数+2,+代表按住不放,按住方向键(下)不放。
第二个参数空着,说明这里不按技能键。
第三个参数100,下蹲动作操作完之后延时100毫秒再执行下一个动作。

第二个动作重脚:
,D,800:第一个参数空着,说明这里不按方向键。
第二个参数D,按下技能键(重脚)。
第三个参数800,重脚动作操作完之后延时800毫秒再执行下一个动作。


第三个动作松开前面按下的所有方向键:
-,,0第一个参数-,-后面没有填写确切的方向键则说明松开所有的方向键。
第二个参数空着,说明没有任何技能键操作。
第三个参数0,无延时。




上面我们说的八神的八稚女招式要如何调用
inputkeys函数呢?
八神的八稚女:↓↘→↘↓↙←+A或C
调用inputkeys函数:
Call InputKeys("2363214,A,1200")




InputKeys函数


将传进来的参数进行分解:
先用split函数 按照 竖线|”+2,,100|,D,800|-,,0 分解成三个部分存放在数组里
然后在针对数组元素,例如数组(0)中存放的是 +2,,100
split函数 按照 逗号,”+2,,100 分解成三个部分存放在三个变量中:KeyStr、KeyCmd、KeySlp

然后用字符串截取函数Left截取三个变量里存放的字符串的第一个字符
如果方向键有符号则调用 StateKey函数
如果技能键有符号/没符号、
方向键无符号则调用InputKey函数


StateKey函数



此函数有两个参数
参数1:需要操作的方向键
参数2:真假
参数2为真,则按下参数1中的方向键
参数2为假,则松开参数1中的方向键





InputKey函数

此函数也是两个参数
参数1:需要操作的键
参数2:真假


此函数在对方向键进行操作之前会先判断方向键是按下还是弹起的状态,
例如: 上次按下了方向键左没有松开
先判断方向键左有没有被按下
如果有,则进一步判断新一次的操作需不需要按下方向键左,如果需要则不松开,不需要则松开



整体代码

  1. Dim Player // 角色 : 八神、火舞、胖子、雅典娜
  2. Dim PlayPos // 0 = 左 、 1 = 右 、 -1 = 未知
  3. Dim KeyStkN_8, KeyStkN_2, KeyStkN_4, KeyStkN_6 // 需要按下的按键
  4. Dim KeyStkO_8, KeyStkO_2, KeyStkO_4, KeyStkO_6 // 需要释放的按键
  5. Dim KeyStkS_8, KeyStkS_2, KeyStkS_4, KeyStkS_6 // 独立控制的按键


  6. Call Register()
  7. Call dm.SetPath("c:\tz_kof")
  8. Call dm.SetShowErrorMsg(0)

  9. // 绑定游戏窗口
  10. hwnd = dm.FindWindow("Afx:", "Kawaks")
  11. Call dm.SetWindowState(hwnd, 12)
  12. Call dm.BindWindowEx(hwnd, "gdi", "normal", "normal", "dx.public.active.api|dx.public.active.message", 0)

  13. Player = "八神"
  14. /*---------------------------出招---------------------------*/
  15. '/* 八神
  16. Do
  17. // 重新定位角色方向
  18. Call PlayerPos()
  19. // 轻拳
  20. Call InputKeys("6,D,0|+1,,300|-,,0")
  21. // 梦弹
  22. Call InputKeys("+6,A,50|,A,100|-,,0|+1,,400|-,,0")
  23. // 八稚女近身
  24. Call InputKeys("2363214,A,0|+1,,1000|-,,0")
  25. // 琴月d阴近身
  26. Call InputKeys("63214,B,0|+1,,800|-,,0")
  27. // 三段葵花
  28. Call InputKeys("214,A,60|214,A,60|214,A,60|214,A,60|214,A,0|+1,,300|-,,0")
  29. // 下蹲重脚
  30. Call InputKeys("+2,,60|,D,200|-,,0|+1,,600|-,,0")
  31. // 暗勾手 + 三发琴月阴抢开
  32. Call InputKeys("63214,B,0|+1,,1600|-,,0")
  33. Call InputKeys("63214,B,0|+1,,1600|-,,0")
  34. Call InputKeys("63214,B,0|+1,,1600|-,,0")
  35. // 三段葵花
  36. Call InputKeys("214,A,60|214,A,60|214,A,60|214,A,60|214,A,0|+1,,800|-,,0")
  37. Loop
  38. '*/
  39. /*---------------------------出招---------------------------*/


  40. // 角色定位
  41. Function PlayerPos()
  42. dm.KeyDown 83
  43. Delay 400
  44. PlayPos = dm.FindPic(0, 0, 610, 450, Player & "_定位_左.bmp|" & Player & "_定位_右.bmp", "000000", 0.9, 0, intX, intY)
  45. Select Case PlayPos
  46. Case 0
  47. TracePrint "角色在左侧"
  48. Case 1
  49. TracePrint "角色在右侧"
  50. Case Else
  51. TracePrint "无法识别角色方向"
  52. End Select
  53. dm.KeyUp 83
  54. Delay 100
  55. End Function


  56. // 指令串解析
  57. Function InputKeys(KeyList)
  58. KeyStu = Split(KeyList, "|")
  59. For j = 0 To UBound(KeyStu)
  60. KeyStr = Split(KeyStu(j), ",")(0) // 方向键
  61. KeyCmd = Split(KeyStu(j), ",")(1) // 指令键
  62. KeySlp = Split(KeyStu(j), ",")(2) // 延时
  63. // 解析方向控制 [状态指令还是连贯指令]
  64. Select Case Left(KeyStr,1)
  65. Case "+" // 状态指令输入
  66. KeyStr = Replace(KeyStr, "+", "")
  67. For i = 1 To Len(KeyStr)
  68. KeyChr = Mid(KeyStr, i, 1)
  69. Call StateKey(KeyChr, True)
  70. Next
  71. Case "-" // 状态指令取消 [后面的指令连贯输入]
  72. KeyStr = Replace(KeyStr, "-", "")
  73. Call StateKey(KeyChr, False)
  74. For i = 1 To Len(KeyStr)
  75. KeyChr = Mid(KeyStr, i, 1)
  76. Call InputKey(KeyChr, False)
  77. Next
  78. Case Else // 连贯指令输入
  79. For i = 1 To Len(KeyStr)
  80. KeyChr = Mid(KeyStr, i, 1)
  81. Call InputKey(KeyChr, False)
  82. Next
  83. End Select
  84. // 控制按键
  85. Select Case Left(KeyCmd, 1)
  86. Case "+" // 状态指令输入
  87. KeyCmd = Replace(KeyCmd, "+", "")
  88. For i = 1 To Len(KeyCmd)
  89. KeyChr = Mid(KeyCmd, i, 1)
  90. Call InputKey(KeyChr, True)
  91. Next
  92. Case "-" // 状态指令取消 [后面的指令连贯输入]
  93. KeyCmd = Replace(KeyCmd, "-", "")
  94. For i = 1 To Len(KeyCmd)
  95. KeyChr = Mid(KeyCmd, i, 1)
  96. Call InputKey(KeyChr, False)
  97. Next
  98. Case Else // 连贯指令输入
  99. For i = 1 To Len(KeyCmd)
  100. KeyChr = Mid(KeyCmd, i, 1)
  101. Call InputKey(KeyChr, True)
  102. Next
  103. For i = 1 To Len(KeyCmd)
  104. KeyChr = Mid(KeyCmd, i, 1)
  105. Call InputKey(KeyChr, False)
  106. Next
  107. End Select
  108. Delay CLng(KeySlp)
  109. Next
  110. End Function

  111. // 输入状态指令
  112. Function StateKey(KeyChr, KeyStk)
  113. If KeyStk Then
  114. // 设置按键状态
  115. Select Case KeyChr
  116. Case "8"
  117. KeyStkS_8 = True
  118. Case "2"
  119. KeyStkS_2 = True
  120. Case "4"
  121. KeyStkS_4 = True
  122. Case "6"
  123. KeyStkS_6 = True
  124. Case "7"
  125. KeyStkS_4 = True
  126. KeyStkS_8 = True
  127. Case "9"
  128. KeyStkS_6 = True
  129. KeyStkS_8 = True
  130. Case "1"
  131. KeyStkS_2 = True
  132. KeyStkS_4 = True
  133. Case "3"
  134. KeyStkS_2 = True
  135. KeyStkS_6 = True
  136. End Select
  137. // 开始按键
  138. If KeyStkS_8 Then Call dm.KeyDown(87)
  139. If KeyStkS_2 Then Call dm.KeyDown(83)
  140. If KeyStkS_4 Then Call dm.KeyDown(iif(PlayPos=1, 68, 65))
  141. If KeyStkS_6 Then Call dm.KeyDown(iif(PlayPos=1, 65, 68))
  142. Else
  143. // 恢复按键
  144. If KeyStkS_8 Then Call dm.KeyUp(87)
  145. If KeyStkS_2 Then Call dm.KeyUp(83)
  146. If KeyStkS_4 Then Call dm.KeyUp(iif(PlayPos=1, 68, 65))
  147. If KeyStkS_6 Then Call dm.KeyUp(iif(PlayPos=1, 65, 68))
  148. KeyStkS_8 = False
  149. KeyStkS_2 = False
  150. KeyStkS_4 = False
  151. KeyStkS_6 = False
  152. End If
  153. End Function

  154. // 输入指令
  155. Function InputKey(KeyChr, KeyStk)
  156. // 设置键位状态
  157. KeyStkN_8 = False
  158. KeyStkN_2 = False
  159. KeyStkN_4 = False
  160. KeyStkN_6 = False
  161. Select Case KeyChr
  162. Case "8" // ↑
  163. KeyStkN_8 = True
  164. Case "4" // ←
  165. KeyStkN_4 = True
  166. Case "6" // →
  167. KeyStkN_6 = True
  168. Case "2" // ↓
  169. KeyStkN_2 = True
  170. Case "7" // ↖
  171. KeyStkN_8 = True
  172. KeyStkN_4 = True
  173. Case "9" // ↗
  174. KeyStkN_8 = True
  175. KeyStkN_6 = True
  176. Case "1" // ↙
  177. KeyStkN_2 = True
  178. KeyStkN_4 = True
  179. Case "3" // ↘
  180. KeyStkN_2 = True
  181. KeyStkN_6 = True
  182. End Select
  183. // 释放旧按键
  184. If KeyStkO_8 Then
  185. If KeyStkN_8 = False Then
  186. Call dm.KeyUp(87)
  187. TracePrint "释放 ↑"
  188. End If
  189. End If
  190. If KeyStkO_2 Then
  191. If KeyStkN_2 = False Then
  192. Call dm.KeyUp(83)
  193. TracePrint "释放 ↓"
  194. End If
  195. End If
  196. If KeyStkO_4 Then
  197. If KeyStkN_4 = False Then
  198. Call dm.KeyUp(iif(PlayPos=1, 68, 65))
  199. TracePrint "释放 ←"
  200. End If
  201. End If
  202. If KeyStkO_6 Then
  203. If KeyStkN_6 = False Then
  204. Call dm.KeyUp(iif(PlayPos=1, 65, 68))
  205. TracePrint "释放 →"
  206. End If
  207. End If
  208. // 按下新按键
  209. If KeyStkN_8 Then
  210. If KeyStkO_8 = False Then
  211. Call dm.KeyDown(87)
  212. TracePrint "按下 ↑"
  213. End If
  214. End If
  215. If KeyStkN_2 Then
  216. If KeyStkO_2 = False Then
  217. Call dm.KeyDown(83)
  218. TracePrint "按下 ↓"
  219. End If
  220. End If
  221. If KeyStkN_4 Then
  222. If KeyStkO_4 = False Then
  223. Call dm.KeyDown(iif(PlayPos=1, 68, 65))
  224. TracePrint "按下 ←"
  225. End If
  226. End If
  227. If KeyStkN_6 Then
  228. If KeyStkO_6 = False Then
  229. Call dm.KeyDown(iif(PlayPos=1, 65, 68))
  230. TracePrint "按下 →"
  231. End If
  232. End If
  233. // 备份键位状态
  234. KeyStkO_8 = KeyStkN_8
  235. KeyStkO_2 = KeyStkN_2
  236. KeyStkO_4 = KeyStkN_4
  237. KeyStkO_6 = KeyStkN_6
  238. // 点击命令键
  239. Select Case KeyChr
  240. Case "A" // 轻拳
  241. If KeyStk Then
  242. Call dm.KeyDown(74)
  243. TracePrint "按下 A"
  244. Else
  245. Call dm.KeyUp(74)
  246. TracePrint "释放 A"
  247. End If
  248. Case "B" // 轻脚
  249. If KeyStk Then
  250. Call dm.KeyDown(75)
  251. TracePrint "按下 B"
  252. Else
  253. Call dm.KeyUp(75)
  254. TracePrint "释放 B"
  255. End If
  256. Case "C" // 重拳
  257. If KeyStk Then
  258. Call dm.KeyDown(76)
  259. TracePrint "按下 C"
  260. Else
  261. Call dm.KeyUp(76)
  262. TracePrint "释放 C"
  263. End If
  264. Case "D" // 重脚
  265. If KeyStk Then
  266. Call dm.KeyDown(85)
  267. TracePrint "按下 D"
  268. Else
  269. Call dm.KeyUp(85)
  270. TracePrint "释放 D"
  271. End If
  272. End Select
  273. Delay 30
  274. End Function


  275. // iif 函数
  276. Function iif(tz_var_exp, tz_var_true, tz_var_false)
  277. If tz_var_exp Then
  278. iif = tz_var_true
  279. Else
  280. iif = tz_var_false
  281. End If
  282. End Function


  283. //注册大漠
  284. Sub Register()
  285. Set ws = CreateObject("Wscript.Shell")
  286. ws.run "regsvr32 atl.dll /s",1,True
  287. Set ws = Nothing
  288. PutAttachment "c:\tz_kof", "*"
  289. PutAttachment ".\Plugin" ,"RegDll.dll"
  290. Call Plugin.RegDll.Reg("c:\tz_kof\dm.dll")
  291. Set dm = CreateObject("dm.dmsoft")
  292. ver = dm.ver()
  293. If len(ver) = 0 Then
  294. MessageBox "插件注册失败,检查系统是否禁用了vbs脚本权限"
  295. EndScript
  296. End If
  297. End Sub

  298. Sub OnScriptExit()
  299. Call dm.UnBindWindow()
  300. End Sub
复制代码
Q文件下载:
您所在的用户组无法下载或查看附件





本文按键学院提供技术支持

【招生】主流回合制常见功能网络辅助教学——你懂得!





    已有1评分我要评分查看所有评分

    本主题由 超级版主 瑞祥幽冥狼 于 2023/9/9 9:08:14 执行 审核帖子 操作
    按键学院免费交流群:376122403

    按键学院招生计划
    按键学院系统教程
    2#

    阿斯达斯阿斯达斯的

    3#

    厉害了

    4#

    看看

    5#

    可以用在腾讯的平台么??

    6#

    11111111111111111111111111111111

    7#


    8#


    9#

    0.0拳皇拳皇拳皇拳皇拳皇拳皇拳皇拳皇拳皇拳皇拳皇拳皇拳皇拳皇拳皇

    10#

    阿斯达斯

    11#

    路过参观.

    12#

    大神大神 顶礼膜拜

    13#

    E:【院刊】-【201502期】拳皇战斗脚本——模拟招式成功率百分百修改

    14#

    感谢楼主分享

    15#

    发给他回法国恢复

    16#

    好东西

    17#

    这个太厉害了!

    18#

    666呀

    19#

    学习一下

    20#

    学习学习学习学习学习学习学习学习

    发新话题 回复该主题