Commit aa23cfba authored by 董政锦's avatar 董政锦

fix: h5 game的摇一摇在oss失效问题;

parent 7b089924
......@@ -8,6 +8,15 @@ const game6Music1Url = assetUrl('game6_1.mp3')
const game6Music2Url = assetUrl('game6_2.mp3')
const go321 = assetUrl('321go.mp3')
console.log('[Music] 音频文件路径:')
console.log(' game1:', game1MusicUrl)
console.log(' game2:', game2MusicUrl)
console.log(' game3_1 (金币):', game3Music1Url)
console.log(' game3_2 (炸弹):', game3Music2Url)
console.log(' game6_1:', game6Music1Url)
console.log(' game6_2:', game6Music2Url)
console.log(' 321go:', go321)
const effectTemplates = new Map<string, HTMLAudioElement>()
const playingEffects = new Set<HTMLAudioElement>()
......
......@@ -276,7 +276,7 @@ onMounted(() => {
console.log('[Game4 H5] 本地模式:2秒后自动开始游戏');
setTimeout(() => {
startGameView();
}, 2000);
}, 3000);
}
});
......
......@@ -146,7 +146,7 @@ onMounted(() => {
.txt-loading {
position: absolute;
top: 743px;
top: 724px;
left: 50%;
width: 288px;
color: #e00000;
......
......@@ -3,6 +3,7 @@ import { onBeforeUnmount, onMounted, ref } from 'vue'
import { assetUrl } from '@/commons/assets'
const shakeSound = assetUrl('game4/yaoyiyao.mp3')
console.log('[摇一摇] 音频文件路径:', shakeSound)
const props = defineProps<{
imageUrls: Record<string, string>
......@@ -37,8 +38,8 @@ let lastPosition = {
// 是否正在摇晃(用于停止检测)
let wasShaking = false
let audioContext: AudioContext | null = null
let shakeAudioBuffer: AudioBuffer | null = null
// 使用 Audio 元素播放音效(避免 CORS 问题)
let shakeAudio: HTMLAudioElement | null = null
// iOS 13+/iPadOS 需要主动请求 DeviceMotion 权限
let motionPermissionGranted = false
......@@ -73,63 +74,56 @@ const requestMotionPermission = async (): Promise<boolean> => {
const initAudio = async () => {
try {
audioContext = new (window.AudioContext || (window as any).webkitAudioContext)()
console.log('[摇一摇] 开始初始化音频...')
// 如果 AudioContext 处于 suspended 状态,注册一次性交互监听器来激活
if (audioContext.state === 'suspended') {
console.log('[摇一摇] AudioContext 处于 suspended 状态,注册交互监听器')
const resumeAudio = async () => {
if (audioContext && audioContext.state === 'suspended') {
await audioContext.resume()
console.log('[摇一摇] AudioContext 已通过用户交互激活')
}
// 移除监听器
window.removeEventListener('touchstart', resumeAudio)
window.removeEventListener('click', resumeAudio)
// 使用 Audio 元素(不受 CORS 限制)
shakeAudio = new Audio(shakeSound)
const audio = shakeAudio // 保存引用,避免 null 检查
audio.preload = 'auto'
audio.volume = 1
// 等待音频加载
await new Promise<void>((resolve, reject) => {
const onCanPlay = () => {
audio.removeEventListener('canplaythrough', onCanPlay)
audio.removeEventListener('error', onError)
resolve()
}
const onError = (e: Event) => {
audio.removeEventListener('canplaythrough', onCanPlay)
audio.removeEventListener('error', onError)
reject(new Error('音频加载失败'))
}
window.addEventListener('touchstart', resumeAudio, { once: true })
window.addEventListener('click', resumeAudio, { once: true })
}
audio.addEventListener('canplaythrough', onCanPlay)
audio.addEventListener('error', onError)
audio.load()
})
const response = await fetch(shakeSound)
const arrayBuffer = await response.arrayBuffer()
shakeAudioBuffer = await audioContext.decodeAudioData(arrayBuffer)
console.log('[摇一摇] 音频初始化成功,AudioContext state:', audioContext.state)
console.log('[摇一摇] 音频初始化成功,使用 Audio 元素')
} catch (error) {
console.error('[摇一摇] 音频初始化失败:', error)
console.error('[摇一摇] 错误堆栈:', (error as Error).stack)
}
}
const playShakeSound = () => {
if (!audioContext || !shakeAudioBuffer) {
if (!shakeAudio) {
console.warn('[摇一摇] 音频未初始化,无法播放')
return
}
// 确保 AudioContext 处于运行状态
if (audioContext.state === 'suspended') {
audioContext.resume().then(() => {
console.log('[摇一摇] AudioContext 已恢复')
playShakeSoundInternal()
}).catch(err => {
console.error('[摇一摇] AudioContext 恢复失败:', err)
try {
// 重置播放位置并播放
shakeAudio.currentTime = 0
shakeAudio.play().catch(err => {
console.error('[摇一摇] 音频播放失败:', err)
})
} else {
playShakeSoundInternal()
} catch (error) {
console.error('[摇一摇] 播放音效出错:', error)
}
}
const playShakeSoundInternal = () => {
if (!audioContext || !shakeAudioBuffer) return
const source = audioContext.createBufferSource()
source.buffer = shakeAudioBuffer
source.connect(audioContext.destination)
source.start(0)
}
const handleDeviceMotion = (ev: DeviceMotionEvent) => {
const nowTime = Date.now()
const motion = ev.accelerationIncludingGravity
......@@ -208,8 +202,9 @@ onMounted(async () => {
onBeforeUnmount(() => {
window.removeEventListener('devicemotion', handleDeviceMotion)
if (audioContext) {
audioContext.close()
if (shakeAudio) {
shakeAudio.pause()
shakeAudio = null
}
if (yaoyiyaoShakeTimer) {
clearTimeout(yaoyiyaoShakeTimer)
......@@ -218,12 +213,7 @@ onBeforeUnmount(() => {
// 点击马触发:iOS 先请求权限(不触发得分)
const onTapHorse = async () => {
// 激活 AudioContext(解决浏览器自动播放策略)
if (audioContext && audioContext.state === 'suspended') {
await audioContext.resume()
console.log('[摇一摇] 通过点击激活 AudioContext')
}
if (!motionPermissionGranted) {
await requestMotionPermission()
showIOSHint.value = false
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment