本教程是给初学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。。
还是少用为好。