原神人物判断,识别,切换,自用热键

许多实用脚本和封装函数, 可以让您编写脚本更加便捷高效

Moderators: tmplinshi, arcticir

Ghost_jack_00
Posts: 4
Joined: 28 Jun 2023, 01:01

原神人物判断,识别,切换,自用热键

07 Apr 2024, 02:53

我在B站做了文本,后来发现,文本格式不够好,图文格式,对读代码不够友好,想到 还是发这个论坛里面来,从B站来的朋友,自取片段

Code: Select all



#HotIf WinActive("ahk_exe YuanShen.exe") && 鼠标在中心点:=IfMousepos(959,539,960,540)
;=============================队伍人物识别====================
~l up::
{
	;等待时间5秒
	Sleep(5000)
	;不断循环等待 鼠标归位中心点===
	while !IfMousepos(959,539,960,540)
		Sleep(1000)
	; 调用ImagePut  和  RapidOcr 两个库文件,截图保存并进行ocr文字识别,正则只要汉字
	chinatxt:=RegExReplace(ImagePutRapidOcr(1655,233,1772,571,"人物识别"), "[^\一-\龟\n]")  ;删除识别文字中的非中文字和非段落符号
	; 替换文字修改ocr 错误
	chinatxt:= StrReplace(chinatxt, "纳西姐", "纳西妲")
	; 创建人物列表数组 全局模式
	global  Persons:=StrSplit(chinatxt,"`n",A_Space)		                                      ;利用段落符号分割字符串转变为数组,忽略空格		
	; 显示在右上角	
	try TextOnTop(Persons[1] "`n" Persons[2] "`n" Persons[3] "`n" Persons[4],1800,0,3,5000)
}

人物识别(1655,233)(1772,571).png
人物识别(1655,233)(1772,571).png (66.45 KiB) Viewed 136 times
调用的 ImagePut 和 RapidOcr 两个库文件,可以论坛里面找

我只是把两个库串了起来,做了一个函数,函数 复后

Code: Select all


;========================= 切换人物 =====================附带释放元素爆发

~1::
~2::
~3::
~4::
{
try	{
		; A_Priorkey,A_TimeSincePriorHotkey 均指向上一个热键,若为第一次热键,就会报错,所以用 try
		if(InStr("1234",SubStr(A_Priorkey,-1)) and A_TimeSincePriorHotkey<500)
			;3按键一齐发动,只有一个在游戏中响应,按顺序优先 滚键盘
			send("{q}{e}{click}")
		; 修改当前人物名称,提取人物列表数组
		global person:=Persons[SubStr(A_ThisHotkey,-1)]
		; 显示在右上角	
		TextOnTop(person,1800,0,3,3000)
		}
}


Code: Select all


;========================= 快速切人W长E 跑图 =====================

WheelUp::
WheelDown::
{
	; 滚轮同时按Q,可以调整Z物品的  1 2 号位置
	if GetKeyState("q") 
		send("{z down}"),Sleep(800),send(A_ThisHotkey="WheelUp"?"1":"2"),send("{z up}")
	; 滚轮同时按E,可以调整Z物品的  3 4 号位置
	else if GetKeyState("e")
		send("{z down}"),Sleep(800),send(A_ThisHotkey="WheelUp"?"3":"4"),send("{z up}")
	;在W行走状态,可以W+wheelup  w+wheeldown ,可以切换人物,并长按E, 方便(钟离,万叶、夜兰、早柚)矿车队跑图采矿
	else if GetKeyState("w") 
		send(A_ThisHotkey="WheelUp"?"12":"34"),Sleep(150),send("{e Down}"),Sleep(850),send("{e up}")
	;什么都不按,就直接切换人物
	else  
		send(A_ThisHotkey="WheelUp"?"12":"34")
	;循环检查当前人物
	loop 4
	{
		if !IfColor(1859, 258+96*(A_index-1),0xFFFFFF)
			person:=Persons[A_index],TextOnTop(person,1800,0,3,3000)
	}
}




Code: Select all



