起因
国庆假期很闲,就找点事情做,想起来小时候玩的造梦西游3好久没上了,想着上去看看,结果需要flash才行,为了找回童年的遗憾,我含泪下载了flash,但是作为一个代码小白,我也忍受不了这无聊的刷级过程,于是就想整一个自动化的脚本,刷刷等级。
经过
本来不打算使用pywinauto的,毕竟pyaotugui这个库的功能足够强大,捕捉图片定位、点击、按键等等,基本上需要的操作都能够实现,我使用的是pycharm社区版,主要是装一些库很方便,同样的流程,使用清华的镜像源装上pyautogui之后,直接写了个简单的挂机脚本。
原理其实是利用的造3里面沙僧的腾空击,大多数小怪都无法攻击空中目标,只需要找一个经验较多的关卡不断刷小怪就可以。(代码仅供参考,无限循环谨慎使用)
# 关于字体颜色的设置:https://blog.csdn.net/weixin_44478378/article/details/104967241
import pyautogui
import pyscreeze
import time
import numpy as np
import matplotlib.pyplot as plt
import threading
pyautogui.KEYBOARD_KEYS = ['\t', '\n', '\r', ' ', '!', '"', '#', '$', '%', '&', "'", '(', ')', '*', '+', ',', '-', '.',
'/', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?', '@',
'[', '\\', ']', '^', '_', '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l',
'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~',
'accept', 'add', 'alt', 'altleft', 'altright', 'apps', 'backspace', 'browserback',
'browserfavorites', 'browserforward', 'browserhome', 'browserrefresh', 'browsersearch',
'browserstop', 'capslock', 'clear', 'convert', 'ctrl', 'ctrlleft', 'ctrlright', 'decimal',
'del', 'delete', 'divide', 'down', 'end', 'enter', 'esc', 'escape', 'execute', 'f1', 'f10',
'f11', 'f12', 'f13', 'f14', 'f15', 'f16', 'f17', 'f18', 'f19', 'f2', 'f20', 'f21', 'f22',
'f23', 'f24', 'f3', 'f4', 'f5', 'f6', 'f7', 'f8', 'f9', 'final', 'fn', 'hanguel', 'hangul',
'hanja', 'help', 'home', 'insert', 'junja', 'kana', 'kanji', 'launchapp1', 'launchapp2',
'launchmail', 'launchmediaselect', 'left', 'modechange', 'multiply', 'nexttrack',
'nonconvert', 'num0', 'num1', 'num2', 'num3', 'num4', 'num5', 'num6', 'num7', 'num8', 'num9',
'numlock', 'pagedown', 'pageup', 'pause', 'pgdn', 'pgup', 'playpause', 'prevtrack', 'print',
'printscreen', 'prntscrn', 'prtsc', 'prtscr', 'return', 'right', 'scrolllock', 'select',
'separator', 'shift', 'shiftleft', 'shiftright', 'sleep', 'space', 'stop', 'subtract', 'tab',
'up', 'volumedown', 'volumemute', 'volumeup', 'win', 'winleft', 'winright', 'yen', 'command',
'option', 'optionleft', 'optionright']
# 上面是一些键盘的操作名
def MoveClick(x, y, flag = 1, n = 1, time_1 = 0.1):
'''移动单击函数
flag的值为1,2,代表左键右键,默认左键
n的值为单击次数,默认为1
time_1的值为单击时间间隔,默认0.1s,只要小于0.25都可以,这个应该跟电脑的设置有关系
'''
pyautogui.moveTo(x, y, duration=0.5) #移动,时间间隔为0.5s
time.sleep(0.3)
if flag == 1:
pyautogui.click(clicks = n, button = 'left', interval=time_1)
elif flag == 2:
pyautogui.click(clicks=n, button='right', interval=time_1)
def click_picture(path_picture):
'''单击图片中心'''
flag = 1
while True:
if pyautogui.locateOnScreen(path_picture, confidence=0.7) != None:
print("成功找到图片!")
xy = pyautogui.locateOnScreen(path_picture, confidence=0.7) # 获取图片的位置
centerx,centery = pyautogui.center(xy) # 寻找图片的中心
pyautogui.moveTo(centerx, centery, duration=0.5) # 移动到图片中心位置
time.sleep(0.2) # 停一下
pyautogui.click(button='left') # 单击一下
return 1
break
else:
if flag == 1:
print("等待中………………")
flag += 1
if flag >= 5:
print("未能成功点击")
return 0
# time.sleep(0.5)
# MoveClick(1394, 256)
# time.sleep(0.5)
break
def run(x,y,t):
# pyautogui.keyDown(x) # 按下
# time.sleep(0.1)
# pyautogui.keyUp(x) # 释放
if y != '0':
time.sleep(0.1)
pyautogui.press(x)
pyautogui.press(y)
time.sleep(0.1)
pyautogui.press(x)
pyautogui.press(y)
time.sleep(0.1)
pyautogui.keyDown(x) # 按下
pyautogui.keyDown(y) # 按下
time.sleep(t)
pyautogui.keyUp(x) # 释放
pyautogui.keyUp(y) # 释放
else:
time.sleep(0.1)
pyautogui.press(x)
time.sleep(0.1)
pyautogui.press(x)
time.sleep(0.1)
pyautogui.keyDown(x) # 按下
time.sleep(t)
pyautogui.keyUp(x) # 释放
def jineng(x,n):
while n > 0 :
# pyautogui.keyDown(x) # 按下
# time.sleep(0.1)
# pyautogui.keyUp(x) # 释放
pyautogui.press(x)
time.sleep(0.1)
n = n-1
def lian1(n,t):
run('D',"right", t)
# jineng('L', 2)
# jineng("space",2)
run("left",'0', 3)
pyautogui.keyDown("left") # 按下
# run('D', 0.1)
# jineng('L', 5)
pyautogui.press('I') #这个I是腾空击的技能按键
time.sleep(0.3)
pyautogui.press('I')
time.sleep(0.3)
pyautogui.press('I')
time.sleep(0.5)
pyautogui.press('I')
time.sleep(0.7)
while n > 0:
# lian1(20)
pyautogui.press('I')
time.sleep(0.7803)
print(n)
n = n - 1
def lian2(n,t):
run('D',"right", t)
# pyautogui.keyDown('D') # 按下
# jineng('L', 2)
# jineng("space",2)
# run('D', 0.1)
# jineng('L', 5)
pyautogui.press('I')
time.sleep(1.2)
pyautogui.press('I')
time.sleep(1.5)
while n > 0:
pyautogui.press('I')
# time.sleep(0.7803)
time.sleep(1.68)
# pyautogui.press('num2')
print(n)
n = n - 1
def lian3(n):
while n > 0:
# pyautogui.press('num1')
# pyautogui.press('num2')
# pyautogui.press('num3')
pyautogui.hotkey('num6')
print("\033[0;32;47m%d\033[0m" %n)
time.sleep(1.68)
n = n-1
def fanhuiditu():
MoveClick(1430, 905)
time.sleep(0.2)
MoveClick(935, 484)
time.sleep(0.3)
def doushuaigong():
ti = [3.5,4.5,5]
nn = [115,117,120]
n_ = 3
while 1:
click_picture(r'.\picture\20.png') #这里这个图片指的是失败后的返回地图的按键,需要截屏保存,单击的是图片中心
MoveClick(531, 365)
time.sleep(0.5)
i = n_
while i > 0 :
lian1(nn[n_-i],ti[n_-i])
i = i-1
fanhuiditu()
def huolongdao():
ti = [3.5, 4.5]
nn = [85,85]
n_ = 2
while 1:
click_picture(r'.\picture\20.png')
MoveClick(693, 686)
# MoveClick(999, 668)
time.sleep(0.5)
i = n_
while i > 0:
lian2(nn[n_ - i], ti[n_ - i])
i = i - 1
fanhuiditu()
def huolongdao01():
pyautogui.press('right')
lian3(100)
thread = threading.Thread(target=huolongdao) #这里是一个多线程的操作,这个是小线程,控制沙僧的动作
print("准备开始,延时2秒")
pyautogui.FAILSAFE = True # 鼠标光标在屏幕左上角,会导致程序异常,用于终止程序运行。
# time.sleep(1)
print("开始操作")
# thread.start()
# time.sleep(5.5)
huolongdao01() #在这个时候,玩家二(唐僧)的操作出现了问题,并没有实质性的操作,所以其实不用多线程也可以实现目标
在代码中还有一些细节,一个是多线程的使用,这里用到了threading库,正如代码里面所说,其实可以不用多线程,直接调用小线程那个函数就可以实现目标,主要原因是这时玩家二的操作还有问题,在挂机的时候我使用的是flash上的浏览器,数字按键可以操控玩家二,而在脚本中我也特意区分了数字键盘和字母上的数字,确保操作是数字键盘,但玩家二却没有反应,正是为了解决这个问题,我又开始尝试使用pywinauto完成玩家二的操作。
目前正在尝试,这个过程中我装好之后却一直报错。说是找不到'win32pi',但是经过搜索才知道'win32pi'是它包含的库,只需要把库里面引用库的语句修改一下就可以,参考另一位博主的文章
2021年,非传统方法解决:ModuleNotFoundError: No module named ‘win32api‘_no module named win32api-CSDN博客r
后期需要学习一下再继续,如果有哪位大佬晓得问题原因也请留言告知,谢谢!