Android onTouchEvent响应ACTION_UP过慢导致游戏转向异常
2D赛车游戏触摸转向异常修复
问题现象
- 预设交互规则:按住屏幕左侧车辆左转,按住屏幕右侧车辆右转,松开所有触摸后车辆回正直行
- 异常表现:按住屏幕左侧快速松手后立刻触摸屏幕右侧,车辆仍保持左转状态
- 原错误判断:认为是
onTouchEvent对MotionEvent.ACTION_UP/ACTION_DOWN事件响应过慢,实际为代码逻辑存在三处明显错误
根因分析
- 方向赋值逻辑完全写反:原代码中屏幕左侧(
event.getX() < screenX/2)按下时设置的是isGoingRight = true,屏幕右侧按下时设置的是isGoingLeft = true,和预设交互逻辑完全相反 - 事件获取方式不兼容多点触控:直接使用
event.getAction()匹配事件类型,无法识别多点触控下的ACTION_POINTER_DOWN/ACTION_POINTER_UP事件,快速切换触摸时会出现事件漏处理 - 未绑定触摸点ID:所有触摸事件共用同一套状态标记,快速操作时前一个触摸点的抬起事件、后一个触摸点的按下事件时序交叉,会导致转向状态被错误覆盖
修复后实现代码
// 记录当前控制转向的触摸点ID,初始值-1表示无激活的控制触摸点 private int activeTouchPointerId = -1; @Override public boolean onTouchEvent(MotionEvent event) { // 用getActionMasked获取剥离指针索引的纯事件类型,兼容多点触控 int action = event.getActionMasked(); switch(action) { case MotionEvent.ACTION_DOWN: case MotionEvent.ACTION_POINTER_DOWN: // 找到当前按下的指针对应的索引和ID int pointerIndex = event.getActionIndex(); int pointerId = event.getPointerId(pointerIndex); // 仅当当前没有激活的控制触摸点时,才处理新的按下事件,避免多点干扰 if (activeTouchPointerId == -1) { activeTouchPointerId = pointerId; float x = event.getX(pointerIndex); player.touch = true; if (x < screenX / 2) { // 左半屏对应左转 player.isGoingLeft = true; player.isGoingRight = false; } else { // 右半屏对应右转 player.isGoingRight = true; player.isGoingLeft = false; } } break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_POINTER_UP: pointerIndex = event.getActionIndex(); pointerId = event.getPointerId(pointerIndex); // 只有当前抬起的是正在控制转向的触摸点时,才重置状态 if (pointerId == activeTouchPointerId) { activeTouchPointerId = -1; player.isGoingRight = false; player.isGoingLeft = false; player.touch = false; } break; } return true; }
优化说明
- 修复后同时支持多点触控场景,不会因为其他手指误触屏幕导致转向失控
- 只有负责控制的触摸点抬起时才会重置方向,避免快速操作时事件时序交叉导致的状态异常
- 修正了原代码左右方向赋值写反的低级错误
内容的提问来源于stack exchange,提问作者josef
相关产品推荐
相关产品推荐

