HonorNet_v1 / inference /action_mapper.py
clarenceleo's picture
Duplicate from clarenceleo/HonorNet_v1
dd9e164
# 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")