Files
cmr-mini/miniprogram/game/feedback/hapticsDirector.ts

95 lines
2.3 KiB
TypeScript

import { type GameEffect } from '../core/gameResult'
import { DEFAULT_GAME_HAPTICS_CONFIG, type FeedbackCueKey, type GameHapticsConfig } from './feedbackConfig'
export class HapticsDirector {
enabled: boolean
config: GameHapticsConfig
constructor(config: GameHapticsConfig = DEFAULT_GAME_HAPTICS_CONFIG) {
this.enabled = true
this.config = config
}
configure(config: GameHapticsConfig): void {
this.config = config
}
setEnabled(enabled: boolean): void {
this.enabled = enabled
}
destroy(): void {}
trigger(key: FeedbackCueKey): void {
if (!this.enabled || !this.config.enabled) {
return
}
const cue = this.config.cues[key]
if (!cue || !cue.enabled) {
return
}
try {
if (cue.pattern === 'long') {
wx.vibrateLong()
} else {
wx.vibrateShort({ type: 'medium' })
}
} catch {}
}
handleEffects(effects: GameEffect[]): void {
for (const effect of effects) {
if (effect.type === 'session_started') {
this.trigger('session_started')
continue
}
if (effect.type === 'session_finished') {
this.trigger('session_finished')
continue
}
if (effect.type === 'session_cancelled') {
this.trigger('session_finished')
continue
}
if (effect.type === 'punch_feedback' && effect.tone === 'warning') {
this.trigger('punch_feedback:warning')
continue
}
if (effect.type === 'guidance_state_changed') {
if (effect.guidanceState === 'searching') {
this.trigger('guidance:searching')
continue
}
if (effect.guidanceState === 'distant') {
this.trigger('guidance:distant')
continue
}
if (effect.guidanceState === 'approaching') {
this.trigger('guidance:approaching')
continue
}
this.trigger('guidance:ready')
continue
}
if (effect.type === 'control_completed') {
if (effect.controlKind === 'start') {
this.trigger('control_completed:start')
continue
}
if (effect.controlKind === 'finish') {
this.trigger('control_completed:finish')
continue
}
this.trigger('control_completed:control')
}
}
}
}