如何用Python+ADB在MEmu模拟器实现游戏缩放?现有代码失效求助
问题分析
你当前的缩放功能失效,核心原因是两个input swipe命令通过&&串行执行,实际是先完成第一个滑动,再执行第二个,而缩放需要两个手指同时进行滑动才能触发系统/游戏的缩放手势。
解决方案
针对MEmu模拟器的ADB环境,提供两种可行修复方式:
方式1:使用ADB多点触控手势命令(推荐,Android 10+支持)
Android 10及以上的ADB提供input touchscreen gesture命令,可模拟多点触控的同时滑动。修改zoom函数的执行逻辑:
import subprocess import time def zoom(zoom_in=True, duration=300, distance=100): # 获取屏幕尺寸 size_output = subprocess.check_output(["adb", "shell", "wm", "size"]).decode().strip() width, height = map(int, size_output.split()[-1].split('x')) # 计算坐标 center_x, center_y = width // 2, height // 2 half_distance = distance // 2 if zoom_in: # 放大:双指从外向内滑动(纠正原逻辑的方向错误) start_x1, start_y1 = center_x - distance, center_y - distance start_x2, start_y2 = center_x + distance, center_y + distance end_x1, end_y1 = center_x - half_distance, center_y - half_distance end_x2, end_y2 = center_x + half_distance, center_y + half_distance else: # 缩小:双指从内向外滑动 start_x1, start_y1 = center_x - half_distance, center_y - half_distance start_x2, start_y2 = center_x + half_distance, center_y + half_distance end_x1, end_y1 = center_x - distance, center_y - distance end_x2, end_y2 = center_x + distance, center_y + distance # 构造多点触控手势命令:同步双指的按下、滑动、抬起动作 # 事件格式:type,x,y,pressure,time_ms(type:0=按下,2=移动,1=抬起) gesture_cmd = ( f"input touchscreen gesture " f"0,{start_x1},{start_y1},100,0 " f"0,{start_x2},{start_y2},100,0 " f"2,{end_x1},{end_y1},100,{duration} " f"2,{end_x2},{end_y2},100,{duration} " f"1,{end_x1},{end_y1},0,{duration+10} " f"1,{end_x2},{end_y2},0,{duration+10}" ) subprocess.run(["adb", "shell", gesture_cmd], shell=True) time.sleep((duration + 10) / 1000 + 0.1)
说明
- 修正了原代码中放大/缩小的方向逻辑(原逻辑将滑动方向搞反)
- 通过时间戳同步双指的动作,确保滑动同时进行
方式2:模拟底层触摸事件(兼容旧版本)
如果MEmu不支持gesture命令,可直接发送sendevent命令模拟多点触控(需先确定触摸设备路径,通常为/dev/input/event2或event3):
import subprocess import time def zoom(zoom_in=True, duration=300, distance=100): # 获取屏幕尺寸 size_output = subprocess.check_output(["adb", "shell", "wm", "size"]).decode().strip() width, height = map(int, size_output.split()[-1].split('x')) # 计算坐标 center_x, center_y = width // 2, height // 2 half_distance = distance // 2 if zoom_in: start_x1, start_y1 = center_x - distance, center_y - distance start_x2, start_y2 = center_x + distance, center_y + distance end_x1, end_y1 = center_x - half_distance, center_y - half_distance end_x2, end_y2 = center_x + half_distance, center_y + half_distance else: start_x1, start_y1 = center_x - half_distance, center_y - half_distance start_x2, start_y2 = center_x + half_distance, center_y + half_distance end_x1, end_y1 = center_x - distance, center_y - distance end_x2, end_y2 = center_x + distance, center_y + distance # 触摸设备路径(可通过`adb shell getevent -il`查询) touch_device = "/dev/input/event2" events = [] # 双指按下 events.append(f"sendevent {touch_device} 3 57 0") events.append(f"sendevent {touch_device} 3 53 {start_x1}") events.append(f"sendevent {touch_device} 3 54 {start_y1}") events.append(f"sendevent {touch_device} 0 0 0") events.append(f"sendevent {touch_device} 3 57 1") events.append(f"sendevent {touch_device} 3 53 {start_x2}") events.append(f"sendevent {touch_device} 3 54 {start_y2}") events.append(f"sendevent {touch_device} 0 0 0") # 分步骤滑动 step_time = duration // 10 step_x1 = (end_x1 - start_x1) // 10 step_y1 = (end_y1 - start_y1) // 10 step_x2 = (end_x2 - start_x2) // 10 step_y2 = (end_y2 - start_y2) // 10 for i in range(10): current_x1 = start_x1 + step_x1 * i current_y1 = start_y1 + step_y1 * i current_x2 = start_x2 + step_x2 * i current_y2 = start_y2 + step_y2 * i events.append(f"sendevent {touch_device} 3 57 0") events.append(f"sendevent {touch_device} 3 53 {current_x1}") events.append(f"sendevent {touch_device} 3 54 {current_y1}") events.append(f"sendevent {touch_device} 0 0 0") events.append(f"sendevent {touch_device} 3 57 1") events.append(f"sendevent {touch_device} 3 53 {current_x2}") events.append(f"sendevent {touch_device} 3 54 {current_y2}") events.append(f"sendevent {touch_device} 0 0 0") events.append(f"sleep {step_time/1000}") # 双指抬起 events.append(f"sendevent {touch_device} 3 57 -1") events.append(f"sendevent {touch_device} 0 0 0") events.append(f"sendevent {touch_device} 3 57 -1") events.append(f"sendevent {touch_device} 0 0 0") subprocess.run(["adb", "shell", "; ".join(events)], shell=True)
说明
- 需先通过
adb shell getevent -il查询模拟器的触摸设备路径和事件编码(如ABS_MT_POSITION_X对应3 53) - 兼容性更强,但实现复杂,需适配不同设备
补充验证
- 手动执行ADB命令测试手势是否生效:
adb shell input touchscreen gesture 0,200,200,100,0 0,600,600,100,0 2,300,300,100,300 2,500,500,100,300 1,300,300,0,310 1,500,500,0,310 - 确认游戏本身支持双指缩放手势(部分游戏有自定义缩放逻辑)
内容的提问来源于stack exchange,提问作者newbie
相关产品推荐
相关产品推荐

