useGamepad
為 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
提供的 pause
和 resume
功能來控制此輪詢
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 連接與斷開連接事件
當手把連接或斷開連接時,將會觸發 onConnected
和 onDisconnected
事件。
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>