监听游戏手柄的轴和按键事件（C/C++）
====================

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/c5/v3/5cKcaNs1RdWcRL8WGzk3Eg/note_3.0-zh-cn.png?HW-CC-KV=V1&HW-CC-Date=20260612T073608Z&HW-CC-Expire=86400&HW-CC-Sign=A1F7DC2BE905151199AD8BA7E95E40EC1EE81F7BCF0E08E20C18C65538316008)

须先完成[监听设备上下线](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/game-controller-monitor-device)功能的开发后，才能进行游戏手柄轴事件和按键事件的监听注册。

#### 功能介绍

Game Controller Kit提供游戏手柄轴事件和按键事件的监听能力。通过轴事件和按键事件的监听注册，在玩家操作手柄按键和摇杆时可获得对应回调通知。

#### 按键

Game Controller Kit支持的手柄键位参考图如下：

![](https://contentcenter-vali-drcn.dbankcdn.cn/pvt_2/DeveloperAlliance_scene_100_1/2b/v3/rAR4WVRcQXC4lKGRitm9vg/zh-cn_image_0000002625188551.png?HW-CC-KV=V1&HW-CC-Date=20260612T073608Z&HW-CC-Expire=86400&HW-CC-Sign=4EC29A8809E0142CAD771255F1F31D3AA3745F79D1AF2C8C5E4BDBC7613B2C52)

#### 接口说明

接口详细介绍请参考[API参考](https://developer.huawei.com/consumer/cn/doc/harmonyos-references/capi-game-controller)。

| 接口名 | 描述 |
| :-- | :-- |
| OH\_GamePad\_LeftShoulder\_RegisterButtonInputMonitor | 注册LeftShoulder按键事件的监听。 |
| OH\_GamePad\_RightShoulder\_RegisterButtonInputMonitor | 注册RightShoulder按键事件的监听。 |
| OH\_GamePad\_LeftTrigger\_RegisterButtonInputMonitor | 注册LeftTrigger按键事件的监听。 |
| OH\_GamePad\_RightTrigger\_RegisterButtonInputMonitor | 注册RightTrigger按键事件的监听。 |
| OH\_GamePad\_ButtonMenu\_RegisterButtonInputMonitor | 注册Menu按键事件的监听。 |
| OH\_GamePad\_ButtonHome\_RegisterButtonInputMonitor | 注册Home按键事件的监听。 |
| OH\_GamePad\_ButtonA\_RegisterButtonInputMonitor | 注册A按键事件的监听。 |
| OH\_GamePad\_ButtonB\_RegisterButtonInputMonitor | 注册B按键事件的监听。 |
| OH\_GamePad\_ButtonX\_RegisterButtonInputMonitor | 注册X按键事件的监听。 |
| OH\_GamePad\_ButtonY\_RegisterButtonInputMonitor | 注册Y按键事件的监听。 |
| OH\_GamePad\_ButtonC\_RegisterButtonInputMonitor | 注册C按键事件的监听。 |
| OH\_GamePad\_Dpad\_LeftButton\_RegisterButtonInputMonitor | 注册方向按键的向左按键事件的监听。 |
| OH\_GamePad\_Dpad\_RightButton\_RegisterButtonInputMonitor | 注册方向按键的向右按键事件的监听。 |
| OH\_GamePad\_Dpad\_UpButton\_RegisterButtonInputMonitor | 注册方向按键的向上按键事件的监听。 |
| OH\_GamePad\_Dpad\_DownButton\_RegisterButtonInputMonitor | 注册方向按键的向下按键事件的监听。 |
| OH\_GamePad\_LeftThumbstick\_RegisterButtonInputMonitor | 注册LeftThumbstick按键事件的监听。 |
| OH\_GamePad\_RightThumbstick\_RegisterButtonInputMonitor | 注册RightThumbstick按键事件的监听。 |
| OH\_GamePad\_LeftTrigger\_RegisterAxisInputMonitor | 注册LeftTrigger轴事件的监听。 |
| OH\_GamePad\_RightTrigger\_RegisterAxisInputMonitor | 注册RightTrigger轴事件的监听。 |
| OH\_GamePad\_Dpad\_RegisterAxisInputMonitor | 注册方向按键轴事件的监听。 |
| OH\_GamePad\_LeftThumbstick\_RegisterAxisInputMonitor | 注册LeftThumbstick轴事件的监听。 |
| OH\_GamePad\_RightThumbstick\_RegisterAxisInputMonitor | 注册RightThumbstick轴事件的监听。 |

#### 开发步骤

#### \[h2\]链接动态库

target\_link\_libraries(entry PUBLIC libohgame\_controller.z.so)

#### \[h2\]导入模块

#include <GameControllerKit/game\_pad.h>

#### \[h2\]注册和取消注册轴事件的监听

调用相应接口注册或取消注册轴事件回调，通过回调函数获取轴值。

物理轴及其对应的轴值获取接口如下：

| 物理轴 | 轴值获取接口 |
| :-- | :-- |
| LeftThumbstick | 
通过OH\_GamePad\_AxisEvent\_GetXAxisValue获取X轴的轴值。

通过OH\_GamePad\_AxisEvent\_GetYAxisValue获取Y轴的轴值。

 |
| RightThumbstick | 

通过OH\_GamePad\_AxisEvent\_GetZAxisValue获取Z轴的轴值。

通过OH\_GamePad\_AxisEvent\_GetRZAxisValue获取RZ轴的轴值。

 |
| DPAD | 

通过OH\_GamePad\_AxisEvent\_GetHatXAxisValue获取HatX轴的轴值。

通过OH\_GamePad\_AxisEvent\_GetHatYAxisValue获取HatY轴的轴值。

 |
| LeftTrigger | 通过OH\_GamePad\_AxisEvent\_GetBrakeAxisValue获取Brake轴的轴值。 |
| RightTrigger | 通过OH\_GamePad\_AxisEvent\_GetGasAxisValue获取Gas轴的轴值。 |

以LeftThumbstick轴事件为例。

napi\_value GamePad::LeftThumbstick\_RegisterAxisInputMonitor(napi\_env env, napi\_callback\_info info) {
    napi\_value result;
    GameController\_ErrorCode errorCode =
        OH\_GamePad\_LeftThumbstick\_RegisterAxisInputMonitor(GamePad::LeftThumbstick\_OnAxisEvent);
    if (errorCode != GameController\_ErrorCode::GAME\_CONTROLLER\_SUCCESS) {
        OH\_LOG\_ERROR(LOG\_APP, "LeftThumbstick\_RegisterAxisInputMonitor Failed, %{public}d", errorCode);
        napi\_create\_double(env, errorCode, &result);
        return result;
    }
    OH\_LOG\_INFO(LOG\_APP, "LeftThumbstick\_RegisterAxisInputMonitor Success");
    napi\_create\_double(env, 0, &result);
    return result;
}

napi\_value GamePad::LeftThumbstick\_UnregisterAxisInputMonitor(napi\_env env, napi\_callback\_info info) {
    napi\_value result;
    GameController\_ErrorCode errorCode = OH\_GamePad\_LeftThumbstick\_UnregisterAxisInputMonitor();
    if (errorCode != GameController\_ErrorCode::GAME\_CONTROLLER\_SUCCESS) {
        OH\_LOG\_ERROR(LOG\_APP, "LeftThumbstick\_UnregisterAxisInputMonitor Failed, %{public}d", errorCode);
        napi\_create\_double(env, errorCode, &result);
        return result;
    }
    OH\_LOG\_INFO(LOG\_APP, "LeftThumbstick\_UnregisterAxisInputMonitor Success");
    napi\_create\_double(env, 0, &result);
    return result;
}

void GamePad::LeftThumbstick\_OnAxisEvent(const struct GamePad\_AxisEvent \*axisEvent) {
    std::string val = "X";
    double xAxisValue;
    OH\_GamePad\_AxisEvent\_GetXAxisValue(axisEvent, &xAxisValue);
    val.append(std::to\_string(xAxisValue)).append("\_Y");
    double yAxisValue;
    OH\_GamePad\_AxisEvent\_GetYAxisValue(axisEvent, &yAxisValue);
    val.append(std::to\_string(yAxisValue));
    OnAxisEvent(axisEvent, "LeftThumbstick\_OnAxisEvent", val);
}

#### \[h2\]注册按键事件的监听和取消注册

调用相应接口注册或取消注册按键事件回调，从回调函数中获取按键值。

以下是按键名称与对应按键值：

| 按键名称 | 按键值 |
| :-- | :-- |
| LeftShoulder | 2307 |
| RightShoulder | 2308 |
| LeftTrigger | 2309 |
| RightTrigger | 2310 |
| LeftThumbstick | 2314 |
| RightThumbstick | 2315 |
| ButtonHome | 2311 |
| ButtonMenu | 2312 |
| ButtonA | 2301 |
| ButtonB | 2302 |
| ButtonC | 2303 |
| ButtonX | 2304 |
| ButtonY | 2305 |
| Dpad\_UpButton | 2012 |
| Dpad\_DownButton | 2013 |
| Dpad\_LeftButton | 2014 |
| Dpad\_RightButton | 2015 |

以LeftShoulder按键事件为例。

napi\_value GamePad::LeftShoulder\_RegisterButtonInputMonitor(napi\_env env, napi\_callback\_info info) {
    napi\_value result;
    GameController\_ErrorCode errorCode =
        OH\_GamePad\_LeftShoulder\_RegisterButtonInputMonitor(GamePad::LeftShoulder\_OnButtonEvent);
    if (errorCode != GameController\_ErrorCode::GAME\_CONTROLLER\_SUCCESS) {
        OH\_LOG\_ERROR(LOG\_APP, "LeftShoulder\_RegisterButtonInputMonitor Failed, %{public}d", errorCode);
        napi\_create\_double(env, errorCode, &result);
        return result;
    }
    OH\_LOG\_INFO(LOG\_APP, "LeftShoulder\_RegisterButtonInputMonitor Success");
    napi\_create\_double(env, 0, &result);
    return result;
}

napi\_value GamePad::LeftShoulder\_UnregisterButtonInputMonitor(napi\_env env, napi\_callback\_info info) {
    napi\_value result;
    GameController\_ErrorCode errorCode = OH\_GamePad\_LeftShoulder\_UnregisterButtonInputMonitor();
    if (errorCode != GameController\_ErrorCode::GAME\_CONTROLLER\_SUCCESS) {
        OH\_LOG\_ERROR(LOG\_APP, "LeftShoulder\_UnregisterButtonInputMonitor Failed, %{public}d", errorCode);
        napi\_create\_double(env, errorCode, &result);
        return result;
    }
    OH\_LOG\_INFO(LOG\_APP, "LeftShoulder\_UnregisterButtonInputMonitor Success");
    napi\_create\_double(env, 0, &result);
    return result;
}

void GamePad::LeftShoulder\_OnButtonEvent(const struct GamePad\_ButtonEvent \*buttonEvent) {
    OnButtonEvent(buttonEvent, "LeftShoulder\_OnButtonEvent");
}

void GamePad::OnButtonEvent(const struct GamePad\_ButtonEvent \*buttonEvent, const std::string &buttonName) {
    std::string temp;
    temp.append("OnButtonEvent:").append(buttonName);
    char \*deviceId;
    OH\_GamePad\_ButtonEvent\_GetDeviceId(buttonEvent, &deviceId);
    temp.append(" ,deviceId:").append(deviceId);
    free(deviceId);
    GamePad\_Button\_ActionType action;
    OH\_GamePad\_ButtonEvent\_GetButtonAction(buttonEvent, &action);
    temp.append(" ,action:").append(std::to\_string(action));
    std::int32\_t buttonCode;
    OH\_GamePad\_ButtonEvent\_GetButtonCode(buttonEvent, &buttonCode);
    temp.append(" ,code:").append(std::to\_string(buttonCode));
    char \*buttonCodeName;
    OH\_GamePad\_ButtonEvent\_GetButtonCodeName(buttonEvent, &buttonCodeName);
    temp.append(" ,codeName:").append(buttonCodeName);
    free(buttonCodeName);
    std::int64\_t actionTime;
    OH\_GamePad\_ButtonEvent\_GetActionTime(buttonEvent, &actionTime);
    temp.append(" ,actionTime:").append(std::to\_string(actionTime));
    std::int32\_t count;
    OH\_GamePad\_PressedButtons\_GetCount(buttonEvent, &count);
    temp.append(" ,count:").append(std::to\_string(count));
    std::string pressedButtonCodes;
    for (std::int32\_t idx = 0; idx < count; idx++) {
        GamePad\_PressedButton \*pressedButton;
        OH\_GamePad\_PressedButtons\_GetButtonInfo(buttonEvent, idx, &pressedButton);
        int code;
        OH\_GamePad\_PressedButton\_GetButtonCode(pressedButton, &code);
        char \*name;
        OH\_GamePad\_PressedButton\_GetButtonCodeName(pressedButton, &name);
        if (idx != 0) {
            pressedButtonCodes = pressedButtonCodes.append(";");
        }
        pressedButtonCodes = pressedButtonCodes.append(std::to\_string(code) + "|").append(name);
        free(name);
        OH\_GamePad\_DestroyPressedButton(&pressedButton);
    }
    temp.append(" ,pressedButtonCodes:").append(pressedButtonCodes);
    OH\_LOG\_INFO(LOG\_APP, "%{public}s", temp.c\_str());
    Log::GetInstance()->PrintLog(temp);
}