Files
wow/stuck_handler.py

91 lines
2.9 KiB
Python
Raw Permalink Normal View History

2026-03-18 09:04:37 +08:00
import math
import time
import random
import pyautogui
class StuckHandler:
# 针对 0.xxxx 坐标系优化
DEFAULT_MIN_MOVE = 0.002 # 极其微小的位移也算移动
DEFAULT_STUCK_DURATION = 2.5 # 减少等待时间,提高效率
TURN_GRACE_SEC = 1.0 # 缩短宽限期,边走边转不需要 5 秒
def __init__(self, min_move_threshold=None, stuck_duration_sec=None):
self.last_pos = None
self.stuck_start_time = 0
self.min_move = min_move_threshold or self.DEFAULT_MIN_MOVE
self.stuck_duration = stuck_duration_sec or self.DEFAULT_STUCK_DURATION
def check_stuck(self, state, last_turn_time):
"""
检测卡死
只有在正在前进按住W且坐标长时间不刷新时触发
"""
current_pos = (state['x'], state['y'])
now = time.time()
# 1. 初始化
if self.last_pos is None:
self.last_pos = current_pos
return False
# 2. 计算位移
dist = math.sqrt(
(current_pos[0] - self.last_pos[0]) ** 2 +
(current_pos[1] - self.last_pos[1]) ** 2
)
# 3. 核心判定:
# 如果位移足够大,重置所有计数
if dist > self.min_move:
self.stuck_start_time = 0
self.last_pos = current_pos
return False
# 4. 位移不足时的处理
# 宽限期优化:只有在非频繁转向时才开始计时
# (避免边走边转的短脉冲把卡死计时器刷掉)
if last_turn_time and (now - last_turn_time) < 0.2:
# 如果刚刚那一瞬间正在转向脉冲中,本帧跳过,不重置计数也不判定
return False
if self.stuck_start_time == 0:
self.stuck_start_time = now
elif (now - self.stuck_start_time) >= self.stuck_duration:
return True
return False
def resolve_stuck(self):
"""增强版脱困针对血DK挂机环境"""
print(">>> [警告] 检测到撞墙,正在执行脱困动作...")
# 1. 全停
for k in ("w", "a", "d", "s"):
pyautogui.keyUp(k)
# 2. 倒车并转向(组合动作更有效)
pyautogui.keyDown("s")
turn_key = random.choice(["a", "d"])
pyautogui.keyDown(turn_key)
# 倒车时间稍长一点,离开障碍物
2026-03-23 09:50:08 +08:00
time.sleep(0.5)
2026-03-18 09:04:37 +08:00
# 3. 尝试跳跃脱离地形卡位
pyautogui.press("space")
2026-03-23 09:50:08 +08:00
time.sleep(0.5)
2026-03-18 09:04:37 +08:00
pyautogui.keyUp(turn_key)
pyautogui.keyUp("s")
# 4. 往前稍微走一步,重新锁定坐标
pyautogui.keyDown("w")
time.sleep(0.5)
pyautogui.keyUp("w")
self.reset()
print(">>> 脱困尝试结束")
def reset(self):
self.last_pos = None
self.stuck_start_time = 0