【院刊】-【201504期】按键有屎以来最智能寻路系列

社区服务
高级搜索
猴岛论坛辅助工具【院刊】-【201504期】按键有屎以来最智能寻路系列
发帖 回复
倒序阅读 最近浏览的帖子最近浏览的版块
0个回复

【院刊】-【201504期】按键有屎以来最智能寻路系列

楼层直达
mimi_rice

ZxID:55494225

等级: 上士
举报 只看楼主 使用道具 楼主   发表于: 2015-04-02 0
按键有屎以来最智能寻路系列
直接输入坐标即时寻路

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




众所周知,自动寻路是脚本编写中非常重要的一环,如何高效并稳定的实现让脚本模拟人工操作进行智能自动寻路成为脚本编写的必修课之一,然而是通过什么让游戏角色可以自动寻路呢?小编认为百分之九十九的游戏自动寻路方式都依赖于本身的游戏地图,擅用游戏地图对我们写脚本往往有事半功倍的效果,所以本期小编打算从易到难出一个关于自动寻路系列的院刊,希望大家多多支持哈~





地图寻路方式
关于游戏的地图寻路方式,小编认为可以大致分为这几类:
  


以上纯属个人看法,个人玩过的游戏及思维能力有限,有补充和其他想法的童鞋欢迎回帖说明,小编会不定时查看的,小编今天就以烈焰这款网页游戏为例,跟大家分享下第1种最简单的—直接输入坐标寻路方法

游戏地图


从图上我们就能比较直观的看出这款游戏一个大概的寻路流程

思路流程



技术难点:
1.X、Y字符不是纯色的,并且X、Y字符偏色程度也是不一样的
2.游戏输入坐标处默认会保存一个0,并且每次打开地图不会自动清空上一次输入的坐标,如何才能正确的输入寻路坐标
3.移动过程中,如何判断人物是否已经移动到了指定坐标点,开始下一步动作



绑定窗口

今天我们写的脚本有用到大漠插件,并且是后台的

因为是单开脚本,并且客户区句柄隐藏的也比较深,所以用的是FindWindowSuper命令,该命令内容较多,具体说明请查看大漠接口说明

后台绑定模式:
      图色模式:dx2
      鼠标模式:windows
      键盘模式:windows

关于大漠绑定模式如何获知
请参阅相关院刊:

【院刊】-【201501期】沙盘后台绑定游戏




打开地图
为了避免地图已经打开的情况
我们要先判断地图有没有打开,没有打开的话才去按M键打开地图
因为后面我们找字的时候就是要在地图上找字,所以我们先进行找字
没找到字的情况下说明地图没打开,再按m键打开地图



大漠找字
因为要分别找X、Y、前往字符,为了降低代码重复度,
所以我们应该想到把找字做成一个带参数的函数,
参数为要找的字符、偏色、相似度,
找到X、Y字符的时候我们要进行计算,
找到后进行相应的坐标偏移才能准确点到坐标输入框,
然而找字符"前往"的话坐标不需要偏移。
所以我们在代码里要加入判断当前查找的字符是不是"前往",
如果是的话执行不一样的移动操作

相关代码
  1. Function 找字(string, color_format, sim)
  2. dm_ret = dm.SetExactOcr(1)//设置找字方式为精确查找,避免类似字符的干扰
  3. Do
  4. dm_ret=dm.FindStrFast(0,0,w,h,string,color_format,sim,intX,intY)
  5. If intX > 0 and string<>"前往"Then //找到X、Y字符的操作
  6. TracePrint "找到了"
  7. Delay 100
  8. dm.MoveTo intX + 66, intY + 8//鼠标漂移相应坐标后点击输入框
  9. Delay 100
  10. dm.LeftClick
  11. Delay 100
  12. Call 清除坐标
  13. Exit Do
  14. Elseif intX > 0 and string="前往" Then //找到前往字符的操作
  15. dm.MoveTo intX , intY
  16. Delay 100
  17. dm.LeftClick
  18. Exit Do
  19. Else
  20. TracePrint "地图没打开,所以找不到"
  21. dm.KeyPress 77//按M键打开地图
  22. End If
  23. Delay 100
  24. Loop
  25. End Function


