很多玩家在魔域窗口模式使用按键精灵时会遇到一个问题,游戏属于复合窗口结构,直接抓取顶层窗口句柄之后,后台找色、找字命令无法读取画面像素,颜色识别一直返回找不到目标。想要正常使用后台找色和找字功能,核心就是找到游戏渲染画面对应的子窗口句柄,下面完整讲解句柄抓取、窗口绑定、后台找色找字代码编写以及调试过程里的各类问题。
前期环境设置要先做好。把魔域客户端切换窗口模式,不能最小化窗口,最小化之后渲染停止,画面读取失效。固定游戏窗口大小,不要随意缩放窗口,画面分辨率改动会直接改变像素坐标。关闭多余游戏特效,过高光影特效会干扰颜色取样,文字边缘出现光晕,导致找字识别失败。安装按键精灵,开启抓抓工具,准备好窗口句柄查看工具,用于遍历窗口子句柄。提前准备好目标颜色点和文字,在游戏画面里定位需要识别的文字或者色块,用于后续取样。
复合窗口原理需要简单了解。魔域主窗口只是一个容器,游戏实际渲染画面是内嵌的子窗口。直接抓取游戏主窗口得到的句柄,只是外层容器句柄,这个句柄不承载游戏画面像素数据。后台找色、找字、找图这类读取画面的插件命令,无法从外层容器句柄读取像素,所以一直识别不到颜色。必须遍历主窗口下所有子窗口,找到负责渲染游戏画面的子句柄,使用这个子句柄进行绑定,后台画面读取命令才能正常工作。
抓取子窗口句柄操作步骤。打开按键精灵自带的窗口工具,抓取魔域主窗口句柄,记录主窗口编号。在脚本中使用窗口遍历命令,枚举主窗口下全部子窗口,循环读取每个子窗口的句柄。依次对每一个子句柄进行测试,调用后台取色命令,读取游戏画面上已知坐标的颜色值。对比取色返回的颜色数值和画面实际颜色,数值一致的那个句柄就是渲染画面的有效子句柄。遍历子窗口过程中,会出现多个子句柄,有的是聊天框子窗口,有的是按钮控件窗口,这些都不能读取游戏场景画面,需要逐个排除。
句柄遍历测试参考代码,运行脚本输出所有子句柄,逐个验证。
HwndParent = Plugin.Window.Foreground()
Dim HwndChild
HwndChild = Plugin.Window.GetChildHwnd(HwndParent,0)
Do While HwndChild>0
TracePrint "子窗口句柄:" & HwndChild
HwndChild = Plugin.Window.GetChildHwnd(HwndParent,Plugin.Window.GetNextHwnd(HwndChild))
Loop
运行这段代码,在调试输出窗口打印全部子句柄,复制每一个句柄,单独写一段后台取色代码测试。取色测试代码如下:
Hwnd = 填入测试子句柄
Call Plugin.Window.Bind(Hwnd, "dx", "dx", "dx", 0)
cr = Plugin.Bkgnd.GetPixelColor(Hwnd, 200,200)
TracePrint cr
Call Plugin.Window.UnBind(Hwnd)
对比抓抓工具里窗口坐标200,200位置的颜色码,两者相同,代表当前子句柄有效。如果返回颜色为黑色或者固定无效数值,说明这个子窗口不承载游戏画面,继续更换下一个子句柄测试。
拿到有效子句柄之后,编写后台找色脚本。打开抓抓工具,切换到窗口坐标模式,选取目标色块,记录坐标范围、颜色值,设置颜色偏差,游戏画面存在轻微颜色波动,偏差一般设置10到30。后台找色完整示例代码。
HwndParent = Plugin.Window.Foreground()
HwndChild = Plugin.Window.GetChildHwnd(HwndParent,0)
Call Plugin.Window.Bind(HwndChild, "dx", "dx", "dx", 0)
Do
Call Plugin.Bkgnd.FindColor(HwndChild,0,0,800,600,"FFFFFF",20,intX,intY)
If intX > 0 And intY > 0 Then
TracePrint "找到颜色,坐标:" & intX & "," & intY
Call Plugin.Bkgnd.LeftClick(HwndChild,intX,intY)
Delay 800
End If
Delay 300
Loop
Call Plugin.Window.UnBind(HwndChild)
代码里0,0,800,600是画面搜索区域,根据窗口实际尺寸修改,FFFFFF替换成目标颜色,20是颜色偏差。找到颜色之后,执行后台左键点击,加入延时等待动作完成。
后台找字功能实现步骤。找字原理是提取文字点阵,需要先在按键精灵字库工具里截取游戏内目标文字,制作字库文件。游戏文字字体、字号、颜色不要改动,字体缩放或者抗锯齿会破坏点阵样本,造成识别失败。字库制作完成保存到脚本附件,使用后台插件读取画面,在指定区域匹配文字点阵。后台找字示例代码。
HwndParent = Plugin.Window.Foreground()
HwndChild = Plugin.Window.GetChildHwnd(HwndParent,0)
Call Plugin.Window.Bind(HwndChild, "dx", "dx", "dx", 0)
Do
Call Plugin.Bkgnd.FindStr(HwndChild,0,0,400,300,"击杀","Attachment:\ziku.txt",0.9,intX,intY)
If intX > 0 And intY > 0 Then
TracePrint "识别到文字"
Delay 800
End If
Delay 500
Loop
Call Plugin.Window.UnBind(HwndChild)
代码中0,0,400,300为文字搜索区域,击杀替换为需要识别的内容,ziku.txt是自己制作的字库文件,0.9为匹配相似度。
常见问题排查。第一种情况,遍历到子句柄,后台取色依旧返回黑色。这类情况大多是绑定模式不匹配,可以更换绑定参数,dx、gdi模式交替测试。部分渲染模式下,后台插件无法读取画面像素,此时只能改用前台找色找字,前台模式鼠标不能移动。第二种情况,句柄每次重启游戏发生变化。每次重新打开魔域客户端,子窗口句柄会变动,所以每次上线都需要重新遍历获取子句柄,不能直接写死固定句柄在脚本内。第三种情况,找字识别不稳定。游戏文字自带阴影、描边,会干扰点阵匹配,尽量关闭画面文字特效,取样的时候选取纯色文字区域,字库样本多做几个不同状态下的文字,提升识别成功率。
还有一些使用方面的要点。复合窗口不能使用顶层句柄进行画面读取,这是最容易踩坑的地方,很多人直接抓取主窗口反复调试,一直无法识别颜色。窗口绑定成功之后,脚本的找色、找字、点击命令都要统一使用子句柄,不能混用顶层句柄和子句柄。窗口不能最小化,最小化后显卡停止渲染,后台读取像素失效,窗口可以被其他窗口遮挡,只要不最小化就能正常识别。游戏切换分辨率,窗口大小改动,子句柄对应的画面坐标全部失效,需要重新取样颜色、文字坐标。
长时间运行脚本时,要留意游戏窗口渲染卡顿问题。电脑性能不足,画面渲染延迟,读取到的像素不是实时画面,颜色识别出现错位。可以适当加大循环延时,降低画面读取频率,减少资源占用。不要同时开启多个游戏窗口,多窗口同时遍历子句柄,句柄获取逻辑会发生冲突,导致识别错乱。如果更换绑定模式之后,后台依旧无法读取像素,属于游戏渲染机制限制,这种情况下无法实现后台画面识别,只能切换前台模式完成找色找字操作。
前期环境设置要先做好。把魔域客户端切换窗口模式,不能最小化窗口,最小化之后渲染停止,画面读取失效。固定游戏窗口大小,不要随意缩放窗口,画面分辨率改动会直接改变像素坐标。关闭多余游戏特效,过高光影特效会干扰颜色取样,文字边缘出现光晕,导致找字识别失败。安装按键精灵,开启抓抓工具,准备好窗口句柄查看工具,用于遍历窗口子句柄。提前准备好目标颜色点和文字,在游戏画面里定位需要识别的文字或者色块,用于后续取样。
复合窗口原理需要简单了解。魔域主窗口只是一个容器,游戏实际渲染画面是内嵌的子窗口。直接抓取游戏主窗口得到的句柄,只是外层容器句柄,这个句柄不承载游戏画面像素数据。后台找色、找字、找图这类读取画面的插件命令,无法从外层容器句柄读取像素,所以一直识别不到颜色。必须遍历主窗口下所有子窗口,找到负责渲染游戏画面的子句柄,使用这个子句柄进行绑定,后台画面读取命令才能正常工作。
抓取子窗口句柄操作步骤。打开按键精灵自带的窗口工具,抓取魔域主窗口句柄,记录主窗口编号。在脚本中使用窗口遍历命令,枚举主窗口下全部子窗口,循环读取每个子窗口的句柄。依次对每一个子句柄进行测试,调用后台取色命令,读取游戏画面上已知坐标的颜色值。对比取色返回的颜色数值和画面实际颜色,数值一致的那个句柄就是渲染画面的有效子句柄。遍历子窗口过程中,会出现多个子句柄,有的是聊天框子窗口,有的是按钮控件窗口,这些都不能读取游戏场景画面,需要逐个排除。
句柄遍历测试参考代码,运行脚本输出所有子句柄,逐个验证。
HwndParent = Plugin.Window.Foreground()
Dim HwndChild
HwndChild = Plugin.Window.GetChildHwnd(HwndParent,0)
Do While HwndChild>0
TracePrint "子窗口句柄:" & HwndChild
HwndChild = Plugin.Window.GetChildHwnd(HwndParent,Plugin.Window.GetNextHwnd(HwndChild))
Loop
运行这段代码,在调试输出窗口打印全部子句柄,复制每一个句柄,单独写一段后台取色代码测试。取色测试代码如下:
Hwnd = 填入测试子句柄
Call Plugin.Window.Bind(Hwnd, "dx", "dx", "dx", 0)
cr = Plugin.Bkgnd.GetPixelColor(Hwnd, 200,200)
TracePrint cr
Call Plugin.Window.UnBind(Hwnd)
对比抓抓工具里窗口坐标200,200位置的颜色码,两者相同,代表当前子句柄有效。如果返回颜色为黑色或者固定无效数值,说明这个子窗口不承载游戏画面,继续更换下一个子句柄测试。
拿到有效子句柄之后,编写后台找色脚本。打开抓抓工具,切换到窗口坐标模式,选取目标色块,记录坐标范围、颜色值,设置颜色偏差,游戏画面存在轻微颜色波动,偏差一般设置10到30。后台找色完整示例代码。
HwndParent = Plugin.Window.Foreground()
HwndChild = Plugin.Window.GetChildHwnd(HwndParent,0)
Call Plugin.Window.Bind(HwndChild, "dx", "dx", "dx", 0)
Do
Call Plugin.Bkgnd.FindColor(HwndChild,0,0,800,600,"FFFFFF",20,intX,intY)
If intX > 0 And intY > 0 Then
TracePrint "找到颜色,坐标:" & intX & "," & intY
Call Plugin.Bkgnd.LeftClick(HwndChild,intX,intY)
Delay 800
End If
Delay 300
Loop
Call Plugin.Window.UnBind(HwndChild)
代码里0,0,800,600是画面搜索区域,根据窗口实际尺寸修改,FFFFFF替换成目标颜色,20是颜色偏差。找到颜色之后,执行后台左键点击,加入延时等待动作完成。
后台找字功能实现步骤。找字原理是提取文字点阵,需要先在按键精灵字库工具里截取游戏内目标文字,制作字库文件。游戏文字字体、字号、颜色不要改动,字体缩放或者抗锯齿会破坏点阵样本,造成识别失败。字库制作完成保存到脚本附件,使用后台插件读取画面,在指定区域匹配文字点阵。后台找字示例代码。
HwndParent = Plugin.Window.Foreground()
HwndChild = Plugin.Window.GetChildHwnd(HwndParent,0)
Call Plugin.Window.Bind(HwndChild, "dx", "dx", "dx", 0)
Do
Call Plugin.Bkgnd.FindStr(HwndChild,0,0,400,300,"击杀","Attachment:\ziku.txt",0.9,intX,intY)
If intX > 0 And intY > 0 Then
TracePrint "识别到文字"
Delay 800
End If
Delay 500
Loop
Call Plugin.Window.UnBind(HwndChild)
代码中0,0,400,300为文字搜索区域,击杀替换为需要识别的内容,ziku.txt是自己制作的字库文件,0.9为匹配相似度。
常见问题排查。第一种情况,遍历到子句柄,后台取色依旧返回黑色。这类情况大多是绑定模式不匹配,可以更换绑定参数,dx、gdi模式交替测试。部分渲染模式下,后台插件无法读取画面像素,此时只能改用前台找色找字,前台模式鼠标不能移动。第二种情况,句柄每次重启游戏发生变化。每次重新打开魔域客户端,子窗口句柄会变动,所以每次上线都需要重新遍历获取子句柄,不能直接写死固定句柄在脚本内。第三种情况,找字识别不稳定。游戏文字自带阴影、描边,会干扰点阵匹配,尽量关闭画面文字特效,取样的时候选取纯色文字区域,字库样本多做几个不同状态下的文字,提升识别成功率。
还有一些使用方面的要点。复合窗口不能使用顶层句柄进行画面读取,这是最容易踩坑的地方,很多人直接抓取主窗口反复调试,一直无法识别颜色。窗口绑定成功之后,脚本的找色、找字、点击命令都要统一使用子句柄,不能混用顶层句柄和子句柄。窗口不能最小化,最小化后显卡停止渲染,后台读取像素失效,窗口可以被其他窗口遮挡,只要不最小化就能正常识别。游戏切换分辨率,窗口大小改动,子句柄对应的画面坐标全部失效,需要重新取样颜色、文字坐标。
长时间运行脚本时,要留意游戏窗口渲染卡顿问题。电脑性能不足,画面渲染延迟,读取到的像素不是实时画面,颜色识别出现错位。可以适当加大循环延时,降低画面读取频率,减少资源占用。不要同时开启多个游戏窗口,多窗口同时遍历子句柄,句柄获取逻辑会发生冲突,导致识别错乱。如果更换绑定模式之后,后台依旧无法读取像素,属于游戏渲染机制限制,这种情况下无法实现后台画面识别,只能切换前台模式完成找色找字操作。

