-
关注Ta
-
- 注册时间 2015-03-31
- 最后登录 2015-06-01
-
- 发帖9
- 在线1小时
- 精华0
- DB26
- 威望0
- 保证金0
- 桃子0
- 鲜花0
- 鸡蛋0
-
访问TA的空间加好友用道具
|
按键有屎以来最智能寻路系列之二 换算地图坐标寻路法 本文由按键学院提供技术支持 引用 上周跟大家介绍了关于游戏地图的寻路方式,也以烈焰游戏无题材向大家分享了下最简单的寻路方法—直接输入坐标寻路法(没看过的童鞋可以参考:按键有屎以来最智能寻路系列),看过之后,想必大家对游戏的寻路方式有了一定的认知,小编今天再跟大家分享下进阶版的寻路方法,即换算地图坐标寻路法 换算地图坐标寻路法 引用 神马叫换算游戏坐标寻路法呢?顾名思义就是游戏地图上显示的坐标跟我们屏幕实际坐标不一致,需要通过相应关系的换算才能算出地图坐标相对于屏幕实际坐标的偏移量,然后鼠标相对偏移量点击地图某位置后即可自动进行寻路,听到这里估计大家还是不大懂,没关系,下面小编就以神途游戏为例子,跟大家深度解析下 游戏地图 图上左上角红色的点0,0为游戏地图的起始坐标, 右下角红色的点为游戏地图的终点坐标830,690, 会发现该地图图片的实际大小大概只有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 判断寻路是否到达 这个在上一期的寻路院刊已经介绍过了,这边就不重复说明了,具体请查看院刊: 按键有屎以来最智能寻路系列 整体代码- Call 注册大漠()
- Set dm = createobject("dm.dmsoft")//创建大漠对象
- Call 找句柄()
- Delay 100
- Call 大漠绑定()
- dm_ret = dm.SetPath("D:\test")//设置全局路径
- dm_ret = dm.SetDict(0, "神途地图名字库.txt")//设置字库为地图名字库为0号字库
- dm_ret = dm.SetExactOcr(1)//设置找字方式为精确查找,避免类似字符的干扰
- //地图起始点X坐标=找"复活区"字-155
- //地图起始点Y坐标=找"复活区"字+31
- Delay 1000
- Call 寻路(360, 360)
- Function 寻路(X坐标, Y坐标)
- Call 识别当前地图名//主要作用在于给当前地图最大X、Y坐标赋值
- dm_ret = dm.SetDict(1, "神途坐标字库.txt")//设置坐标字库为1号字库
- dm_ret = dm.UseDict(1)//使用1号字库来找字
- Call 找字
- Delay 1000
- x =int(600/地图最大X坐标*X坐标)
- y =int(375/地图最大Y坐标*Y坐标)
- TracePrint x
- TracePrint y
- dm.MoveTo intX-154+x,intY+31+y//相对于地图起始点坐标进行换算后的鼠标偏移点击
- Delay 1000
- dm.leftclick
- Do
- s = dm.Ocr(77,746,133,764, "ffffff-000000", 0.9)
- If len(s) > 0 Then
- 坐标 = split(s, ":")//分割游戏左下角显示的x、y坐标
- TracePrint "当前角色所在坐标为"&s
- // TracePrint cint(坐标(0))
- // TracePrint cint(坐标(1))
- If (abs(x坐标 - cint(坐标(0))) < 3) and (abs(y坐标 - cint(坐标(1))) < 3) Then //当前位置坐标与指定坐标的距离差的绝对值小于3则判断到达指定坐标
- dm.keypress 9////按tab关闭地图
- Call Plugin.Msg.Tips("到达指定坐标,寻路结束并关闭地图")//托盘信息提示到达指定坐标
- Exit Do
- Else Call Plugin.Msg.Tips("寻路中!!!当前角色所在坐标为"&s) //托盘信息提示还未到达指定坐标
- End If
- End If
- Delay 500
- Loop
- End Function
- Function 找字
- Do
- dm_ret = dm.FindStrFast(0, 0, w, h, "复活区", "ffe34a-000000", 0.9, intX, intY)
- If intX >= 0 and intY >= 0 Then
- TracePrint intX
- TracePrint intY
- Exit Do
- Else
- dm.keypress 9//按tab打开地图
- End If
- Delay 2000
- loop
- End Function
- Function 识别当前地图名
- Do
- s = dm.Ocr(4,728,200,768, "ffffff-000000", 0.8)//识别当前地图名
- If len(s) > 0 Then
- TracePrint s
- Select Case s
- Case "土城"//地图名是"土城"则对当前地图最大坐标赋值
- TracePrint "当前角色在土城"
- 地图最大X坐标=830
- 地图最大Y坐标 = 690
- Case "客栈一楼"//地图名是"客栈一楼"则对当前地图最大坐标赋值
- 地图最大X坐标=27
- 地图最大Y坐标 = 31
- // Case 其他···
- End Select
- Exit Do
- End If
- Delay 1000
- Loop
- End Function
- Function 找句柄
- For i = 0 To 20
- hwnd = dm.FindWindow("GAME","神途")
- Delay 2000
- If hwnd > 0 Then
- TracePrint hwnd
- dm_ret = dm.GetClientSize(hwnd,w,h) //获取窗口客户区大小
- TracePrint "游戏客户区宽度:" & w & ",高度:" & h
- dm_ret = dm.SetWindowState(hwnd, 1)
- Exit For
- Elseif i >= 20 Then MsgBox"未检测到游戏窗口,请确认游戏窗口已经打开"
- End If
- Next
- End Function
- Function 注册大漠()
- Dim i
- //释放附件内容
- PutAttachment "D:\test", "*.*"
- Set ws = createobject("Wscript.Shell")
- For i = 0 To 20
- //注册atl跟dm插件
- ws.run("regsvr32 atl.dll -s")
- ws.run ("regsvr32 D:\test\dm.dll -s")
- Delay 200
- Set ws = nothing
- Set dm = createobject("dm.dmsoft")
- ver = dm.ver()
- //输出版本号
- If ver <> "" Then
- Exit For
- End If
- Next
- If i >= 20 Then
- TracePrint "大漠插件注册失败!"
- EndScript
- End If
- Set dm = nothing
- Delay 10
- End Function
- Function 大漠绑定
- For i = 0 To 20
- dm_ret = dm.BindWindowEx(hwnd, "dx2", "windows", "windows", "", 0)'绑定窗口
- Delay 500
- If dm_ret = 1 Then
- TracePrint "绑定窗口成功"
- Exit For
- Elseif i>=20 Then TracePrint "绑定失败"
- End If
- Next
- End Function
- Sub OnScriptExit()//解绑大漠
- dm_ret = dm.UnBindWindow()
- End Sub
[ 此帖被按键学院在2015-04-09 15:35重新编辑 ]
|