71 lines
2.3 KiB
Python
71 lines
2.3 KiB
Python
|
|
"""
|
|||
|
|
战斗状态检测模块,通过模板匹配判断角色是否处于战斗中
|
|||
|
|
"""
|
|||
|
|
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
|