Skip to content

useGamepad

类别
导出体积
1.25 kB
上次更改
2 minutes ago

提供了 Gamepad API 的响应式绑定。

示例

此设备不支持游戏手柄。似乎你的设备不支持游戏手柄 API。查看这里以查看支持游戏手柄的设备列表。

使用方法

由于 Gamepad API 的工作方式,你必须使用游戏手柄与页面进行交互,然后才能检测到它。

vue
<script setup>
import { useGamepad } from '@vueuse/core'
import { computed } from 'vue'

const { isSupported, gamepads } = useGamepad()
const gamepad = computed(() => gamepads.value.find(g => g.mapping === 'standard'))
</script>

<template>
  <span>
    {{ gamepad.id }}
  </span>
</template>

游戏手柄更新

目前,Gamepad API 没有事件支持来更新游戏手柄的状态。为了更新游戏手柄的状态,使用 requestAnimationFrame 来轮询游戏手柄的变化。你可以通过使用 useGamepad 提供的 pauseresume 函数来控制此轮询。

ts
import { useGamepad } from '@vueuse/core'

const { pause, resume, gamepads } = useGamepad()

pause()

// 游戏手柄对象不会更新

resume()

// 游戏手柄对象将在用户输入时更新

游戏手柄连接和断开事件

当游戏手柄连接或断开连接时,onConnectedonDisconnected 事件将触发。

ts
const { gamepads, onConnected, onDisconnected } = useGamepad()

onConnected((index) => {
  console.log(`${gamepads.value[index].id} connected`)
})

onDisconnected((index) => {
  console.log(`${index} disconnected`)
})

振动

游戏手柄触觉 API 的支持不完整,请在使用之前检查兼容性表

ts
import { computed } from 'vue'

const supportsVibration = computed(() => gamepad.hapticActuators.length > 0)
function vibrate() {
  if (supportsVibration.value) {
    const actuator = gamepad.hapticActuators[0]
    actuator.playEffect('dual-rumble', {
      startDelay: 0,
      duration: 1000,
      weakMagnitude: 1,
      strongMagnitude: 1,
    })
  }
}

映射

为了使 Gamepad API 更易于使用,我们提供了映射来将控制器映射到控制器的按钮布局。

Xbox360 控制器

vue
<script setup>
import { mapGamepadToXbox360Controller } from '@vueuse/core'

const controller = mapGamepadToXbox360Controller(gamepad)
</script>

<template>
  <span>{{ controller.buttons.a.pressed }}</span>
  <span>{{ controller.buttons.b.pressed }}</span>
  <span>{{ controller.buttons.x.pressed }}</span>
  <span>{{ controller.buttons.y.pressed }}</span>
</template>

目前只有 Xbox 360 控制器的映射。如果你有要添加映射的控制器,请随时为更多控制器映射打开 PR!

类型声明

显示类型声明
typescript
export interface UseGamepadOptions
  extends ConfigurableWindow,
    ConfigurableNavigator {}
/**
 * 将标准游戏手柄映射到 Xbox 360 控制器。
 */
export declare function mapGamepadToXbox360Controller(
  gamepad: Ref<Gamepad | undefined>,
): ComputedRef<{
  buttons: {
    a: GamepadButton
    b: GamepadButton
    x: GamepadButton
    y: GamepadButton
  }
  bumper: {
    left: GamepadButton
    right: GamepadButton
  }
  triggers: {
    left: GamepadButton
    right: GamepadButton
  }
  stick: {
    left: {
      horizontal: number
      vertical: number
      button: GamepadButton
    }
    right: {
      horizontal: number
      vertical: number
      button: GamepadButton
    }
  }
  dpad: {
    up: GamepadButton
    down: GamepadButton
    left: GamepadButton
    right: GamepadButton
  }
  back: GamepadButton
  start: GamepadButton
} | null>
export declare function useGamepad(options?: UseGamepadOptions): {
  isSupported: ComputedRef<boolean>
  onConnected: EventHookOn<number>
  onDisconnected: EventHookOn<number>
  gamepads: Ref<
    {
      readonly axes: ReadonlyArray<number>
      readonly buttons: readonly {
        readonly pressed: boolean
        readonly touched: boolean
        readonly value: number
      }[]
      readonly connected: boolean
      readonly id: string
      readonly index: number
      readonly mapping: GamepadMappingType
      readonly timestamp: DOMHighResTimeStamp
      readonly vibrationActuator: {
        playEffect: (
          type: GamepadHapticEffectType,
          params?: GamepadEffectParameters,
        ) => Promise<GamepadHapticsResult>
        reset: () => Promise<GamepadHapticsResult>
      }
    }[],
    | Gamepad[]
    | {
        readonly axes: ReadonlyArray<number>
        readonly buttons: readonly {
          readonly pressed: boolean
          readonly touched: boolean
          readonly value: number
        }[]
        readonly connected: boolean
        readonly id: string
        readonly index: number
        readonly mapping: GamepadMappingType
        readonly timestamp: DOMHighResTimeStamp
        readonly vibrationActuator: {
          playEffect: (
            type: GamepadHapticEffectType,
            params?: GamepadEffectParameters,
          ) => Promise<GamepadHapticsResult>
          reset: () => Promise<GamepadHapticsResult>
        }
      }[]
  >
  pause: Fn
  resume: Fn
  isActive: Readonly<Ref<boolean, boolean>>
}
export type UseGamepadReturn = ReturnType<typeof useGamepad>

源码

源码演示文档

贡献者

Anthony Fu
一纸忘忧
wheat
Anthony Fu
Jelf
Aaron-zon
yue
Curt Grimes
Stefan
Antonin Rousset
丶远方
三咲智子

更新日志

v10.10.0 on 5/27/2024
2ccbd - fix: avoid spread to fix gamepad state (#3913)
v10.8.0 on 2/20/2024
9b8ed - fix: improve data updating logic (#3775)
8c735 - fix: explicitly ensure gamepad index is available (#3653)