前言
当初我通过 ahk自带的 pixelsearch 和 pixelgetcolor 函数做自动拾取,那叫一个痛苦,通过一个点一个点往下判定,一个功能写了百来行代码,又臭又长,效率还低,以至于到后来我几乎失去了维护的心思。
直到某天发现飞跃大佬的Findtext,用十几行代码完成了之前同样的功能,执行效率翻了好几倍,那真是山重水复疑无路,柳暗花明又一村,即使滔滔江水之多的溢美之词也难以描述那一刻我对飞跃大佬的崇拜之情!!
飞跃 大佬??就完事了!
分享一下我的代码,顺便说下思路,也算是一篇Findtext的使用指南
Ⅰ:
在原神这款游戏里,在出现可对话的对象时,会出现一个图标“F”,以此作为依据就可以知道有没有东西可以拾取
随后确定这个图标会出现的最大范围
但是仅仅这样判断是不行的,因为还有不少东西(对话、烹饪之类)是不需要自动点的,所幸通过图标可以判断出来。
增加横向的判定范围
通过统计后,我发现不需要点的东西比较少,所以做排除,识别到这类就不点击
一个个排除吗?嘿,怎么可能,要这样当初我的代码就不止百来行了
使用PS将两张图完全重叠,使用 变暗 叠加方式,剩下的就是两个图标的重叠部分
7个图标重叠后,剩下一小块共有区域。
此时,只要判断一次,就能确定这个东西在不在不可点击范围内
Ⅱ:
这时打开Findtext的GUI,调整到能囊括两个图标的大小,抓图
我使用的是 多色查找 这一栏
找好特征点,依次点击
得到一段Findtext数据,这是不可点击的部分
Text:="|<NF>##15$0/0/FFFFFF,12/7/343434,16/13/FFFFFF,21/15/727272,83/3/FFFFFF,79/10/F5F5F5,93/28/FFFFFF"
接下来去掉右边图标部分的三个数据,得到“F”图标的数据,这就是可点击的部分,把可点击部分的代码放在上一段下面,ahk的“.”运算符会把两者视为一体
Text.="|<CF>##15$0/0/FFFFFF,12/7/343434,16/13/FFFFFF,21/15/727272"
翻看Findtext的注释,得知将这个参数设置为0后,找到一个就会返回。因为可点击部分“CF”在不可点击部分“NF”下面,Findtext函数只有在扫描不到“NF”时,才能扫描到“CF”,而“NF”是可以存在多个的,以后出现新的不需要点击的对象也能简单加入
就这么轻松完成了自动拾取功能。
下面是完整代码,隐藏的是打包好的单文件
另:因我使用的是1080P屏幕,所以只适配了1080P部分,使用其它分辨率的xdm可以一起来完善数据
#SingleInstance, Force
#Include FindText.ahk
;以管理员模式运行
RunWithAdmin()
Autograph1:="自动拾取 v1.2 By-J.x"
global WinGenShin:="ahk_exe YuanShen.exe"
;每秒检测10次
global PickupRate:=1000//10
;默认是否开启
global PickupDefSt:=1
SetTimer, AutoP, % PickupDefSt?PickupRate:"off"
ScreenScale()
Menu, Tray, Tip, % Autograph1
Menu, Tray, Add, 退出, ExitC
Menu, Tray, NoStandard
Menu, Tray, Icon,,, 1
Return
;不同分辨率参数的初始化
ScreenScale()
{
global
Pick_X:=1095
Pick_Y:=332
Pick_X2:=1209
Pick_Y2:=750
Switch A_ScreenHeight
{
case "1080":
ToolTip 1080P屏幕,0,0
PickupIcon:="|<NF>##15$0/0/FFFFFF,12/7/343434,16/13/FFFFFF,21/15/727272,83/3/FFFFFF,79/10/F5F5F5,93/28/FFFFFF"
PickupIcon.="|<CF>##15$0/0/FFFFFF,12/7/343434,16/13/FFFFFF,21/15/727272"
;未完成
case "1440":
ToolTip 2K屏幕,0,0
PickupIcon:=
Pick_X:=Round(Pick_X*1.333)
Pick_Y:=Round(Pick_Y*1.333)
Pick_X2:=Round(Pick_X2*1.333)
Pick_Y2:=Round(Pick_Y2*1.333)
;未完成
case "2160":
ToolTip 4K屏幕,0,0
PickupIcon:=
Pick_X*=2
Pick_Y*=2
Pick_X2*=2
Pick_Y2*=2
}
SetTimer, ctt,-3000
Return
ctt:
ToolTip
Return
}
;长按F开关自动拾取
AutomatedPickP()
{
local X,Y
KeyWait, f
if (A_TimeSinceThisHotkey>1000)
{
if PickupDefSt
{
SetTimer, AutoP, off
PickupDefSt:=0
SoundBeep,300,200
}
else
{
SetTimer, AutoP, %PickupRate%
PickupDefSt:=1
SoundBeep,200,100
SoundBeep,200,100
}
}
Return
AutoP:
WinWaitActive,%WinGenShin%
static PriorPickupTime:=0
if (FindText(X, Y, Pick_X, Pick_Y, Pick_X2, Pick_Y2, 0, 0, PickupIcon,,0).1.id=="CF")
{
; 降低误点的概率
if ((A_TickCount-PriorPickupTime)<1000)
SendInput {f}
PriorPickupTime:=A_TickCount
}
Return
}
RunWithAdmin()
{
full_command_line := DllCall("GetCommandLine", "str")
if not (A_IsAdmin or RegExMatch(full_command_line, " /restart(?!\S)"))
{
try
{
if A_IsCompiled
Run *RunAs "%A_ScriptFullPath%" /restart
else
Run *RunAs "%A_AhkPath%" /restart "%A_ScriptFullPath%"
}
ExitApp
}
}
ExitC:
ExitApp
Em:
Return
;只在原神里启用
#IfWinActive ahk_exe YuanShen.exe
~f::
AutomatedPickP()
Return
#IfWinActive
谢谢大佬?
非常不错的实践
FindText函数很好用,我也基于它做了一个工具,改天分享出来
感谢,收藏了
非常不错
厉害了我的哥!
厉害了我的哥!
0
0
看懂了我总算看懂了,大佬好办法,牛逼!
懂了,感谢
你是我的英雄
大佬666
就是不太懂怎么用?先打开原神,再打开软件?我电脑好像没什么反应hhh
1080P全屏模式才能用,其它分辨率没适配
哈哈哈,同样用不了233
在第二部分,可点击CF与不可点击部分NF,都是放在text里面的,不是会一起寻找到吗?Findtext里面的这个text文本还有可以“避开图像”的功能?把NF放在text里的第一位,就可以避免识别到?没看懂?
FindText有个功能是找到一个就停止,NF放在前面,先识别到不能点击的图标就不会继续识别了
非常感谢,很好用。但原神更新到须弥后有点问题,比如新的树,是否有更新的版本呢?
感谢..6666
卧槽,牛逼学到了学到了我也可以运用到其他游戏
怎么提示有木马
蛮好的,就是图片重叠变暗后,不容易找标记点
进入游戏没起作用
好的脚本是具有广泛的兼容性和自适应性的,并且是稳定高效的,这个脚本显然已经做到了,非常好,祝贺,感谢。
希望今后制造出能够在不同屏幕、不同系统平台中运行的脚本。能够在各种屏幕尺寸的MacBook Air、MacBook Pro Max、安卓手机、苹果手机、安卓电脑、Windows电脑、Linux电脑等各种客户端和服务器硬件平台和软件平台上高效运行的脚本。