~e::
{
; 正则修改 A_ThisHotkey 的 修饰键
thisHotkey := RegExReplace(A_ThisHotkey,"^(\w* & |\W*)")
; 获取鼠标当前位置(959,539)====(960,540) 4个点中,判断出左右,上下的旋转随机数
MouseGetPos(&X,&Y),LR:=x=960?-1:1,UD:=y=540?-1:1
try switch person
		{
			case "纳西妲":
			{
				while GetKeyState(thisHotkey, "P")
				{
					if iscolordev(770,363,0XF0F0F0,16)          ;相机左上角的颜色,RGB 差值在+-16以内
					{
					; ImagePutRapidOcr(770-100,363-100,770+100,363+100,"纳西妲E技能识别点x=770y=363color=0XF0F0F0偏差=16")
					Loop 16
						DllCall("mouse_event", "UInt", 1,"UInt",Ceil(LR*308),"UInt",Ceil(5*308*(A_index=1?0.5:A_index=16?-0.5:mod(A_index,2)=1?1:-1))),Sleep(35)
					break
					}
				Sleep(50)
				}
			}
			case "那维莱特":
			{
			send("{e}"),Sleep(50),send("{click down}"),Sleep(500),send("{click up}"),startTime:=A_TickCount
			while GetKeyState(thisHotkey, "P")
				{
				if iscolordev(614,579,0x101010,16)             ;   614,579===>> 头顶黑色区域
					{
					 ; ImagePutRapidOcr(614-100,579-100,614+100,579+100,"那维莱特E技能识别点x=614y=579color=0X101010偏差=16")	
						while GetKeyState(thisHotkey, "P") and (A_TickCount-startTime<=3000)
							Loop 16
								DllCall("mouse_event", "UInt", 1,"UInt",Ceil(LR*308),"UInt",Ceil(5*308*(A_index=1?0.5:A_index=16?-0.5:mod(A_index,2)=1?1:-1))),Sleep(35)
					}
				Sleep(50)
				}
			}
		Default:
			return
		}
}







两个库的串联函数

Code: Select all


ImagePutRapidOcr(x1:=0,y1:=0,x2:=A_ScreenWidth,y2:=A_ScreenHeight,name:=" ")
{
	w:=x2-x1,h:=y2-y1,MyArray:=[x1,y1,w,h]
	folderPath := A_ScriptDir "\图片"
	if (!DirExist(folderPath))
		DirCreate folderPath
	Imagefile:=folderPath "\" name "(" x1 "," y1 ")(" x2 "," y2 ").png"
return RapidOcr().ocr_from_file(ImagePutFile(MyArray,Imagefile))
}

#include <ImagePut>
#Include <RapidOcr\RapidOcr>


需要的其他函数,需要的自取

Code: Select all





iscolordev(x1,y1,color2,devR:=0,devG:=devR,devB:=devR)
{
    CoordMode "Pixel","Screen"             ; 全屏识别找坐标色
		Color1:= PixelGetColor(X1, Y1)
    r1 := Format("{:d}","0x" SubStr(color1, -6, 2))
    g1 := Format("{:d}","0x" SubStr(color1, -4, 2))
    b1 := Format("{:d}","0x" SubStr(color1, -2, 2))
		
    color2:=format("0X{:x}",color2)
    r2 := Format("{:d}","0x" SubStr(color2, -6, 2))
    g2 := Format("{:d}","0x" SubStr(color2, -4, 2))
    b2 := Format("{:d}","0x" SubStr(color2, -2, 2))
    return (abs(r1-r2)<=devR and Abs(g1-g2)<=devG and Abs(b1-b2)<=devB)
}





GetColor(x,y)    ;函数调用
{
    CoordMode "Pixel","Screen"             ; 全屏识别找坐标色
    return PixelGetColor(x,y)    ;获取X和Y坐标的颜色值 作为返回值
}




IfColor(x, y, Color) {
/*------------------------------------------------		
; 判断一个屏幕坐标点的颜色是否正确	
; 示例用法	
		; 判断单个坐标点
		; singleResult := IfColor(100, 200, 0xFF0000) ; 100, 200 坐标点的颜色是否为红色
    ; singleResult := IfColor(100, 200, "0xFF0000,0xFFFFFF") ; 100, 200 坐标点的颜色是否为红色或白色
    ; MsgBox, % singleResult ? "颜色正确" : "颜色错误"
返回:0,假     大于零的整数,真
*/ ;--------------------------------------------	
	if IsInteger(color)
		Color:=format("0X{:x}",Color)
	CoordMode "Pixel", "Screen"
	return InStr(Color,PixelGetColor(x, y))
}


