useGamepad
提供了Gamepad API的响应式绑定。
Demo
使用方法
由于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
供的pause
和resume
函数来控制此轮询。
ts
import { useGamepad } from '@vueuse/core'
const { pause, resume, gamepads } = useGamepad()
pause()
// 游戏手柄对象不会更新
resume()
// 游戏手柄对象将在用户输入时更新
游戏手柄连接和断开事件
当游戏手柄连接或断开连接时,onConnected
和onDisconnected
事件将触发。
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>
Source
贡献者
Anthony Fu
丶远方
wheat
Anthony Fu
Jelf
Aaron-zon
yue
Curt Grimes
Stefan
Antonin Rousset
三咲智子