""" 玩家位置模块,用于获取人物当前所在坐标 """ import os import time import re from typing import Optional, Tuple import cv2 import numpy as np import pyautogui from text_finder import TextFinder class PlayerPosition: """玩家位置类,用于获取人物当前所在坐标""" def __init__(self): self.screen_width, self.screen_height = pyautogui.size() self.text_finder = TextFinder() def get_position(self) -> Optional[Tuple[float, float]]: """获取人物当前所在坐标 Returns: Optional[Tuple[float, float]]: 坐标 (x, y),如果识别失败返回 None """ try: # 截图左上角区域 region_width = self.screen_width // 3 region_height = self.screen_height // 4 screenshot = pyautogui.screenshot(region=(0, 0, region_width, region_height)) os.makedirs('screenshot', exist_ok=True) screenshot.save('screenshot/position_screenshot.png') # 使用 text_finder 识别所有文字 text_info_list = self.text_finder.recognize_text_from_image(screenshot) if not text_info_list: print("未识别到任何文字") return None # 打印识别到的所有文字,用于调试 print(f"识别到的文字: {[info['text'] for info in text_info_list]}") # 匹配坐标格式 xx / xx # 匹配格式:坐标:x:25.77y:68.82 或 坐标:x25.77y:68.82(冒号可能被OCR漏识别) coord_pattern = re.compile(r'坐标[::]?\s*[xX][::]?\s*(\d+\.?\d*)\s*[yY][::]?\s*(\d+\.?\d*)') for text_info in text_info_list: text = text_info.get('text', '') match = coord_pattern.search(text) if match: x_coord = float(match.group(1)) y_coord = float(match.group(2)) print(f"找到坐标: ({x_coord}, {y_coord})") return (x_coord, y_coord) print("未找到坐标格式") return None except Exception as e: print(f"获取位置失败: {str(e)}") return None def get_position_with_retry(self, max_retries: int = 3, retry_delay: float = 0.5) -> Optional[Tuple[float, float]]: """带重试机制的获取人物当前所在坐标 Args: max_retries (int): 最大重试次数,默认为 3 retry_delay (float): 每次重试的间隔时间(秒),默认为 0.5 Returns: Optional[Tuple[float, float]]: 坐标 (x, y),如果识别失败返回 None """ for i in range(max_retries): position = self.get_position() if position: return position if i < max_retries - 1: print(f"第 {i + 1} 次尝试失败,{retry_delay} 秒后重试...") time.sleep(retry_delay) print(f"经过 {max_retries} 次尝试,仍未获取到坐标") return None def get_heading(self) -> Optional[float]: """获取人物当前朝向 Returns: Optional[float]: 朝向角度,如果识别失败返回 None """ try: region_width = self.screen_width // 3 region_height = self.screen_height // 4 screenshot = pyautogui.screenshot(region=(0, 0, region_width, region_height)) os.makedirs('screenshot', exist_ok=True) screenshot.save('screenshot/heading_screenshot.png') text_info_list = self.text_finder.recognize_text_from_image(screenshot) if not text_info_list: print("未识别到任何文字") return None print(f"识别到的文字: {[info['text'] for info in text_info_list]}") # 朝向格式可能有冒号也可能没有:朝向:123 或 朝向123 heading_pattern = re.compile(r'朝向[::]?\s*(\d+\.?\d*)\s*') for text_info in text_info_list: text = text_info.get('text', '') text = text.replace(' ', '') match = heading_pattern.search(text) if match: heading = float(match.group(1)) print(f"找到朝向: {heading}°") return heading print("未找到朝向格式") return None except Exception as e: print(f"获取朝向失败: {str(e)}") return None def get_heading_with_retry(self, max_retries: int = 3, retry_delay: float = 0.5) -> Optional[float]: """带重试机制的获取人物当前朝向 Args: max_retries (int): 最大重试次数,默认为 3 retry_delay (float): 每次重试的间隔时间(秒),默认为 0.5 Returns: Optional[float]: 朝向角度,如果识别失败返回 None """ for i in range(max_retries): heading = self.get_heading() if heading is not None: return heading if i < max_retries - 1: print(f"第 {i + 1} 次尝试失败,{retry_delay} 秒后重试...") time.sleep(retry_delay) print(f"经过 {max_retries} 次尝试,仍未获取到朝向") return None