跳到主要內容

useGamepad

分類
導出大小
1.34 kB
最後變更
3 週前

Gamepad API 提供響應式綁定。

演示

此裝置不支援 Gamepad。您的裝置似乎不支援 Gamepad 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 更新

目前 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`)
})

震動

Gamepad Haptics 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 {}
/**
 * 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>

原始碼

原始碼演示文件

貢獻者

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

更新日誌

v12.4.0 on 1/10/2025
dd316 - feat: 使用被動事件處理程序在任何可能的地方 (#4477)
v12.0.0-beta.1 on 11/21/2024
0a9ed - feat!: 移除 Vue 2 支援,最佳化 bundles 並清理 (#4349)
v10.10.0 on 5/27/2024
2ccbd - fix: 避免擴展以修復手把狀態 (#3913)
v10.8.0 on 2/20/2024
9b8ed - fix: 改善資料更新邏輯 (#3775)
8c735 - fix: 明確確保手把索引可用 (#3653)

以 MIT 許可證發布。