IfMousepos(x1:=0,y1:=0,x2:=A_ScreenWidth,y2:=A_ScreenHeight)
{
	MouseGetPos &x,&y
	; x1:=x1=""?0:x1
	; y1:=y1=""?0:y1
	; x2:=x2=""?A_ScreenWidth:x2
	; y2:=y2=""?A_ScreenHeight:y2
	return x>=x1 and x<=x2 and y>=y1 and y<=y2
}



IfColors(&X, &Y , Params*) {
/*--------------------------------------------------------------	
判断颜色 1.2
作者: Ghost_jack
(功能灵活,可多点,可单点,可多色,可单色)
返回值: 0-false  1-true 
示例用法  1.0版本 (PixelGetColor 第四参数 多点)


		
		1、IfColors(&X, &Y ,"100,200,0xFFFFFF")
		 => pc:=PixelGetColor(100,200)
		 => InStr(0xFFFFFF,pc)
			
			单点判断单颜色真假
		2、IfColors(&X, &Y ,"100,200,0xFFFFFF|0x00000")
			=> pc:=PixelGetColor(100,200)
			=> InStr(0xFFFFFF|0x00000,pc)
			单点判断多颜色真假,颜色分隔符不能是逗号
			
		3、IfColors(&X, &Y ,"100,200,0xFFFFFF","300,400,0x000000")
			多点判断多颜色同时成立的真假,多点用引号分开
			
		4、IfColors(&X, &Y ,"100,200,0xFFFFFF,or","300,400,0x000000")
			多点判断多颜色任一成立的真假,  第4参数为or ||,默认不设置为 and
		
		5、IfColors(&X, &Y ,"100,200,0xFFFFFF|0x000000,||","300,400,0x000000","500,600,0x888888")
			a => IfColors(&X, &Y ,"100,200,0xFFFFFF|0x000000")
			b => IfColors(&X, &Y ,"300,400,0x000000")
			c => IfColors(&X, &Y ,"500,600,0x888888")
		复杂逻辑的组合:解释从左往右,  (a or b)and c
		
/*------------------------------------------------------------	
示例用法  1.1版本 (PixelSearch 多色)
		兼容1.0,区分为 坐标数字,区分为是否存在 ~|-_ 分隔符
		
		1、IfColors(&X, &Y ,"100~200,300,0xFFFFFF")
			=>   PixelSearch(&X, &Y, 100, 300, 200, 300, 0xFFFFFF, 0 )
			范围判断单颜色真假
			
		2、IfColors(&X, &Y ,"100,300~200,0xFFFFFF|0x000000")
			a=>  PixelSearch(&X, &Y, 100, 300, 100, 200, 0xFFFFFF, 0 )
			b=>  PixelSearch(&X, &Y, 100, 300, 100, 200, 0x000000, 0 )
			  a or b
			判断范围,是否存在多颜色中的任意一个颜色 ,颜色分隔符不能是逗号
			
		3、IfColors(&X, &Y ,"100~200,300~400,0xFFFFFF","300,400,0x000000")
			a=> PixelSearch(&X, &Y, 100, 300, 200, 400, 0xFFFFFF, 0 )
			b=> IfColors(&X, &Y ,"300,400,0x000000")
				a and b
			范围判断+ 单点判断,同时成立
			
		4、IfColors(&X, &Y ,"100~200,300~400,0xFFFFFF,or","300,400,0x000000")
			a=> PixelSearch(&X, &Y, 100, 300, 200, 400, 0xFFFFFF, 0 )
			b=> IfColors(&X, &Y ,"300,400,0x000000")
				a or b
			范围判断 + 单点判断,任一成立    (第4参数为or ||,默认不设置为 and)
		
		5、IfColors(&X, &Y ,"100~200,200,0xFFFFFF|0x000000,||","300,400,0x000000","500~600,700,0x888888")
		
			a=> PixelSearch(&X, &Y, 100, 200, 100, 300, 0xFFFFFF, 0 )
					PixelSearch(&X, &Y, 100, 200, 100, 300, 0x000000, 0 )
			b=> IfColors(&X, &Y ,"300,400,0x000000")
			c=> PixelSearch(&X, &Y, 500, 700, 600, 700, 0xFFFFFF, 0 )

		复杂的组合:解释从左往右,  (a or b)and c

/*--------------------------------------------------------------
示例用法  1.3版本 (坐标缺省值设置,可反转)

		兼容1.0,1.1, 区分为 坐标数字缺省值表达方式 分隔符  ~_&<>.|
		没有分隔符   =  全屏幕坐标
		有分隔符,缺省数值 = 自动屏幕坐标值   > 分隔符表示反转
		
		1、缺省值
		=>  ifcolors(100~,~300,"0xFFFFFF")
		=>  PixelSearch(&X, &Y, 100,A_ScreenHeight, A_ScreenWidth,300 , 0xFFFFFF, 0 )
		
		2、缺省值表达 全屏搜索,下列表达是一个效果

		=>  ifcolors(,,"0xFFFFFF")
		=>  ifcolors( , ,"0xFFFFFF")
		=>  ifcolors(~, ,"0xFFFFFF")
		=>  ifcolors(~,|,"0xFFFFFF")
		=>  ifcolors(0~,0<,"0xFFFFFF")
		=>  PixelSearch(&X, &Y, 0, 0, A_ScreenWidth, A_ScreenHeight, "0xFFFFFF", 0 )
		
		3、缺省坐标表达式   反转分隔符  >
		=>  ifcolors(>, ,"0xFFFFFF")
		=>  PixelSearch(&X, &Y, A_ScreenWidth, 0,  0, A_ScreenHeight, "0xFFFFFF", 0 )
		
		
		
*/ ;--------------------------------------------

	for index,param in params	
	{
		xyc:= StrSplit(StrReplace(param, A_Space),","),x:=xyc[1],y:=xyc[2],cs:=xyc[3]
		a_o:=InStr("or||",xyc.Length=4?xyc[4]:"&")=0?false:true
		if (RegExMatch(x . y, "([~_&<>\.\|])") or !StrLen(x) or !StrLen(y)) 
		{
			x1:=RegExMatch(x, "(^\d+)", &xr)?xr[1]:RegExMatch(x, ">")?A_ScreenWidth:0
			x2:=RegExMatch(x, "(\d+$)", &xr)?xr[1]:RegExMatch(x, ">")?0:A_ScreenWidth
			y1:=RegExMatch(y, "(^\d+)", &yr)?yr[1]:RegExMatch(y, ">")?A_ScreenHeight:0
			y2:=RegExMatch(y, "(\d+$)", &yr)?yr[1]:RegExMatch(y, ">")?0:A_ScreenHeight
			Loop Parse, cs, "-~|&_."
				{
				IF t_f:=PixelSearch(&X, &Y, x1, y1, x2, y2,A_LoopField)
					break
				}
		}	else 
			t_f:=InStr(cs,PixelGetColor(x,y))=0?false:true
		if !t_f and !a_o
			return false
		if t_f and a_o
			return true
	}
	return t_f
}


