跳到内容

useGamepad

Category
导出大小
1.34 kB
Last Changed
3 weeks ago

Gamepad API 提供响应式绑定。

Demo

Gamepad 在此设备上不受支持。您的设备似乎不支持 Gamepad API。查看 此处 以获取支持设备的列表。

Usage

由于 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 更新

目前,Gamepad API 不支持事件来更新手柄的状态。要更新手柄状态,requestAnimationFrame 用于轮询手柄更改。您可以使用 useGamepad 提供的 pauseresume 函数来控制此轮询

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

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

pause()

// gamepads object will not update

resume()

// gamepads object will update on user input

Gamepad 连接和断开事件

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

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

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

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

Vibration

Gamepad 触觉 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,
    })
  }
}

Mappings

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

Xbox360 Controller

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 以获取更多控制器映射!

Type Declarations

Show Type Declarations
typescript
export interface UseGamepadOptions
  extends ConfigurableWindow,
    ConfigurableNavigator {}
/**
 * Maps a standard standard gamepad to an Xbox 360 Controller.
 */
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<ShallowRef<boolean>>
}
export type UseGamepadReturn = ReturnType<typeof useGamepad>

Source

SourceDemoDocs

Contributors

Anthony Fu
wheat
Anthony Fu
Jelf
Fernando Fernández
Robin
Aaron-zon
yue
Curt Grimes
Stefan
Antonin Rousset
丶远方
三咲智子

Changelog

v12.4.0 on 1/10/2025
dd316 - feat: use passive event handlers everywhere is possible (#4477)
v12.0.0-beta.1 on 11/21/2024
0a9ed - feat!: drop Vue 2 support, optimize bundles and clean up (#4349)
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)

在 MIT 许可证下发布。