怎么用python写脚本(教你写页游自动化Python脚本,取色,大漠识别和后台点击)

本教程是给初学python的教程
废话少说。下面开始python教程
先用tkinter搭建脚本的基本接口。



私人边肖01可以获得很多Python学习资源。

导入tkinter为tk#[size=3]首先要导入tkinter,需要提前用pip把它们安装到python中(方法是百度)[/size] def init _ window(): Global CS,wd wd = tk。Tk() cs = tk。Canvas(wd, width = 800, height = 500, BG = & # 39;怀特& # 39;) wd.minsize(800,500) #最小尺寸 wd.maxsize(800,500)#最大尺寸最大化失败 wd . title(& # 39;DDTHelper & # 39) pic = tk。PhotoImage(file = & # 34;pic.png & # 34)#设置背景图片,最好是800*500和 cs.create _ image (400,250,image = PIC) cs . pack() Bt = tk . button(WD, text。初始化& # 39;, BG =(& # 39;怀特& # 39;), font =(& # 39;微软雅黑& # 39;,20), width=155, height=48, command = BT _ on creat) BT . pack() cs . create _ window(530,70, width=155, height=48, window = BT) wd . main loop() def BT _ on creat(): print()初始化。。。") #入口,这行代码需要一直留在脚本底部 #设置字典 hwnd _ title = dict() init _ window()(不过其实有更好的方案是在图片上叠加控件,使控件背景透明,但是那篇文章的代码运行不了。



现在再来添加点初始化按钮的东西
,让他在被点的时候可以识别当前的游戏窗口
(因为我用的是36jb大厅登录游戏,所以在抓手柄的时候可以根据他的标题来区分游戏窗口)
这里我偷了一个偷懒的作业,用了登录器的游戏窗口标题来获取。



更改上面的导入库和BT_onCreat()方法。

