Native 运行时里 navigator.getGamepads() 直接返回 null,浏览器的 Gamepad API 在 Native 下不可用。
不过 Native 3.3+ 有扩展插件系统,可以用 C++ 写一个 XInput 插件把手柄数据暴露给 JS。大致思路:
- 创建一个 Native 扩展插件(C++ DLL),在里面调用 Windows 的 XInput API 读取手柄状态
- 通过 jsvm API 把手柄数据暴露给 JS 层
C++ 侧核心代码大概这样:
#include <extension/LayaExtension.h>
#include <Xinput.h>
#pragma comment(lib, "xinput.lib")
static jsvm_value getGamepadState(jsvm_env env, jsvm_callback_info info) {
XINPUT_STATE state;
ZeroMemory(&state, sizeof(XINPUT_STATE));
if (XInputGetState(0, &state) != ERROR_SUCCESS) {
jsvm_value null_val;
jsvm_get_null(env, &null_val);
return null_val;
}
jsvm_value obj;
jsvm_create_object(env, &obj);
// 按钮
jsvm_value buttons;
jsvm_create_int32(env, state.Gamepad.wButtons, &buttons);
jsvm_set_named_property(env, obj, "buttons", buttons);
// 摇杆
jsvm_value lx, ly, rx, ry;
jsvm_create_double(env, state.Gamepad.sThumbLX / 32768.0, &lx);
jsvm_create_double(env, state.Gamepad.sThumbLY / 32768.0, &ly);
jsvm_create_double(env, state.Gamepad.sThumbRX / 32768.0, &rx);
jsvm_create_double(env, state.Gamepad.sThumbRY / 32768.0, &ry);
jsvm_set_named_property(env, obj, "leftStickX", lx);
jsvm_set_named_property(env, obj, "leftStickY", ly);
jsvm_set_named_property(env, obj, "rightStickX", rx);
jsvm_set_named_property(env, obj, "rightStickY", ry);
// 扳机
jsvm_value lt, rt;
jsvm_create_double(env, state.Gamepad.bLeftTrigger / 255.0, <);
jsvm_create_double(env, state.Gamepad.bRightTrigger / 255.0, &rt);
jsvm_set_named_property(env, obj, "leftTrigger", lt);
jsvm_set_named_property(env, obj, "rightTrigger", rt);
return obj;
}
JS 侧在 onUpdate 里轮询:
onUpdate() {
let state = gamepad_extension.getGamepadState();
if (!state) return;
// A 键 = 0x1000, B 键 = 0x2000, X = 0x4000, Y = 0x8000
if (state.buttons & 0x1000) console.log("A pressed");
let lx = state.leftStickX; // -1 ~ 1
let ly = state.leftStickY;
}
扩展插件的完整开发流程(CMake 配置、清单文件、部署方式)可以参考 IDE 发布 Windows Native 项目后 publish/extension/ 目录下的开发指南和示例模板。
以上由 AI 自动回复,仅供参考。若无异议将不再人工审查;如需人工介入请回帖说明。