输入坐标后点击前往后,人物就开始移动了
那怎么才能知道人物已经移动到指定点了呢?
小编认为最简便的方法就是莫过于用大漠的IsDisplayDead函数来判断了,
关于这个函数的说明与使用方法已经在之前的院刊已经重点的介绍过了,
有不懂的童鞋可以查看:【院刊】-【201503期】寻路中判断人物是否停止行走
那除了使用这个函数的方法外或者我们本身不知道有这个函数的话,是否还有其他方法呢?
答案显示是有的,小编今天就再给大家重点介绍一个识别数字后分割坐标的方法



坐标识别法


如图所示,很多游戏小地图上通常都是类似这样显示当前坐标的,而且坐标的颜色通常都是固定的,所以我们不妨分别提取出0-9的数字,以及逗号做成一个独立字库,不会使用大漠做字库的童鞋可以参考:如何利用大漠综合工具自作字库

字库做完后,我们就可以通过这个字库使用大漠插件的Ocr函数来识别这个范围的坐标值了,因为里面刚好有个逗号,我们就可以用逗号来分割出X坐标和Y坐标,通过循环一直获取坐标与我们要寻路到达的坐标作比较,由于这个游戏寻路到达坐标的时候坐标都会少1,所以我们用绝对值来对比距离差,允许些许容差

命令名称Ocr
命令功能识别屏幕范围(x1,y1,x2,y2)内符合color_format的字符串,并且相似度为sim,sim取值范围(0.1-1.0)
命令参数x1 整形数:区域的左上X坐标
y1 整形数:区域的左上Y坐标
x2 整形数:区域的右下X坐标
y2 整形数:区域的右下Y坐标
color_format 字符串:颜色格式串.
RGB和HSV颜色格式都支持.
sim 双精度浮点数:相似度,取值范围0.1-1.0
返 回 值字符串:
返回识别到的字符串

相关代码
  1. Do
  2.         s = dm.Ocr(500, 30, w, h, "ff9912-000000", 0.9)
  3.         If len(s) > 0 Then
  4.             TracePrint "找到了"
  5.             坐标 = split(s, ",")
  6.             TracePrint cint(坐标(0))//即当前位置X坐标
  7.             TracePrint cint(坐标(1))//即当前位置Y坐标
  8.             If (abs(x坐标 -cint(坐标(0)))<3) and (abs(y坐标 - cint(坐标(1)))<3) Then //当前位置坐标与指定坐标的距离差的绝对值小于3则判断到达指定坐标
  9.                 Call Plugin.Msg.Tips("到达指定坐标,寻路结束")//托盘信息提示到达指定坐标
  10.                 Exit Do
  11.                 Else  Call Plugin.Msg.Tips("寻路中!!!") //托盘信息提示还未到达指定坐标
  12.             End If
  13.         End If
  14.         Delay 500//每隔500毫秒检测一次,可自定义
  15.     Loop[/color][/blockquote]

小拓展:小编这里只是用坐标做是否寻路到达的判断,
其实通过识别游戏的当前坐标我们可以做很多其他判断和操作的,
当然这是个仁者见仁、智者见智的问题了,小编在此就不讨论了


