""" 战斗状态检测模块,通过模板匹配判断角色是否处于战斗中 """ import os import logging import cv2 import numpy as np import pyautogui from config import GameConfig class CombatDetector: """通过截图与模板匹配判断当前是否处于战斗状态""" TEMPLATES = [ 'images/1.png', 'images/2.png', 'images/3.png', 'images/4.png', ] SCREENSHOT_PATH = 'screenshot/combat_screenshot.png' def __init__(self, config: GameConfig): self.config = config self.screen_width, self.screen_height = pyautogui.size() self.logger = logging.getLogger(__name__) os.makedirs(os.path.dirname(self.SCREENSHOT_PATH), exist_ok=True) def is_in_combat(self) -> bool: """判断是否处于战斗中。 截取屏幕左上半区域,逐一与模板图片做归一化相关系数匹配, 任一模板匹配值超过阈值即视为处于战斗状态。 Returns: bool: 处于战斗中返回 True,否则返回 False """ try: region_width = self.screen_width // 2 region_height = self.screen_height // 2 screenshot = pyautogui.screenshot(region=(0, 0, region_width, region_height)) screenshot.save(self.SCREENSHOT_PATH) screenshot_cv = cv2.cvtColor(np.array(screenshot), cv2.COLOR_RGB2BGR) for template_file in self.TEMPLATES: if not os.path.exists(template_file): self.logger.warning(f"模板文件不存在,跳过: {template_file}") continue template = cv2.imread(template_file) result = cv2.matchTemplate( screenshot_cv, template, cv2.TM_CCOEFF_NORMED ) _, max_val, _, _ = cv2.minMaxLoc(result) if max_val > self.config.recognition_threshold: self.logger.info( f"战斗状态: 是(模板: {template_file},匹配值: {max_val:.2f})" ) return True self.logger.info("战斗状态: 否(所有模板均未匹配)") return False except Exception as e: self.logger.error(f"判断战斗状态失败: {str(e)}") return False