你好呀,
查看机器人视频,以了解该机器人的工作原理link here
要遵循本指南,请克隆项目 from here。
第113至613行的所有代码都与GUI有关(以您自身的风险阅读,因为本指南不会在此处解释)。
本指南将通过615到1015的行。
在第615行 中,您可以看到函数“运行”包含几个功能定义,这些函数定义充当“助手”功能,以帮助繁琐的bot工作,例如:
(第616行)
def find_object(file):
img = pag.screenshot()
img = img.convert('RGB')
img = np.array(img)
img_rgb = img[:, :, ::-1].copy()
img_gray = cv.cvtColor(img_rgb, cv.COLOR_BGR2GRAY)
template = cv.imread("objects/" + file,0)
w, h = template.shape[::-1]
res = cv.matchTemplate(img_gray,template,cv.TM_SQDIFF_NORMED)
mn,_,mnLoc,_ = cv.minMaxLoc(res)
print(file, "->", mn)
if mn < 0.007:
return mnLoc
else:
return False
'Find_Object'函数,进行游戏的屏幕截图,并试图在该屏幕截图内找到图像“文件”,使用此功能是在游戏屏幕中找到游戏对象。
函数从616到700,都是“助手”功能,其中大多数使用库pyautogui库,而pyautogui则短于代码中的“ pag”,pyautogui提供的功能提供了使用键盘移动鼠标并输入键盘的功能(read pyautogui读取pyautogui了解这些功能如何工作)。
功能从700到930,都是“任务”功能,它使用Pyautogui函数和“助手”功能的组合来执行游戏内任务(将在下面说明)。
然后,我们继续进行前循环初始化:
(第931行)
castle = 1
max = (4 if i > 1 else 10)
cur_task = 0
tasks = {
0 : lambda : selector(i),
1 : lambda : enter_target_info(ALL[i]["C" + str(castle) + "_x"], ALL[i]["C" + str(castle) + "_y"]),
2 : lambda : open_attackWin(),
3 : lambda : select_preset(int(ALL[i]['Slot'])),
4 : lambda : apply_preset(),
5 : lambda : attack(),
6 : lambda : select_speedup(i)
}
在这里,变量“城堡”是要从(GUI中的10个记录的城堡)开始的城堡号。
“ max”是要使用的最大城堡数量。
“ cur_task”是一个索引变量,可以跟踪当前运行任务。
“任务”是游戏中任务的字典,应按顺序完成,以获得成功的城堡攻击。
任务0-选择器(i)功能
(第895行)
def selector(i):
if i > 1 and not self.firstRotation:
return extinguish(ALL[i]["C" + str(castle) + "_x"], ALL[i]["C" + str(castle) + "_y"])
elif i <= 1 and not self.firstRotation:
return waitFor_reappear(ALL[i]["C" + str(castle) + "_x"], ALL[i]["C" + str(castle) + "_y"])
else:
sleep(5)
return True
此任务作业是在可能的情况下熄灭攻击城堡,如果没有,它将等待城堡重新出现,但此任务被称为首先称为,尽管它直到机器人完成攻击后才实际使用,因此它可以使用,因为它不会执行第一个旋转中的两个功能之一。
任务1- enter_target_info(a,b)功能
(第659行)
def enter_target_info(x, y):
press("tab")
pag.write(x)
press("tab")
pag.write(y)
press("enter")
sleep(0.5)
press("tab")
pag.write(x)
press("tab")
pag.write(y)
press("enter")
sleep(1)
if findClick_object("target.bmp") == False: return False
return repeat(lambda: find_object("success_targselect.bmp"), True)
使用pyautogui,pynput。
然后单击“ target.bmp”对象,打开攻击对话框。
它还检查了攻击对话框是否打开,并将其返回为布尔。
任务2 -Open_attackwin()函数
(第904行)
def open_attackWin():
if findClick_object("confirm.bmp") == False: return False
sleep(2)
return repeat(lambda: find_object("use_preset.bmp"), True)
此任务单击“攻击”对话框上的确认按钮,以打开“攻击设置”窗口。
然后检查攻击设置窗口是否打开,并将其返回为布尔。
任务3 -select_preset(i)函数
(第685行)
def select_preset(i):
cords = find_object("drop_preset.bmp")
if cords == False: return False
click(cords[0] - 50, cords[1] + 60)
sleep(1)
if self.checkBox.isChecked():
pag.move(0, -(int(22 * 1.25) * i))
else:
pag.move(0, -(22 * i))
sleep(0.25)
pag.click()
self.preset_ready = True
在“预设”下降菜单中选择“ i”。
任务4- apply_preset()函数
(第912行)
def apply_preset():
if findClick_object("use_preset.bmp", x=10, y=5) == False: return False
sleep(1)
return repeat(lambda: find_object("failed_preset_use.bmp"), False)
此任务唯一的作业是单击蓝色按钮应用预设,然后检查预设是否应用并返回为bool。
任务5-攻击()功能
(第919行)
def attack():
if findClick_object("start_attack.bmp", x=50, y=10) == False: return False
sleep(1)
return repeat(lambda: find_object("success_attack.bmp"), True)
再次,一个简单的任务,目标是单击攻击按钮,然后检查最后一个确认窗口是否可见,并将其返回为布尔。
任务6 -select_speedup(i)函数
(第876行)
def select_speedup(i):
cords = find_object("confirm3.bmp")
if cords == False: return False
if i > 1:
click(cords[0] - 300, cords[1] - 200)
else:
click(cords[0] + 100, cords[1] - 200)
sleep(0.5)
click(cords[0], cords[1])
sleep(1)
return repeat(lambda: find_object("success_attack.bmp"), False)
此任务工作是选择适当的攻击速度,然后单击“确认”按钮,然后检查是否执行攻击并将其返回为布尔。
这些都是主要的机器人任务,由主要机器人循环控制
前进到主机器人循环:
(第963行)
while self.on:
if next_task() != False:
#fcounter = 0
if cur_task == (len(tasks) - 1):
cur_task = 0
if castle == max:
self.firstRotation = False
castle = 1
else:
castle += 1
else:
cur_task += 1
else:
boxCheck()
“如果next_task()!= false:”行运行下一个,并通过检查返回布尔来检查它是否成功,并且如果成功完成任务,则仅移至下一个任务。
“ BoxCheck”功能,顾名思义,它检查是否有游戏对话框阻止与游戏的bot交互,并在发现的对话框中删除对话框。
(第994行)
def kb_listener(self):
def on_release(key):
if key == Key.esc:
self.on = False
self.statusbar.showMessage("Stopping...")
return False
with Listener(on_release=on_release) as listener:
listener.join()
该部分负责使用键盘快捷键停止机器人。
此函数'kb_listener'定义了一个键的侦听器,当bot运行时,一旦释放了一个键,键'on_release(key)'被释放的键“键”调用。
。该函数中的第一行检查“如果key == key.esc:”,该函数指出,如果发布的键是“逃生或ESC”,它将仅执行IF支架。
检查pynput库以获取有关此听众的更多信息。
总结:
bot是以序列/任务逻辑开发的,因为游戏是通过彼此进行多个对话框进行的,因此每个任务都取决于在开始之前要完成任务之前的任务。
我很久以前开发了这个机器人,这里有一些必读的反思:
- GUI代码不应与Bot脚本相同的模块。
- 辅助功能不应全部包含在主要机器人功能中。
- 机器人循环应在其自己的函数中。
- 机器人需要一种安全的失败方法,内置案例被卡在其中一个任务中。