导入win32com.client为wc,win32gui为wg,threading为xc,time,tkinter为tk,win32api为wa,Win32 aswn #需要提前用pip将pywin32插件安装到python中(方法是百度) def init _ window(): global cs,wd wd = tk . tk() cs = tk . canvas(wd white & # 39;) wd.minsize(800,500) #最小尺寸 wd.maxsize(800,500)#最大尺寸最大化失败 wd . title(& # 39;DDTHelper & # 39) pic = tk。PhotoImage(file = & # 34;pic.png & # 34)#设置背景图片,最好是800*500和 cs.create _ image (400,250,image = PIC) cs . pack() Bt = tk . button(WD, text。初始化& # 39;, BG =(& # 39;怀特& # 39;), font =(& # 39;微软雅黑& # 39;,20), width=155, height=48, command = BT _ on creat) BT . pack() cs . create _ window(530,70, width=155, height=48, window = BT) wd . main loop() def BT _ on creat(): global is4399"In: #根据标题中包含的4399提取游戏窗口 hwnd = t . split(& # 34;|")[3] name = t . split(& # 34;|")[2] 打印(& # 34;账号:& # 34;+name+& # 34;手柄:& # 34;+hwnd) znum = znum+1 hwnd = int(hwnd)#把句柄转换成int,因为句柄是从题目中获取的字符串,导致类型错误,我就是在这个坑里陷了很久。。 如果Znum==1:#为每个游戏界面创建一个单独的操作线程。为了便于全局转移,不使用exec。 t1 = xc。Thread(target=Con,args=(hwnd,name,Znum)) elif Znum = = 2: T2 = xc。Thread(target=Con,args=(hwnd,name,Znum)) elif Znum = = 3: T3 = xc。Thread(target=Con,args=(hwnd,name,Znum)) init_control(Znum,Name) #下面再加几个方法 # def get _ all _ hwnd(hwnd,mouse): if wg。IsWindow(hwnd)和wg。IsWindowEnabled(hwnd)和wg。IsWindowVisible(hwnd): hwnd _ title . update({ hwnd:WG。GetWindowText(hwnd)})[/h/ ] #为每个线程创建一个相应的控件来控制线程的运行 def init _ control (znum,name): 全局CS,WD,V1,V2,V3,TX1,T2,TX2,T3,TX3,TXN1,TXN2,txn3 如果Znum==1: v1=tk。IntVar() tx1=tk。StringVar() txn1=tk。string var() elif Znum = = 2: v2 = tk。IntVar() tx2=tk。StringVar() txn2=tk。string var() elif Znum = = 3: v3 = tk。IntVar() tx3=tk。StringVar() txn3=tk。string var() exec(& # 39;tx{}。设置(& # 34;")'。format(Znum)) exec(& # 39;lb{} = tk。Label(wd,text = & # 34{}",BG =(& # 34;# ffffff & # 34),font =(& # 34;微软雅黑& # 34;,20))'。format(Znum,name)) exec(& # 39;lbn{} = tk。Label(wd,textvariable=txn{},BG =(& # 34;# ffffff & # 34),font =(& # 34;微软雅黑& # 34;,10))'。format(Znum,Znum)) exec(& # 39;cb{} = tk。Checkbutton(wd,textvariable=tx{},BG =(& # 34;# ffffff & # 34),font =(& # 34;微软雅黑& # 34;,10),变量= v{},高度=5,宽度= 0,命令= BT _ on run { })& # 39;。format(Znum,Znum,Znum,Znum)) exec(& # 39;cb{}。pack()& # 39;。format(Znum)) exec(& # 39;lb{}。pack()& # 39;。format(Znum)) exec(& # 39;lbn{}。pack()& # 39;。format(Znum)) Ytmp = Znum * 100 Ytmp = Ytmp+70 exec(& # 39;cs.create_window(630,{},width=0,height=0,window = lb { })& # 39;。format(Ytmp,Znum)) Ytmp = Ytmp+40 exec(& # 39;cs.create_window(630,{},width=35,height=25,window = lbn { })& # 39;。format(Ytmp,Znum)) exec(& # 39;cs.create_window(710,{},width=70,height=25,window = CB { })& # 39;。format(Ytmp,Znum)) # Thread方法 defcon (hwnd,name,xc): print(& # 34;成功启动& # 34;) #多框点击事件 defbt _ on run 1(): global v1,tx1,t1,ct1 ifv1.get () = = 1: #确定是否选中 ct1 = 0[Running & # 39;) t1 . start() else: CT1 = 1 #用于控制线程终止 tx1 . set(& # 39;'没有运行;) defbt _ on run 2(): global v2,tx2,ct2 ifv2。get () = = 1: #判断是否 ct2 = 0 tx2。设置(& # Running & # 39) T2 . start() else: ct2 = 1 tx2 . set(& # 39;'没有运行;) defbt _ on run 3(): global v3,tx3,ct3 ifv3.get () = = 1: #判断 ct3是否= 0 tx3 . set(& # Running & # 39;) T3 . start() else: ct3 = 1 tx3 . set(& # 39;'没有运行;) #入口,这行代码需要一直待在脚本底部 #设置字典 hwnd _ title = dict() init _ window()运行后点击初始化效果。



可以看出,当只有一个游戏窗口时,脚本会自动识别游戏窗口。(目前最多能识别三个,不能两次点击初始化,否则报错。据说可以用dict接收用exce动态打包的线程,目前有一个通用的二次识别方案)

并且当不运行旁边的框被勾选时,运行对应的线程。


接下来我们就来到脚本的线程模块,有过py基础的人都知道,py的线程没有stopThread
,但是我们会实现如何控制执行游戏操作的脚本的线程,使其自由回缩。

下面的教程开始
因为下面的脚本是简化的,和上一个帖子略有不同,以这个帖子为准
我们来构建一个和上一个帖子一样的接口代码,作为一个平台。

