适配Google Play Games on PC:Android物理键盘长按按键问题求助
适配Google Play Games on PC:WASD键盘移动逻辑实现问题
我正在为2月即将上线Google Play Games on PC的游戏做适配,现有Android客户端通过屏幕摇杆控制移动:点击摇杆移动一格,长按则持续移动直至松开。现在需要实现逻辑完全一致的WASD键盘移动功能。
但遇到了问题:Android的onKeyDown和onKeyUp方法可以处理单次按键事件,不过event.startTracking()方法与onKeyLongPress回调对物理键盘无效——长按W键时,系统会反复触发onKeyDown/onKeyUp事件,无法区分单次点击和长按操作。
我已经查阅相关资料但没找到可行方案,希望得到解决思路。
可行解决方案思路
1. 手动维护按键状态与计时器
- 维护一个全局按键状态集合(比如
HashMap<Integer, Boolean>),记录每个WASD按键是否处于按下未释放状态 - 在
onKeyDown中:- 如果按键未被标记为按下:标记为按下,立即执行一次移动(对应单次点击逻辑),同时启动一个延迟计时器(比如200ms,可根据需求调整),计时器触发后开始持续执行移动逻辑
- 如果按键已被标记为按下:忽略此次重复触发的事件
- 在
onKeyUp中:- 将对应按键标记为未按下,立即停止持续移动逻辑,同时取消对应的延迟计时器
示例核心代码:
private HashMap<Integer, Boolean> keyPressedMap = new HashMap<>(); private Handler moveHandler = new Handler(Looper.getMainLooper()); private Runnable repeatMoveRunnable; private int currentKey = -1; @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if (isWASDKey(keyCode)) { if (!keyPressedMap.getOrDefault(keyCode, false)) { keyPressedMap.put(keyCode, true); currentKey = keyCode; // 单次移动逻辑 moveOnce(keyCode); // 启动延迟计时器,触发长按持续移动 repeatMoveRunnable = new Runnable() { @Override public void run() { if (keyPressedMap.getOrDefault(currentKey, false)) { moveContinuous(currentKey); moveHandler.postDelayed(this, 100); // 持续移动的间隔 } } }; moveHandler.postDelayed(repeatMoveRunnable, 200); // 长按触发阈值 } return true; } return super.onKeyDown(keyCode, event); } @Override public boolean onKeyUp(int keyCode, KeyEvent event) { if (isWASDKey(keyCode)) { keyPressedMap.put(keyCode, false); if (currentKey == keyCode) { moveHandler.removeCallbacks(repeatMoveRunnable); stopContinuousMove(); currentKey = -1; } return true; } return super.onKeyUp(keyCode, event); } // 辅助方法:判断是否为WASD按键 private boolean isWASDKey(int keyCode) { return keyCode == KeyEvent.KEYCODE_W || keyCode == KeyEvent.KEYCODE_A || keyCode == KeyEvent.KEYCODE_S || keyCode == KeyEvent.KEYCODE_D; } // 单次移动逻辑 private void moveOnce(int keyCode) { // 根据keyCode执行对应方向的一格移动 } // 持续移动逻辑 private void moveContinuous(int keyCode) { // 根据keyCode执行对应方向的持续移动(每帧或固定间隔移动) } // 停止持续移动 private void stopContinuousMove() { // 终止持续移动的逻辑 }
2. 利用KeyEvent的重复事件标记
Android物理键盘长按触发的重复onKeyDown事件中,event.isRepeat()会返回true,可以利用这个标记区分首次按下和重复触发:
- 在
onKeyDown中:- 如果
!event.isRepeat():执行单次移动,启动持续移动的计时器 - 如果
event.isRepeat():忽略(或仅在计时器已启动时处理,避免重复触发)
- 如果
- 在
onKeyUp中停止计时器和持续移动
这种方法简化了状态维护,但需注意部分设备的重复事件触发时机存在差异,需要测试适配。
3. 适配Google Play Games on PC专属API
Google Play Games on PC提供了针对键鼠输入的适配支持,可以查看官方文档中的输入兼容部分,是否有专门处理长按输入的API,比如直接监听按键的按下/持续/释放状态,而非依赖Android原生按键回调。
内容的提问来源于stack exchange,提问作者KisnardOnline
相关产品推荐
相关产品推荐

