# inference/action_mapper.py import subprocess import time import io from PIL import Image class GameController: """ADB 游戏控制器""" def __init__(self, device_id="emulator-5554"): self.device_id = device_id def tap(self, x, y): """点击""" cmd = f"adb -s {self.device_id} shell input tap {x} {y}" subprocess.run(cmd, shell=True) def swipe(self, x1, y1, x2, y2, duration=50): """滑动""" cmd = f"adb -s {self.device_id} shell input swipe {x1} {y1} {x2} {y2} {duration}" subprocess.run(cmd, shell=True) def swipe_continuous(self, x1, y1, x2, y2, duration_ms=50): """连续滑动(用于保持移动)""" cmd = f"adb -s {self.device_id} shell input swipe {x1} {y1} {x2} {y2} {duration_ms}" subprocess.run(cmd, shell=True) def screenshot(self): """截图""" cmd = f"adb -s {self.device_id} exec-out screencap -p" output = subprocess.check_output(cmd, shell=True) return Image.open(io.BytesIO(output)) def get_screen_size(self): """获取屏幕分辨率""" cmd = f"adb -s {self.device_id} shell wm size" output = subprocess.check_output(cmd, shell=True).decode() size_str = output.split(":")[1].strip() w, h = map(int, size_str.split("x")) return w, h class ActionMapper: """ 动作映射器 - 使用持续滑动保持移动 """ def __init__(self, controller): self.ctrl = controller # 按钮坐标 self.buttons = { "joystick_center": (448, 861), "attack": (1936, 925), "skill_1": (1723, 750), "skill_2": (1927, 635), "skill_3": (1443, 969), "recall": (1150, 979), "heal": (1283, 979), "summoner": (1443, 969), "upgrade": (1513, 833), } # 移动目标坐标(摇杆应该滑到的位置) self.move_targets = { "up": (448, 741), "down": (448, 981), "left": (328, 861), "right": (568, 861), "upleft": (363, 776), "upright": (533, 776), "downleft": (363, 946), "downright": (533, 946), } # 当前状态 self.current_direction = None # 动作映射 self.action_to_button = { "attack": "attack", "skill_1": "skill_1", "skill_2": "skill_2", "skill_3": "skill_3", "summoner": "summoner", "recall": "recall", "heal": "heal", "upgrade": "upgrade", } def execute(self, action_name): """ 执行动作(每帧调用) """ # 移动动作 if action_name.startswith("move_"): direction = action_name.replace("move_", "") if direction in self.move_targets: self._do_move(direction) return # 停止移动 if action_name == "move_stop": self._stop_move() return # 点击动作 if action_name in self.action_to_button: button = self.action_to_button[action_name] if button in self.buttons: x, y = self.buttons[button] self.ctrl.tap(x, y) def _do_move(self, direction): """ 执行移动:每帧都滑动到目标位置 这样才能保持英雄持续移动 """ cx, cy = self.buttons["joystick_center"] tx, ty = self.move_targets[direction] # 每帧都执行滑动,保持摇杆位置 self.ctrl.swipe(cx, cy, tx, ty, duration=30) self.current_direction = direction def _stop_move(self): """停止移动:摇杆回中心""" cx, cy = self.buttons["joystick_center"] self.ctrl.swipe(cx, cy, cx, cy, duration=30) self.current_direction = None def attack(self): """普攻""" x, y = self.buttons["attack"] self.ctrl.tap(x, y) def skill_1(self): """技能1""" x, y = self.buttons["skill_1"] self.ctrl.tap(x, y) def skill_2(self): """技能2""" x, y = self.buttons["skill_2"] self.ctrl.tap(x, y) def skill_3(self): """技能3""" x, y = self.buttons["skill_3"] self.ctrl.tap(x, y) def recall(self): """回城""" x, y = self.buttons["recall"] self.ctrl.tap(x, y) if __name__ == "__main__": ctrl = GameController() mapper = ActionMapper(ctrl) print("测试移动...") print("向上移动3秒") for i in range(30): mapper.execute("move_up") time.sleep(0.1) print("停止") mapper.execute("move_stop")