整体代码
  
  1. Call 找字("X", "A6AB56-0C0E35", 0.9)//找地图上的X字
  2. dm.SendString hwnd,cstr(x坐标)//向后台窗口输入X坐标(这里要注意类型需要转换下)
  3. Delay 500
  4. Call 找字("Y", "A8AE42-0C1343", 0.9)//找地图上的Y字
  5. dm.SendString hwnd, cstr(y坐标)//向后台窗口输入Y坐标(这里要注意类型需要转换下)
  6. Delay 500
  7. Call 找字("前往", "f2e627-000000", 0.9)//找小地图上的前往字符
  8. //以下代码是每隔500毫秒,识别一下当前位置坐标与指定坐标的距离差,循环判断是否到达指定坐标
  9. Do
  10. s = dm.Ocr(500, 30, w, h, "ff9912-000000", 0.9)
  11. If len(s) > 0 Then
  12. 坐标 = split(s, ",")
  13. TracePrint "当前角色所在x坐标为"&s
  14. // TracePrint cint(坐标(0))
  15. // TracePrint cint(坐标(1))
  16. If (abs(x坐标 - cint(坐标(0))) < 3) and (abs(y坐标 - cint(坐标(1))) < 3) Then //当前位置坐标与指定坐标的距离差的绝对值小于3则判断到达指定坐标
  17. dm.keypress 77//关闭地图
  18. Call Plugin.Msg.Tips("到达指定坐标,寻路结束并关闭地图")//托盘信息提示到达指定坐标
  19. Exit Do
  20. Else Call Plugin.Msg.Tips("寻路中!!!") //托盘信息提示还未到达指定坐标
  21. End If
  22. End If
  23. Delay 500
  24. Loop
  25. End Function
  26. Function 找字(string, color_format, sim)
  27. dm_ret = dm.SetExactOcr(1)//设置找字方式为精确查找,避免类似字符的干扰
  28. Do
  29. dm_ret=dm.FindStrFast(0,0,w,h,string,color_format,sim,intX,intY)
  30. If intX > 0 and string<>"前往"Then //找到X、Y字符的操作
  31. TracePrint "找到地图了"
  32. TracePrint "x字符坐标为"&intx
  33. TracePrint "y字符坐标为" & inty
  34. Delay 100
  35. dm.MoveTo intX + 66, intY + 8//鼠标漂移相应坐标后点击输入框
  36. Delay 100
  37. dm.LeftClick
  38. Delay 100
  39. Call 清除坐标
  40. Exit Do
  41. Elseif intX > 0 and string="前往" Then //找到前往字符的操作
  42. dm.MoveTo intX , intY
  43. Delay 100
  44. dm.LeftClick
  45. TracePrint"点击前往按钮"
  46. Exit Do
  47. Else
  48. TracePrint "未找到地图,按m键打开地图"
  49. Delay 100
  50. dm.KeyPress 77//按M键打开小地图
  51. End If
  52. Delay 100
  53. Loop
  54. End Function
  55. Function 清除坐标
  56. For 10 //打开小地图后按10次backspace键先对原先的坐标进行清除
  57. dm.keypress 8
  58. Delay 100
  59. Next
  60. TracePrint "清空地图初始坐标"
  61. dm.keypress 39//按右方向键一次保证坐标不会被0影响
  62. End Function
  63. Function 找句柄
  64. For i = 0 To 20
  65. hwnd = dm.FindWindowSuper("MacromediaFlashPlayerActiveX",2,1,"Internet Explorer_Server",6,0) //根据俩组设置条件,获得烈焰窗口句柄
  66. Delay 2000
  67. If hwnd > 0 Then
  68. TracePrint hwnd
  69. dm_ret = dm.GetClientSize(hwnd,w,h) //获取窗口客户区大小
  70. TracePrint "游戏客户区宽度:" & w & ",高度:" & h
  71. dm_ret = dm.SetWindowState(hwnd, 1)
  72. Exit For
  73. Elseif i >= 20 Then MsgBox"未检测到游戏窗口,请确认游戏窗口已经打开"
  74. End If
  75. Next
  76. End Function
  77. Function 注册大漠()
  78. Dim i
  79. //释放附件内容
  80. PutAttachment "D:\test", "*.*"
  81. Set ws = createobject("Wscript.Shell")
  82. For i = 0 To 20
  83. //注册atl跟dm插件
  84. ws.run("regsvr32 atl.dll -s")
  85. ws.run ("regsvr32 D:\test\dm.dll -s")
  86. Delay 200
  87. Set ws = nothing
  88. Set dm = createobject("dm.dmsoft")
  89. ver = dm.ver()
  90. //输出版本号
  91. If ver <> "" Then
  92. Exit For
  93. End If
  94. Next
  95. If i >= 20 Then
  96. TracePrint "大漠插件注册失败!"
  97. EndScript
  98. End If
  99. Set dm = nothing
  100. Delay 10
  101. End Function
  102. Function 大漠绑定
  103. For i = 0 To 20
  104. dm_ret = dm.BindWindowEx(hwnd, "dx2", "windows", "windows", "", 0)'绑定窗口
  105. Delay 500
  106. If dm_ret = 1 Then
  107. TracePrint "绑定窗口成功"
  108. Exit For
  109. Elseif i>=20 Then TracePrint "绑定失败"
  110. End If
  111. Next
  112. End Function
  113. Sub OnScriptExit()//解绑大漠
  114. dm_ret = dm.UnBindWindow()
  115. End Sub
后记
关于初级寻路今天就介绍到这里了,欲知其他寻路方式的解决办法,请听下回分解!



[ 此帖被mimi_rice在2015-04-02 12:17重新编辑 ]
« 返回列表
发帖 回复