import cv2 from utils.get_image import GetImage from utils.mouse import init_mouse_keyboard, Mouse_guiji from ultralytics import YOLO import time import serial import ch9329Comm import random import math from utils import shizi from config import config_manager # 加载YOLO模型 model = YOLO(r"best.pt").to('cuda') model0 = YOLO(r"best0.pt").to('cuda') # 从配置加载 active_group = config_manager.get_active_group() if active_group is None: print("❌ 没有活动的配置组,请在gui_config.py中设置") exit(1) print(f"📋 使用配置组: {active_group['name']}") # 初始化串口和鼠标 init_mouse_keyboard(active_group) # 初始化键盘和鼠标 keyboard = ch9329Comm.keyboard.DataComm() from utils.mouse import mouse, mouse_gui # 导入已初始化的mouse和mouse_gui # 创建全局的mouse_gui实例 mouse_gui = Mouse_guiji() # 初始化采集卡 get_image = GetImage( cam_index=active_group['camera_index'], width=active_group['camera_width'], height=active_group['camera_height'] ) # 检查采集卡是否初始化成功 if get_image.cap is None: print(f"❌ 采集卡 {active_group['camera_index']} 初始化失败") print("请检查:") print("1. 采集卡是否正确连接") print("2. 采集卡索引是否正确") print("3. 采集卡驱动是否安装") exit(1) print(f"✅ 初始化完成 - 串口:{active_group['serial_port']} 采集卡:{active_group['camera_index']}") # 全局变量 left = 0 top = 30 k = 0 # 控制转圈的方向 panduan = False # 是否在图内 boss_pd = False # 是否到boss关卡 rw = (632, 378) # 从配置读取移动速度 v = active_group['move_velocity'] def yolo_shibie(im_PIL, detections, model): results = model(im_PIL) # 目标检测 for result in results: for i in range(len(result.boxes.xyxy)): left, top, right, bottom = result.boxes.xyxy[i] scalar_tensor = result.boxes.cls[i] value = scalar_tensor.item() label = result.names[int(value)] if label == 'center' or label == 'next' or label == 'boss' or label == 'zhaozi': player_x = int(left + (right - left) / 2) player_y = int(top + (bottom - top) / 2) + 30 RW = [player_x, player_y] detections[label] = RW elif label == 'daojv' or label == 'gw': player_x = int(left + (right - left) / 2) player_y = int(top + (bottom - top) / 2) + 30 RW = [player_x, player_y] detections[label].append(RW) elif label == 'npc1' or label == 'npc2' or label == 'npc3' or label == 'npc4': player_x = int(left + (right - left) / 2) player_y = int(bottom) + 30 RW = [player_x, player_y] detections[label] = RW return detections def sq(p1, p2): """计算两点之间的欧式距离""" return math.sqrt((p1[0] - p2[0]) ** 2 + (p1[1] - p2[1]) ** 2) def process_points(points): if not points: return None # 空列表情况 n = len(points) if n == 1: # 只有一个点,直接返回 return points[0] elif n == 2: # 两个点取中点 x = (points[0][0] + points[1][0]) / 2 y = (points[0][1] + points[1][1]) / 2 return [x, y] else: # 随机选3个点 sample_points = random.sample(points, 3) # 对每个点计算到这3个点的总距离 min_sum = float('inf') best_point = None for p in points: dist_sum = sum(sq(p, sp) for sp in sample_points) if dist_sum < min_sum: min_sum = dist_sum best_point = p return best_point def move_randomly(rw, k): k = k % 4 suiji_t = float(random.randint(10, 13) / 10) if k == 0: keyboard.send_data("66") time.sleep(suiji_t) keyboard.release() # Release elif k == 1: keyboard.send_data("88") time.sleep(suiji_t) keyboard.release() # Release elif k == 2: keyboard.send_data("44") time.sleep(suiji_t) keyboard.release() # Release elif k == 3: keyboard.send_data("22") time.sleep(suiji_t) keyboard.release() # Release return k + 1 def move_to(rw, mb): """使用配置的v值""" global v v = active_group['move_velocity'] # 每次都从配置读取最新值 if rw[0] >= mb[0]: keyboard.send_data("44") time.sleep(float(abs(rw[0] - mb[0]) / v)) keyboard.release() # Release else: keyboard.send_data("66") time.sleep(float(abs(rw[0] - mb[0]) / v)) keyboard.release() # Release if rw[1] >= mb[1]: keyboard.send_data("88") time.sleep(float(abs(rw[1] - mb[1]) / v)) keyboard.release() # Release else: keyboard.send_data("22") time.sleep(float(abs(rw[1] - mb[1]) / v)) keyboard.release() i = 0 print("🚀 开始自动化...") while True: detections = { 'center': None, 'next': None, 'npc1': None, 'npc2': None, 'npc3': None, 'npc4': None, 'boss': None, 'daojv': [], 'gw': [], 'zhaozi': None } im_opencv = get_image.get_frame() # [RGB,PIL] if im_opencv is None: print("⚠️ 无法获取图像帧,跳过本次循环") time.sleep(0.1) continue detections = yolo_shibie(im_opencv[1], detections, model) if shizi.tuwai(im_opencv[0]): # 进图算法 im_opencv = get_image.get_frame() # [RGB,PIL] if im_opencv is None: print("⚠️ 无法获取图像帧,跳过本次循环") time.sleep(0.1) continue detections = yolo_shibie(im_opencv[1], detections, model0) print('当前在城镇中') if detections['npc1'] is not None and sq(rw, detections['npc1']) > 80: print("向npc1靠近") print(sq(rw, detections['npc1'])) move_to(rw, detections['npc1']) continue elif detections['npc1'] is not None and sq(rw, detections['npc1']) <= 80: print("在npc旁边,向上走") print(sq(rw, detections['npc1'])) mb = (detections['npc1'][0], detections['npc1'][1] - 1010) move_to(rw, mb) continue elif detections['npc3'] is not None and detections['npc4'] is None: print("在npc3旁边,向右走") mb = (rw[0], detections['npc3'][1] - 50) move_to(rw, mb) mb = (rw[0] + 700, rw[1]) move_to(rw, mb) continue elif detections['npc4'] is not None: if sq(detections['npc4'], rw) < 50: print("离npc4很近 直接进入") keyboard.send_data("DD") time.sleep(0.15) keyboard.release() time.sleep(1) im_opencv = get_image.get_frame() # [RGB,PIL] if im_opencv is None: print("⚠️ 无法获取图像帧") continue if shizi.daoying(im_opencv[0]): mouse_gui.send_data_absolute(rw[0], rw[1] - 110, may=1) time.sleep(1) continue else: print("离npc4有点远 点击进入") move_to(rw, detections['npc4']) time.sleep(1) im_opencv = get_image.get_frame() # [RGB,PIL] if im_opencv is None: print("⚠️ 无法获取图像帧") continue if shizi.daoying(im_opencv[0]): mouse_gui.send_data_absolute(rw[0], rw[1] - 110, may=1) time.sleep(1) continue elif shizi.tiaozhan(im_opencv[0]): # 开启挑战 print('进入塔4') mouse_gui.send_data_absolute(left + 1100, top + 600, may=1) time.sleep(0.3) mouse_gui.send_data_absolute(left + 433, top + 455, may=1) panduan = True continue elif shizi.jieshu(im_opencv[0]): # 结束挑战 print('结束挑战') mouse_gui.send_data_absolute(left + 542, top + 644, may=1) time.sleep(0.8) mouse_gui.send_data_absolute(left + 706, top + 454, may=1) continue elif panduan: # 图内情况 print("在图内") if shizi.shuzi(im_opencv[0]): boss_pd = True print("进入到boss!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!") if shizi.fuhuo(im_opencv[0]): print('点击复活') mouse_gui.send_data_absolute(left + 536, top + 627, may=1) time.sleep(0.15) keyboard.release() continue if shizi.tuichu(im_opencv[0]) and detections['next'] is None and len(detections['daojv']) == 0 and len(detections['gw']) == 0 and boss_pd: print("识别到可以退出挑战!!!!!!!!!!!!!!!!!!") for i in range(3): time.sleep(0.5) im_opencv = get_image.get_frame() # [RGB,PIL] if im_opencv is None: print("⚠️ 无法获取图像帧") continue detections = { 'center': None, 'next': None, 'npc1': None, 'npc2': None, 'npc3': None, 'npc4': None, 'boss': None, 'daojv': [], 'gw': [], 'zhaozi': None } detections = yolo_shibie(im_opencv[1], detections, model) if detections['next'] is not None or len(detections['daojv']) != 0 or len(detections['gw']) != 0 or detections['boss'] is not None: break else: mouse_gui.send_data_absolute(left + 640, top + 40, may=1) # 点击退出 panduan = False # 退出挑战 boss_pd = False time.sleep(2.0) continue if detections['center'] is None and detections['next'] is None and (len(detections['gw']) != 0 or detections["boss"] is not None): # 识别不到中心情况 但是有怪物 print("未检测到中心点,但是有怪物") if len(detections['gw']) != 0: move_to(rw, detections['gw'][0]) time.sleep(0.26) elif detections['boss'] is not None: # 跟随boss boss_suiji1 = random.randint(-30, 30) boss_suiji2 = random.randint(-30, 30) detections['boss'] = (detections['boss'][0] + boss_suiji1, detections['boss'][1] + boss_suiji2) move_to(rw, detections['boss']) time.sleep(0.7) continue elif (detections['center'] is not None and detections['next'] is None and len(detections['gw']) != 0) or (boss_pd == True and detections['center'] is not None and detections['next'] is None): # 识别到中心 但是有怪物 if detections['center'][0] >= rw[0] and detections['center'][1] < rw[1]: # 3 mb = (rw[0] + 100, rw[1]) elif detections['center'][0] <= rw[0] and detections['center'][1] < rw[1]: # 4 mb = (rw[0], rw[1] - 100) elif detections['center'][0] <= rw[0] and detections['center'][1] > rw[1]: # 1 mb = (rw[0] - 100, rw[1]) elif detections['center'][0] >= rw[0] and detections['center'][1] > rw[1]: # 2 mb = (rw[0], rw[1] + 100) move_to(rw, mb) time.sleep(0.25) continue elif boss_pd == True and detections['center'] is None and detections['next'] is None: # boss出现了 但是没有中心 k = move_randomly(rw, k) continue elif detections['next'] is not None: print('进入下一层啦啦啦啦啦啦') panduan = True move_to(rw, detections['next']) for i in range(2): keyboard.send_data("DD") time.sleep(0.15) keyboard.release() continue else: k = move_randomly(rw, k) continue elif shizi.daoying(im_opencv[0]): mouse_gui.send_data_absolute(rw[0], rw[1] - 110, may=1) time.sleep(1) continue