导入win32com.client为wc,win32gui为wg,threading为xc,time,tkinter为tk,win32api为wa,win32con为wn,多处理为JC def init _ window(): global cs,wd wd = tk。Tk() cs = tk。Canvas(wd, width = 800, height = 500, BG = & # 39;怀特& # 39;) wd.minsize(800,500)# Minimum size wd . maxsize(800,500) wd . title(& # 39;DDTHelper & # 39) pic = tk。PhotoImage(file = & # 34;pic.png & # 34) cs.create_image(400,250,image = pic) cs . pack() Bt = tk。Button(wd, text = & # 39;初始化& # 39;, BG =(& # 39;怀特& # 39;), font =(& # 39;微软雅黑& # 39;,20), width=155, height=48, command = BT _ on creat) BT . pack() cs . create _ window(530,70, width=155, height=48, window = BT) wd . main loop() def init _ control(Znum,name): IntVar() tx1=tk。StringVar() #txn1=tk。string var() elif Znum = = 2: v2 = tk。IntVar() tx2=tk。StringVar() #txn2=tk。string var() elif Znum = = 3: v3 = tk。IntVar() tx3=tk。StringVar() #txn3=tk。string var() exec(& # 39;tx{}。设置(& # 34;")'。format(Znum)) exec(& # 39;lb{} = tk。Label(wd,text = & # 34{}",BG =(& # 34;# ffffff & # 34),font =(& # 34;微软雅黑& # 34;,20))'。format(Znum,name)) # exec(& # 39;lbn{} = tk。Label(wd,textvariable=txn{},BG =(& # 34;# ffffff & # 34),font =(& # 34;微软雅黑& # 34;,10))'。format(Znum,Znum)) exec(& # 39;cb{} = tk。Checkbutton(wd,textvariable=tx{},BG =(& # 34;# ffffff & # 34),font =(& # 34;微软雅黑& # 34;,10),变量= v{},高度=5,宽度= 0,命令= BT _ on run { })& # 39;。format(Znum,Znum,Znum,Znum)) exec(& # 39;cb{}。pack()& # 39;。format(Znum)) exec(& # 39;lb{}。pack()& # 39;。format(Znum)) # exec(& # 39;lbn{}。pack()& # 39;。format(Znum)) Ytmp = Znum * 100 Ytmp = Ytmp+70 exec(& # 39;cs.create_window(630,{},width=0,height=0,window = lb { })& # 39;。format(Ytmp,Znum)) Ytmp = Ytmp+40 # exec(& # 39;cs.create_window(630,{},width=35,height=25,window = lbn { })& # 39;。format(Ytmp,Znum)) exec(& # 39;cs.create_window(710,{},width=70,height=25,window = CB { })& # 39;。format(Ytmp,Znum)) def BT _ on creat(): 全局Znum,D1,D2,D3,conT Znum = 0 wg。EnumWindows(get_all_hwnd,0) conT=jc。经理()。数组(& # 34;我& # 34;,[3,0,0,0])#用于控制进程 #lock = jc。Lock()#用来对进程的运行顺序进行排序,防止显示混乱,打包成exe时可以去掉(改成lock = jc。Manager.Lock()如果windos有错误什么的,那也行。或者删除管理器) #lock不稳定,hwnd _ title.items()中h,t的 : if & # 34;4399"in t: hwnd = t . split(& # 34;|")[3] name = t . split(& # 34;|")[2] 打印(& # 34;账号:& # 34;+name+& # 34;手柄:& # 34;+hwnd) Znum = Znum+1 hwnd = int(hwnd) init _ control(Znum,name) if Znum==1: D1 = jc。经理()。数组(& # 34;我& # 34;,[1,hwnd]) elif Znum = = 2: D2 = JC。经理()。数组(& # 34;我& # 34;,[2,hwnd]) elif Znum = = 3: D3 = JC。经理()。数组(& # 34;我& # 34;,[3,hwnd]) def get _ all _ hwnd(hwnd,mouse): if wg。IsWindow(hwnd)和wg。IsWindowEnabled(hwnd)和wg。IsWindowVisible(hwnd): hwnd _ title . update({ hwnd:WG。GetWindowText(hwnd)}) def con(data,cont): # l . acquire()# lock # try: print(& # 34;成功运行& # 34;) # finally: # l . release() def onr unman(Znum): if onr unman 2(Znum)= = 1: conT[Znum]= 0 exec(& # 39;p{} = jc。Process(target=Con,args=(D{},conT))& # 39;。format(Znum,Znum)) exec(& # 39;p{}。daemon = True & # 39。format(Znum)) exec(& # 39;tx{}。设置(& # 34;跑步& # 34;)'。format(Znum)) exec(& # 39;p{}。start()& # 39;。format(Znum)) else: conT[Znum]= 1 exec(& # 39;tx{}。设置(& # 34;")'。format(Znum)) def on run N2(Znum): if Znum = = 1: return v1 . get() elif Znum = = 2: return v2 . get() elif Znum = = 3: return v3 . get() def BT _ on run 1(): on run(1) def BT _ on run 2(): _ _ main _ _ & # 39: hwnd _ title = dict() init _ window()



识别成功后,我们挂接运行钩子
。如果成功会在终端上显示成功运行

这次我把要发送给进程的数据打包在onCreat方法
中然后在onRunMain中动态组装进程并启动它
,然后让生成的子进程生成守护线程。让守护线程控制游戏

。然后,子流程循环检查我们是否发出了停止命令。如果线程检测到我们发出了stop命令

,它自己的代码就会被执行,然后驱动它的守护线程就会被杀死。
这样,多线程可以随时停止。





代码还巧妙地借用了exec指令的“特性”:输出变量只能在方法中看到,一旦方法重启,变量就会消失
也就是说,如果我们直接用P1 = jc.process (target = con,args = (D1,CONT))生成进程[需要Del p1来清除进程的“尸体”,然后用它设置的con方法代码



脚本怎么用

Con (hwnd,znum,cont,l): #设置守护线程 time . sleep(1) exec(& # 39;t{} = xc。Thread(target=RunMain,args=(hwnd,Znum))& # 39;。format(Znum))#动态生成不同的线程 exec(& # 39;t{}。setDaemon(True)& # 39;。format(Znum)) exec(& # 39;t{}。start()& # 39;。format(Znum)) while True:#开始接收我们是否发出了停止命令 if cont [znum] = = 0: time。sleep(1) else: break[/h]Process & # 39;+str(Znum)+& # 39;:已退出& # 39;)来补充由它产生的子线程执行的方法(不可用)

Def main (hwnd,znum): RM = 0 #运行次数,因为多进程后无法向用户输出程序,所以 hdc = WG . getwindowdc(int(hwnd))#已放弃获取目标页游(flash)的HDC获取指定坐标的颜色[/h] =str(10248996):#检查游戏角色是否在房间界面中(首先要求用户手动将游戏角色输入房间界面),其中房间& # 34;) Doclick (hwnd,5,5) time。sleep(1) if choose _ FB(hwnd,HDC) = = 1: #看看当前两个副本哪个打开。其实这个设计并不合理。如果当前没有打开副本,将会出现错误。- FB_MS(hwnd,hdc)#开始1号复制方案 else: FB _ JD (HWND,HDC)# 2号复制方案 RM = RM+1当然,由于主题和篇幅的原因,我现在就不加了。

def RunMain(hwnd,Znum): white True: print(& # 34;我在跑步& # 34;) time.sleep(1)这样一来,选中running时,
终端会一直显示我正在运行
直到我们取消了running钩子,就不会再显示了(线程被杀)。

熟悉按钮向导的人应该都用过一个叫Desert的插件
。但首先要使用微软官方的指令,不依赖沙漠实现脚本操作。

导入win32com.client为wc,win32gui为wg,threading为xc,time,tkinter为tk,win32api为wa,win32con为wn,多处理为JC def init _ window(): global cs,wd wd = tk。Tk() cs = tk。Canvas(wd, width = 800, height = 500, BG = & # 39;怀特& # 39;) wd.minsize(800,500)# Minimum size wd . maxsize(800,500) wd . title(& # 39;DDTHelper & # 39) pic = tk。PhotoImage(file = & # 34;pic.png & # 34) cs.create_image(400,250,image = pic) cs . pack() Bt = tk。Button(wd, text = & # 39;初始化& # 39;, BG =(& # 39;怀特& # 39;), font =(& # 39;微软雅黑& # 39;,20), width=155, height=48, command = BT _ on creat) BT . pack() cs . create _ window(530,70, width=155, height=48, window = BT) wd . main loop() def init _ control(Znum,name): IntVar() tx1=tk。StringVar() #txn1=tk。string var() elif Znum = = 2: v2 = tk。IntVar() tx2=tk。StringVar() #txn2=tk。string var() elif Znum = = 3: v3 = tk。IntVar() tx3=tk。StringVar() #txn3=tk。string var() exec(& # 39;tx{}。设置(& # 34;")'。format(Znum)) exec(& # 39;lb{} = tk。Label(wd,text = & # 34{}",BG =(& # 34;# ffffff & # 34),font =(& # 34;微软雅黑& # 34;,20))'。format(Znum,name)) # exec(& # 39;lbn{} = tk。Label(wd,textvariable=txn{},BG =(& # 34;# ffffff & # 34),font =(& # 34;微软雅黑& # 34;,10))'。format(Znum,Znum)) exec(& # 39;cb{} = tk。Checkbutton(wd,textvariable=tx{},BG =(& # 34;# ffffff & # 34),font =(& # 34;微软雅黑& # 34;,10),变量= v{},高度=5,宽度= 0,命令= BT _ on run { })& # 39;。format(Znum,Znum,Znum,Znum)) exec(& # 39;cb{}。pack()& # 39;。format(Znum)) exec(& # 39;lb{}。pack()& # 39;。format(Znum)) # exec(& # 39;lbn{}。pack()& # 39;。format(Znum)) Ytmp = Znum * 100 Ytmp = Ytmp+70 exec(& # 39;cs.create_window(630,{},width=0,height=0,window = lb { })& # 39;。format(Ytmp,Znum)) Ytmp = Ytmp+40 # exec(& # 39;cs.create_window(630,{},width=35,height=25,window = lbn { })& # 39;。format(Ytmp,Znum)) exec(& # 39;cs.create_window(710,{},width=70,height=25,window = CB { })& # 39;。format(Ytmp,Znum)) def BT _ on creat(): 全局Znum,D1,D2,D3,conT Znum = 0 wg。EnumWindows(get_all_hwnd,0) conT = jc。经理()。数组(& # 34;我& # 34;,[3,0,0,0]) for h,t in hwnd _ title . items(): if & # 34;4399"in t: hwnd = t . split(& # 34;|")[3] name = t . split(& # 34;|")[2] 打印(& # 34;账号:& # 34;+name+& # 34;手柄:& # 34;+hwnd) Znum = Znum+1 hwnd = int(hwnd) init _ control(Znum,name) if Znum == 1: D1 = jc。经理()。数组(& # 34;我& # 34;,[1,hwnd]) elif Znum = = 2: D2 = JC。经理()。数组(& # 34;我& # 34;,[2,hwnd]) elif Znum = = 3: D3 = JC。经理()。数组(& # 34;我& # 34;,[3,hwnd]) def get _ all _ hwnd(hwnd,mouse): if wg。IsWindow(hwnd)和wg。IsWindowEnabled(hwnd)和wg。IsWindowVisible(hwnd): hwnd _ title . update({ hwnd:WG。GetWindowText(hwnd)}) def all _ run(Znum): while Znum & gt;0: exec(& # 39;t{}。start()& # 39;。格式(Znum)) Znum = Znum-1 # Class-operation-type-operation-type-operation-type-operation-type-operation-type-operation-type-operation-type-operation-type-operation-type-operation-Fx):[/hWM _ keydown,68,none) wa.sendmessage (HwnD,WN。WM _ None) #1.3=1屏距 wa.sendmessage (hwnd,wn.wm _ keydown,68,None) time . sleep(JL * 1.3) wa.sendmessage (hwnd,hwnd None) else: #适应方向并防止无效 wa . sendmessage(hwnd,wn.wm _ keydown,65,None) 发送消息(hwnd,wn。WM_KEYDOWN,87,无) wa。发送消息(hwnd,wn。WM_KEYUP,87,None) def doClick(hwnd,cx,cy): long_position = wa。MAKELONG(cx,cy) wa。发送消息(hwnd,wn。WM_LBUTTONDOWN,WN。MK_LBUTTON,long_position) wa。发送消息(hwnd,wn。WM_LBUTTONUP,wn。MK_LBUTTON,long _ position) def do fire(hwnd,Ld): wa。发送消息(hwnd,wn。WM _ keyfirst,66,none) # Press first wa。发送消息(hwnd,wn。WM _ keyfirst,69,无)#按第一技能 wa。发送消息。wn。WM_KEYFIRST,97,None) wa。发送消息(hwnd,wn。WM_KEYFIRST,98,None) wa。发送消息(hwnd,wn。WM_KEYFIRST,97,无)#11大招 wa.sendmessage (hwnd,wn.wm _ keyfirst,100,无) wa.sendmessage (hwnd,wn.wm _ keydown,32,无) time . sleep(LD * 0.04) wa .发送消息(hwnd,wn。WM_KEYUP,32,无) #游戏流程处理类-。def choose _ FB(HWND,HDC): Doclick (HWND,600,200) #打开菜单 时间。sleep (1) Doclick (HWND,626,18)# single copy time . sleep(1) while true: doc tick(HWND,5,5) ifstr (wg.getpixel (HDC,244,237)) = = 23) #魔法石 FBN = 1 Break Elifstr(WG .Getpixel (HDC,337,278))= = STR(13298869): Doclick(HWND,29)# skill Dan fbn = 2 break time。睡眠(1) 医生(hwnd,726,501) #难度 时间。睡眠(1) [/ 53) # OK 时间。sleep (1) Doclick (HWND,951,491) return(FBN) def FB _ MS(HWND,HDC): = str(5418993):# turn detection doc tick(HWND,5,5) time . sleep(0.5) while true: doc tick(HWND,5,5) [/ 1") JD = 18 break else: print(& # 34;位置2 & # 34;) 爬升(hwnd,0.5,0) JD = 25 破位 wa。发送消息(hwnd,wn。WM _ keyfirst,69,无)valley专用 wa。None)#第一遍 time . sleep(5) for I in range(2): while str(WG . get pixel(HDC,497,169))!= str(5418993):# turn detection Doclick(hwnd,5,5) time . sleep(0.5) wa . sendmessage(hwnd,wn.wm _ keydown,65,none) [/ Wn.wm _ keyup,65,none) do fire (hwnd,20) time . sleep(6) do angle(hwnd,JD) sleep(1) CS = CS+1 # Exit[退出副本& # 34;) break else: do fire(hwnd,20) def FB_JD(hwnd,hdc): while True: cs = 0 CG = 0 while str(WG .GetPixel(hdc,497,169))!= str(5418993):# Round detection IFCS >:= 20:# time out exit CG = 1 CS = 0 break else: Doclick(hwnd,5,5) time . sleep(1) CS = CS+1 if CG = = 1: break else: do fire(: RM=0 hdc=wg。GetWindowDC(hwnd) while True: while str(WG。GetPixel(hdc,919,280))!=str(10248996):#房间检测 打印(& # 34;房间& # 34;) doClick(hwnd,5,5) time . sleep(1) if choose _ FB(hwnd,hdc) == 1: FB_MS(hwnd,Hdc) FB _ JD(hwnd,Hdc) RM = RM+1 defcon(data,cont): #设置守护线程 znumThread(target=RunMain,args=(hwnd,)& # 39;。format(Znum)) exec(& # 39;t{}。setDaemon(True)& # 39;。format(Znum)) exec(& # 39;t{}。start()& # 39;。format(Znum)) while True: if conT[Znum]= = 0: time . sleep(1) else: break print(& # 39;流程& # 39;+str(Znum)+& # 39;:已退出& # 39;) def on run man(Znum): if on run man 2(Znum)= = 1: conT[Znum]= 0 exec(& # 39;tx{}。设置(& # 34;跑步& # 34;)'。format(Znum)) exec(& # 39;p{} = jc。Process(target=Con,args=(D{},conT))& # 39;。format(Znum,Znum)) exec(& # 39;p{}。daemon = True & # 39。format(Znum)) exec(& # 39;p{}。start()& # 39;。format(Znum)) else: conT[Znum]= 1 # exec(& # 39;del p { } & # 39。format(Znum)) exec(& # 39;tx{}。设置(& # 34;")'。format(Znum)) def onRunMan 2(Znum): if Znum = = 1: return v1 . get() elif Znum = = 2: return v2 . get() elif Znum = = 3: return v3 . get() def onRunMan 3(Znum): if Znum = = 1: if P1 . is _ alive:[/h_ _ main _ _ & # 39: hwnd _ title = dict() init _ window()我已经用-
区分了模块代码我们讲了窗口接口和程序线程

重点讲了操作类

Def Doclick (HWND,CX,CY): long _ position = wa。Makelong (CX,CY) #模拟鼠标指针被转移到指定的坐标 wa。发送消息(WN HWND。wn的WM _ LButtondown。MK _ LButton,Long_position)#模拟鼠标按 wa.sendmessage (hwnd,wn.wm _ lbuttonup,wn.mk _ lbutton,long _ position) #模拟鼠标弹跳。这个方法压缩了原来复杂的代码,所以我们想点击游戏界面的时候可以调用这个方法,比如


看看其他的方法。

Def爬升(hwnd,JL,FX): IFFX = = 1: #右 #自适应方向和无效预防 wa。发送消息(hwnd,wn。WM _ keydown,68,无) wa。sendmessage None) #1.3秒=1屏距离 wa.sendmessage (hwnd,wn.wm _ keydown,68,None) time . sleep(JL * 1.3) wa.sendmessage (hwnd,wn.wm _ keydown,65,None) else: #适应方向并防止无效 wa . sendmessage(hwnd,wn.wm _ keydown,65,none) Wa发送消息(hwnd,wn。WM_KEYDOWN,87,无) wa。发送消息(hwnd,wn。WM_KEYUP,87,None) def doFire(hwnd,ld): wa。发送消息(hwnd,wn。WM_KEYFIRST,66,无)#先按大招 wa.sendmessage (hwnd,wn.wm _ keyfirst,69,无)#先按技能 wa.sendmessage (hwnd,wn.wm _ keyfirst,97,无) wa.sendmessage Wn .WM_KEYFIRST,98,None)#如果有大招, wa.sendmessage (hwnd,wn.wm _ keyfirst,97,none) # 11大招 wa.sendmessage (hwnd,wn.wm _ keyfirst,100,None) wa .发送消息(hwnd,wn。WM _ keydown,32,none) #空电池容量 time.sleep(ld * 0.04)#每个电池容量大约需要0.04秒,受游戏延迟和电脑性能影响。但是因为速度条颜色不纯而暂时搁置) wa。发送消息(hwnd,wn。WM _ keyup,32,none) # Release 空这里的方法基本上都是一些键盘操作的集合
比如用
方法climb来控制游戏中人物的爬行。
方法doAngle用于调整游戏中角色发射炮弹的角度
方法doFire是操作游戏中的角色发动攻击
总结以上方法,模拟键盘按键的命令有三种。

哇。SendMessage(游戏窗口句柄,wn。WM_KEYDOWN,键码,None) wa。SendMessage(游戏窗口句柄,wn。WM_KEYUP,键码,None) wa。SendMessage(游戏窗口句柄,wn。WM_KEYFIRST,key code,None)它们是将指定按钮发送到游戏窗口弹出指定按钮,点击集按压和弹出于一体的指定按钮
。但是需要注意的是
如果需要重复点击某个按钮,不要使用点击指定按钮的代码
。这样会造成一个bug,相当于按了按钮却没有弹出来。导致失控
就像doAngle方法一样需要按下弹起保证不会有bug

然后去游戏捡颜色
因为不需要提取,我不用单独分开
你需要用hdc(想了解hdc可以去百度hdc和hwnd)

Hdc = WG。getwindowdc (int (hwnd)) =通过hwnd获取hdc

Color = wg。GetPixel(hdc,x坐标,Y坐标)↑获取指定点的颜色
细心的朋友可以发现
每个获取颜色的代码附近都有一个doClick的调用
那是为了防止用户在游戏界面点击后点击其他地方,导致游戏窗口失去焦点。所以用doClick强制激活窗口

这里要注意一点
因为这款游戏官方允许使用脚本,因此,微软官方的说明是有的
否则可以尝试使用沙漠插件或者其他插件发送硬件级模拟键信息

下面是调用沙漠插件的方法
下载沙漠插件:点击我下载
注:沙漠

导入win 32 com . client DM = win 32 com . client . dispatch(& # 39;dm.dmsoft & # 39)#调用沙漠插件 print(dm.ver())#输出版本号成功调用沙漠插件,输出版本号
绑定窗口。

dm_ret = dm。BindWindow(hwnd,& # 34;gdi & # 34, "windows & # 34, "windows & # 34,0)绑定字典

dm.setDict(0,& # 39;字典。txt & # 39)#把字典文件和脚本放在同一个目录下 dm.useDict(0)可以说成功注册沙漠插件
后,它的使用代码基本上和自带的手册上的一样
。有需要的可以多看看自带的说明书。




但是dm.dll经常被防守队员毒害。。。结果就是我想用都用不了

虽然沙漠里的识别系统很强大,但毕竟是闭源支付,强行换成32位python。。
还是少用为好。

您可以还会对下面的文章感兴趣

使用微信扫描二维码后

点击右上角发送给好友