TextOnTop(text:="",x:=1600,y:=0,MyGui:="Gui",Delay:=5000,ColorS:="00ffFF",side:=0,w:=0) {
/* ;-------------------------------------------------------------------------------	
显示text的内容,delay后消失
<参数>
	text					:要显示的文本内容。
	X							:显示位置的X,默认为1600。
	Y							:显示位置的Y,默认为0。
	WhichToolTip	:如果您不需要同时显示多个工具提示, 默认值为20。
	Delay 				:文本显示后 消失的时间。 默认为1000,若为0,则不消失。
<返回>
	Text	
*/ ;-------------------------------------------------------------------------------	
global
if WinExist("my_over_Lay")
{
	try MyGuiText.text:=""
	try MyGui.Destroy()
}
MyGui:= Gui("+AlwaysOnTop -Caption +ToolWindow","my_over_Lay") ; +ToolWindow 避免显示任务栏按钮和 alt-tab 菜单项.
MyGui.BackColor := "000000"  ; 可以是任何 RGB 颜色(下面会变成透明的).
MyGui.SetFont("s12 c" ColorS)  ; 设置大字体(32 磅).
MyGuiText:=MyGui.Add("Text","w500 r5",text)  ; XX & YY 用来自动调整窗口大小.
WinSetTransColor(MyGui.BackColor " 150",MyGui)
MyGui.Show("x" x "y" y "NoActivate")  ; NoActivate 让当前活动窗口继续保持活动状态.
SetTimer(Guidestroy, "-" Delay)
Guidestroy(*)
	{
	try MyGui.Destroy()
	}
}

Return to “脚本函数”

Who is online

Users browsing this forum: No registered users and 5 guests