Commit aba1225d authored by 陈冲's avatar 陈冲

feat: 添加game1,game6大屏音乐及H5音效

parent 0638a2a7
import game1MusicUrl from '@/assets/images/game1.mp3'
import game6Music1Url from '@/assets/images/game6_1.mp3'
import game6Music2Url from '@/assets/images/game6_2.mp3'
import game6Music3Url from '@/assets/images/game6_3.mp3'
import go321 from '@/assets/images/321go.mp3'
let backgroundMusic: HTMLAudioElement | null = null
function getBackgroundMusic() {
if (!backgroundMusic) {
backgroundMusic = new Audio(game1MusicUrl)
backgroundMusic.loop = true
backgroundMusic.preload = 'auto'
backgroundMusic.volume = 0.6
backgroundMusic.load()
const effectTemplates = new Map<string, HTMLAudioElement>()
const playingEffects = new Set<HTMLAudioElement>()
let pendingPlay = false
let pendingRetry: (() => void) | null = null
function getEffectTemplate(music: string) {
let template = effectTemplates.get(music)
if (!template) {
template = new Audio(music)
template.loop = false
template.preload = 'auto'
template.volume = 0.6
template.load()
effectTemplates.set(music, template)
}
return backgroundMusic
return template
}
export async function playGame1Music() {
const audio = getBackgroundMusic()
function releaseEffect(audio: HTMLAudioElement) {
audio.pause()
audio.removeAttribute('src')
audio.load()
playingEffects.delete(audio)
}
function clearPendingRetry() {
if (pendingRetry) {
window.removeEventListener('pointerdown', pendingRetry)
window.removeEventListener('keydown', pendingRetry)
pendingRetry = null
}
pendingPlay = false
}
function setPendingRetry(retry: () => void) {
clearPendingRetry()
pendingPlay = true
pendingRetry = retry
window.addEventListener('pointerdown', retry, { once: true })
window.addEventListener('keydown', retry, { once: true })
}
async function playEffect(music: string, retry: () => void) {
const audio = getEffectTemplate(music).cloneNode(true) as HTMLAudioElement
audio.loop = false
audio.volume = 0.6
playingEffects.add(audio)
const release = () => releaseEffect(audio)
audio.addEventListener('ended', release, { once: true })
audio.addEventListener('error', release, { once: true })
try {
await audio.play()
window.removeEventListener('pointerdown', playGame1Music)
window.removeEventListener('keydown', playGame1Music)
if (pendingRetry === retry) {
clearPendingRetry()
}
} catch {
window.addEventListener('pointerdown', playGame1Music, { once: true })
window.addEventListener('keydown', playGame1Music, { once: true })
releaseEffect(audio)
if (!pendingPlay) {
setPendingRetry(retry)
}
}
}
function stopEffects() {
clearPendingRetry()
for (const audio of playingEffects) {
releaseEffect(audio)
}
playingEffects.clear()
}
export async function playGame1Music() {
await playEffect(game1MusicUrl, playGame1Music)
}
export function stopGame1Music() {
window.removeEventListener('pointerdown', playGame1Music)
window.removeEventListener('keydown', playGame1Music)
backgroundMusic?.pause()
stopEffects()
}
export async function playCountdownMusic() {
await playEffect(go321, playCountdownMusic)
}
export function stopCountdownMusic() {
window.removeEventListener('pointerdown', playCountdownMusic)
window.removeEventListener('keydown', playCountdownMusic)
stopEffects()
}
/*
打地鼠击中爆炸6-1
打小白兔眩晕6-2
没打中6-3
*/
export async function playGame6Music(index: number) {
let arr: [string, string, string, string] = ['', game6Music1Url, game6Music2Url, game6Music3Url];
const music = arr[index]
if (!music) {
return
}
const retry = () => { playGame6Music(index) }
await playEffect(music, retry)
}
export function stopGame6Music() {
stopEffects()
}
<script setup lang="ts">
import { computed, onBeforeUnmount, onMounted, ref } from 'vue'
import { playCountdownMusic, stopCountdownMusic } from '@/commons/music'
const props = withDefaults(defineProps<{
background?: string
......@@ -74,6 +75,7 @@ onMounted(() => {
})
onBeforeUnmount(() => {
stopCountdown()
window.removeEventListener('resize', updateScale)
window.visualViewport?.removeEventListener('resize', updateScale)
})
......@@ -106,6 +108,7 @@ const clearCountdown = () => {
}
const stopCountdown = () => {
clearCountdown()
stopCountdownMusic()
countdownVisible.value = false
gameCountdownVisible.value = false
countdownResolve?.()
......@@ -113,6 +116,7 @@ const stopCountdown = () => {
}
const startCountdown = (startSeconds = 3) => {
stopCountdown()
playCountdownMusic()
return new Promise<void>((resolve) => {
countdownResolve = resolve
......
......@@ -303,4 +303,4 @@ const showGameRuleHandler = () => {
transform: scale(0.8);
}
}
</style>
\ No newline at end of file
</style>
......@@ -6,7 +6,7 @@ import { useGameSocket, joinSharedRoom, sendGameMessage, userJoinStatus } from '
import LoadingView from './views/LoadingView.vue'
import PlayingView from './views/PlayingView.vue'
import { $getWechat } from '@/commons/utils.ts'
import { playGame1Music } from '@/commons/music'
import { playGame6Music, stopGame6Music } from '@/commons/music';
type GameView = 'loading' | 'playing'
type RankPlayer = {
......@@ -181,7 +181,13 @@ const touchHandler = (scoreDelta: number) => {
const nextTick = score.value + scoreDelta
score.value = nextTick
submitScore(false, nextTick)
playGame1Music();
if (scoreDelta == 5) {
playGame6Music(1);
} else if (scoreDelta == -3) {
playGame6Music(2);
} else {
playGame6Music(3);
}
}
if (wechat) {
......@@ -240,6 +246,7 @@ onMounted(() => {
onBeforeUnmount(() => {
_offSocketMessage.value?.()
stopGame6Music()
if (guFrameTimer) {
window.clearTimeout(guFrameTimer)
}
......
......@@ -21,16 +21,7 @@ onMounted(() => {
<div class="img-logo"></div>
<div class="img-loadingbg1">游戏等待开始倒计时60秒</div>
<div class="img-loadingbg2">游戏即将开始 敬请期待</div>
<div class="txt-bottom">您已成功加入游戏<br />等待主持人开始</div>
<!-- <div class="img-title"></div> -->
<!-- <div class="img-avatar" :style="`background: url(${avatar});border-radius:66px;width:132px;height:132px;`"></div> -->
<!-- <div class="txt-nickname">{{ nickname }}</div>
<div class="txt-loading">
<label v-if="userJoinStatus">您已成功加入游戏等待主持人开始</label>
<label v-else>正在加入游戏...</label>
</div> -->
<!-- <div class="bg-bottom"></div> -->
<!-- <div class="loading-gu"></div> -->
<div class="txt-bottom" v-if="userJoinStatus">您已成功加入游戏<br />等待主持人开始</div>
</div>
</template>
......
......@@ -288,10 +288,10 @@ onBeforeUnmount(() => {
width: 750px;
height: 600px;
row-gap: 70px;
top: 560px;
top: 560px;
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: repeat(3, 1fr);
grid-template-rows: repeat(3, 1fr);
place-items: center;
>div {
......
<script setup lang="ts">
<!-- <script setup lang="ts">
import { $getWechat } from '@/commons/utils';
import { onMounted, ref } from 'vue';
......@@ -46,4 +46,4 @@ onMounted(() => {
transform: translateX(-50%);
}
</style>
</style> -->
import game1MusicUrl from '@/assets/images/game1.mp3'
import game6MusicUrl from '@/assets/images/game6.mp3'
import go321 from '@/assets/images/321go.mp3'
let backgroundMusic: HTMLAudioElement | null = null
let countdownTemplate: HTMLAudioElement | null = null
let pendingCountdownRetry: (() => void) | null = null
const countdownAudios = new Set<HTMLAudioElement>()
function getBackgroundMusic() {
function getBackgroundMusic(music: string) {
if (!backgroundMusic) {
backgroundMusic = new Audio(game1MusicUrl)
backgroundMusic = new Audio(music)
backgroundMusic.loop = true
backgroundMusic.preload = 'auto'
backgroundMusic.volume = 0.6
......@@ -15,7 +20,7 @@ function getBackgroundMusic() {
}
export async function playGame1Music() {
const audio = getBackgroundMusic()
const audio = getBackgroundMusic(game1MusicUrl)
try {
await audio.play()
......@@ -32,3 +37,80 @@ export function stopGame1Music() {
window.removeEventListener('keydown', playGame1Music)
backgroundMusic?.pause()
}
export async function playGame6Music() {
const audio = getBackgroundMusic(game6MusicUrl)
try {
await audio.play()
window.removeEventListener('pointerdown', playGame6Music)
window.removeEventListener('keydown', playGame6Music)
} catch {
window.addEventListener('pointerdown', playGame6Music, { once: true })
window.addEventListener('keydown', playGame6Music, { once: true })
}
}
export function stopGame6Music() {
window.removeEventListener('pointerdown', playGame6Music)
window.removeEventListener('keydown', playGame6Music)
backgroundMusic?.pause()
}
function getCountdownTemplate() {
if (!countdownTemplate) {
countdownTemplate = new Audio(go321)
countdownTemplate.loop = false
countdownTemplate.preload = 'auto'
countdownTemplate.volume = 0.8
countdownTemplate.load()
}
return countdownTemplate
}
function releaseCountdownAudio(audio: HTMLAudioElement) {
audio.pause()
audio.removeAttribute('src')
audio.load()
countdownAudios.delete(audio)
}
function clearCountdownRetry() {
if (!pendingCountdownRetry) return
window.removeEventListener('pointerdown', pendingCountdownRetry)
window.removeEventListener('keydown', pendingCountdownRetry)
pendingCountdownRetry = null
}
export async function playCountdownMusic() {
const audio = getCountdownTemplate().cloneNode(true) as HTMLAudioElement
audio.loop = false
audio.volume = 0.8
countdownAudios.add(audio)
const release = () => releaseCountdownAudio(audio)
audio.addEventListener('ended', release, { once: true })
audio.addEventListener('error', release, { once: true })
try {
await audio.play()
clearCountdownRetry()
} catch {
releaseCountdownAudio(audio)
if (pendingCountdownRetry) return
pendingCountdownRetry = () => {
pendingCountdownRetry = null
void playCountdownMusic()
}
window.addEventListener('pointerdown', pendingCountdownRetry, { once: true })
window.addEventListener('keydown', pendingCountdownRetry, { once: true })
}
}
export function stopCountdownMusic() {
clearCountdownRetry()
countdownAudios.forEach(releaseCountdownAudio)
}
<script setup lang="ts">
import { computed, onBeforeUnmount, onMounted, ref } from 'vue'
import { playCountdownMusic, stopCountdownMusic } from '@/commons/music'
const props = withDefaults(defineProps<{
width?: number
......@@ -45,6 +46,7 @@ const clearCountdown = () => {
const stopCountdown = () => {
clearCountdown()
stopCountdownMusic()
countdownVisible.value = false
gameCountdownVisible.value = false
countdownResolve?.()
......@@ -53,6 +55,7 @@ const stopCountdown = () => {
const startCountdown = (startSeconds = 3, gameSeconds = 60) => {
stopCountdown()
void playCountdownMusic()
return new Promise<void>((resolve) => {
countdownResolve = resolve
......
......@@ -2,7 +2,6 @@
import { $save } from '@/commons/utils.ts';
import { onMounted, ref } from 'vue'
import { useRouter } from 'vue-router'
// import { playGame1Music } from '@/commons/music'
const emit = defineEmits<{
loginSuccess: []
......@@ -32,7 +31,6 @@ async function login() {
}
const loginHandler = async () => {
// playGame1Music()
const { state, msg, data } = await login()
if (state === 0) {
......@@ -46,7 +44,6 @@ const loginHandler = async () => {
}
onMounted(() => {
// playGame1Music()
})
</script>
......
......@@ -3,7 +3,7 @@ import { cssAssetUrl } from '@/commons/assets.ts';
import { $read } from '@/commons/utils';
import router from '@/router';
import { ref } from 'vue';
import Login from './Login.vue';
import Login from '../components/Login.vue';
const imageUrls = {
bg1: cssAssetUrl('main-bg1.png'),
......
......@@ -6,7 +6,7 @@ import Rank1 from './views/Rank1View.vue'
import Rank2 from './views/Rank2View.vue'
import { useAdminGameSocket } from '@/composables/useAdminGameSocket'
import type Player from '@/commons/player.ts'
import { playGame1Music } from '@/commons/music'
import { playGame1Music, stopGame1Music } from '@/commons/music'
import { $remove_socket_storage } from '@/commons/utils.ts'
const router = useRouter()
......@@ -156,7 +156,6 @@ const startGameWithMusic = () => {
alert('房间中没有玩家')
return;
}
playGame1Music()
startGame()
}
......@@ -167,7 +166,6 @@ const nextRound = () => {
}
const nextRoundWithMusic = () => {
playGame1Music()
nextRound()
}
......@@ -177,6 +175,7 @@ onMounted(() => {
})
onUnmounted(() => {
stopGame1Music()
window.removeEventListener('beforeunload', confirmRefresh)
})
</script>
......
......@@ -6,7 +6,7 @@ import Rank1 from './views/Rank1View.vue'
import Rank2 from './views/Rank2View.vue'
import { useAdminGameSocket } from '@/composables/useAdminGameSocket'
import type Player from '@/commons/player.ts'
import { playGame1Music } from '@/commons/music'
import { playGame6Music, stopGame6Music } from '@/commons/music'
import { $remove_socket_storage } from '@/commons/utils.ts'
const router = useRouter()
......@@ -156,7 +156,6 @@ const startGameWithMusic = () => {
alert('房间中没有玩家')
return;
}
playGame1Music()
startGame()
}
......@@ -167,16 +166,16 @@ const nextRound = () => {
}
const nextRoundWithMusic = () => {
playGame1Music()
nextRound()
}
onMounted(() => {
window.addEventListener('beforeunload', confirmRefresh)
playGame1Music()
playGame6Music()
})
onUnmounted(() => {
stopGame6Music();
window.removeEventListener('beforeunload', confirmRefresh)
})
</script>
......
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