按键有屎以来最智能寻路系列之二

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

按键有屎以来最智能寻路系列之二

楼层直达
按键学院

ZxID:61232169

等级: 列兵
举报 图酷模式  只看楼主 使用道具 楼主   发表于: 2015-04-09 0
按键有屎以来最智能寻路系列之二
换算地图坐标寻路法

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



引用
上周跟大家介绍了关于游戏地图的寻路方式,也以烈焰游戏无题材向大家分享了下最简单的寻路方法—直接输入坐标寻路法(没看过的童鞋可以参考:按键有屎以来最智能寻路系列),看过之后,想必大家对游戏的寻路方式有了一定的认知,小编今天再跟大家分享下进阶版的寻路方法,即换算地图坐标寻路法



换算地图坐标寻路法

引用
神马叫换算游戏坐标寻路法呢?顾名思义就是游戏地图上显示的坐标跟我们屏幕实际坐标不一致,需要通过相应关系的换算才能算出地图坐标相对于屏幕实际坐标的偏移量,然后鼠标相对偏移量点击地图某位置后即可自动进行寻路,听到这里估计大家还是不大懂,没关系,下面小编就以神途游戏为例子,跟大家深度解析下


游戏地图

图上左上角红色的点0,0为游戏地图的起始坐标,
右下角红色的点为游戏地图的终点坐标830,690,
但是实际上我们用qq截图功能对地图区域进行截图
会发现该地图图片的实际大小大概只有660*415像素,
除了游戏初始(0,0)坐标跟实际鼠标偏移坐标一致外,
其他游戏地图坐标跟实际鼠标偏移坐标都是不一致的
再进一步来讲就是相对于游戏地图初始点坐标(0,0)来讲
游戏坐标(830,690)=实际鼠标偏移坐标(660,412)
那根据这个关系我们怎么进行坐标换算呢
坐标换算
该游戏地图的大小都是660*412像素(实际是600*375,上传到论坛变大了,为了方便对照,我们就以上面的图片为例),那比如我们当前人物如上图所示坐标是(258,266),游戏地图最大坐标是(830,690),那么相对于游戏地图起始坐标(0,0)点来讲,我们人物角色当前的所在位置(也就是地图上橘黄色的点的中心位置)就应该等于:
实际偏移X坐标=int(660/830*258)=205
实际偏移Y坐标=int(412/690*266)=159


到底对不对呢,我们不妨用大漠综合工具的浮动抓图功能截取上面的图片来验证看看:  
有图有真相,事实证明小编的计算是正确的


思路流程


技术难点:
1.地图名不一样所对应的地图最大X、Y坐标都不一样

2.如何确定地图初始点(0,0)位置,然后进行坐标换算后偏移
3.移动过程中,如何判断人物是否已经移动到了指定坐标点,开始下一步动作



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


因为是单开脚本,顶层窗口句柄就是游戏所对应的客户区句柄,所有用的是大漠的findwindow命令,查找符合类名或者标题名的顶层    可见窗口

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

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

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


判断地图名


游戏左下角会显示地图名及坐标,由于游戏不同的地图对应的游戏最大X坐标、Y坐标都是不一样的,所以我们要先识别当前的地图名,然后根据识别到的地图名对最大X坐标、Y坐标进行相应赋值,由于左下角会显示地图名和坐标,相互之间有时会有影响,所以做了俩个字库(坐标字库、地图名字库),分开调用

打开地图

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


确定地图初始点坐标

找地图上的"复活区"字,找到后就会得到该字左上角第一点坐标(IntX,IntY)然后通过大漠工具精确抓图获取到地图初始点位置(0,0)相对于"复活区"    偏移的坐标


地图起始点X坐标=IntX-154
地图起始点Y坐标=IntY+31



判断寻路是否到达


这个在上一期的寻路院刊已经介绍过了,这边就不重复说明了,具体请查看院刊:按键有屎以来最智能寻路系列

整体代码
  1. Call 注册大漠()
  2. Set dm = createobject("dm.dmsoft")//创建大漠对象
  3. Call 找句柄()
  4. Delay 100
  5. Call 大漠绑定()
  6. dm_ret = dm.SetPath("D:\test")//设置全局路径
  7. dm_ret = dm.SetDict(0, "神途地图名字库.txt")//设置字库为地图名字库为0号字库
  8. dm_ret = dm.SetExactOcr(1)//设置找字方式为精确查找,避免类似字符的干扰
  9. //地图起始点X坐标=找"复活区"字-155
  10. //地图起始点Y坐标=找"复活区"字+31
  11. Delay 1000
  12. Call 寻路(360, 360)
  13. Function 寻路(X坐标, Y坐标)
  14. Call 识别当前地图名//主要作用在于给当前地图最大X、Y坐标赋值
  15. dm_ret = dm.SetDict(1, "神途坐标字库.txt")//设置坐标字库为1号字库
  16. dm_ret = dm.UseDict(1)//使用1号字库来找字
  17. Call 找字
  18. Delay 1000
  19. x =int(600/地图最大X坐标*X坐标)
  20. y =int(375/地图最大Y坐标*Y坐标)
  21. TracePrint x
  22. TracePrint y
  23. dm.MoveTo intX-154+x,intY+31+y//相对于地图起始点坐标进行换算后的鼠标偏移点击
  24. Delay 1000
  25. dm.leftclick
  26. Do
  27. s = dm.Ocr(77,746,133,764, "ffffff-000000", 0.9)
  28. If len(s) > 0 Then
  29. 坐标 = split(s, ":")//分割游戏左下角显示的x、y坐标
  30. TracePrint "当前角色所在坐标为"&s
  31. // TracePrint cint(坐标(0))
  32. // TracePrint cint(坐标(1))
  33. If (abs(x坐标 - cint(坐标(0))) < 3) and (abs(y坐标 - cint(坐标(1))) < 3) Then //当前位置坐标与指定坐标的距离差的绝对值小于3则判断到达指定坐标
  34. dm.keypress 9////按tab关闭地图
  35. Call Plugin.Msg.Tips("到达指定坐标,寻路结束并关闭地图")//托盘信息提示到达指定坐标
  36. Exit Do
  37. Else Call Plugin.Msg.Tips("寻路中!!!当前角色所在坐标为"&s) //托盘信息提示还未到达指定坐标
  38. End If
  39. End If
  40. Delay 500
  41. Loop
  42. End Function
  43. Function 找字
  44. Do
  45. dm_ret = dm.FindStrFast(0, 0, w, h, "复活区", "ffe34a-000000", 0.9, intX, intY)
  46. If intX >= 0 and intY >= 0 Then
  47. TracePrint intX
  48. TracePrint intY
  49. Exit Do
  50. Else
  51. dm.keypress 9//按tab打开地图
  52. End If
  53. Delay 2000
  54. loop
  55. End Function
  56. Function 识别当前地图名
  57. Do
  58. s = dm.Ocr(4,728,200,768, "ffffff-000000", 0.8)//识别当前地图名
  59. If len(s) > 0 Then
  60. TracePrint s
  61. Select Case s
  62. Case "土城"//地图名是"土城"则对当前地图最大坐标赋值
  63. TracePrint "当前角色在土城"
  64. 地图最大X坐标=830
  65. 地图最大Y坐标 = 690
  66. Case "客栈一楼"//地图名是"客栈一楼"则对当前地图最大坐标赋值
  67. 地图最大X坐标=27
  68. 地图最大Y坐标 = 31
  69. // Case 其他···
  70. End Select
  71. Exit Do
  72. End If
  73. Delay 1000
  74. Loop
  75. End Function
  76. Function 找句柄
  77. For i = 0 To 20
  78. hwnd = dm.FindWindow("GAME","神途")
  79. Delay 2000
  80. If hwnd > 0 Then
  81. TracePrint hwnd
  82. dm_ret = dm.GetClientSize(hwnd,w,h) //获取窗口客户区大小
  83. TracePrint "游戏客户区宽度:" & w & ",高度:" & h
  84. dm_ret = dm.SetWindowState(hwnd, 1)
  85. Exit For
  86. Elseif i >= 20 Then MsgBox"未检测到游戏窗口,请确认游戏窗口已经打开"
  87. End If
  88. Next
  89. End Function
  90. Function 注册大漠()
  91. Dim i
  92. //释放附件内容
  93. PutAttachment "D:\test", "*.*"
  94. Set ws = createobject("Wscript.Shell")
  95. For i = 0 To 20
  96. //注册atl跟dm插件
  97. ws.run("regsvr32 atl.dll -s")
  98. ws.run ("regsvr32 D:\test\dm.dll -s")
  99. Delay 200
  100. Set ws = nothing
  101. Set dm = createobject("dm.dmsoft")
  102. ver = dm.ver()
  103. //输出版本号
  104. If ver <> "" Then
  105. Exit For
  106. End If
  107. Next
  108. If i >= 20 Then
  109. TracePrint "大漠插件注册失败!"
  110. EndScript
  111. End If
  112. Set dm = nothing
  113. Delay 10
  114. End Function
  115. Function 大漠绑定
  116. For i = 0 To 20
  117. dm_ret = dm.BindWindowEx(hwnd, "dx2", "windows", "windows", "", 0)'绑定窗口
  118. Delay 500
  119. If dm_ret = 1 Then
  120. TracePrint "绑定窗口成功"
  121. Exit For
  122. Elseif i>=20 Then TracePrint "绑定失败"
  123. End If
  124. Next
  125. End Function
  126. Sub OnScriptExit()//解绑大漠
  127. dm_ret = dm.UnBindWindow()
  128. End Sub






[ 此帖被按键学院在2015-04-09 15:35重新编辑 ]
« 返回列表
发帖 回复