Commit 8e748bdc authored by 董政锦's avatar 董政锦

fix: 修复game5背景音乐逻辑;加本地测试数据;

parent 902e3273
......@@ -6,8 +6,8 @@ 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 { playApplauseMusic, playGame5Music, stopAllMusic, stopGame5Music } from '@/commons/music'
import { $confirm, $remove_socket_storage, $notify, $toast } from '@/commons/utils.ts'
import { playApplauseMusic, playGame5Music, stopAllMusic, stopApplauseMusic, stopGame5Music } from '@/commons/music'
import { $confirm, $is_local_mode, $remove_socket_storage, $notify, $toast } from '@/commons/utils.ts'
const router = useRouter()
......@@ -33,7 +33,25 @@ const emptyRankPlayer = (index: number): Player => ({
})
const screen = ref<GameScreen>('loading')
const loadingPlayers = ref<any[]>(Array.from({ length: PLAYER_LIMIT }, emptyLoadingPlayer))
// 本地模式下使用模拟玩家数据
const mockPlayers = [
{ userid: 'local-1', nickname: '疾风骑士', avatar: 'https://api.dicebear.com/9.x/fun-emoji/svg?seed=Felix', score: 45 },
{ userid: 'local-2', nickname: '闪电侠', avatar: 'https://api.dicebear.com/9.x/fun-emoji/svg?seed=Aneka', score: 38 },
{ userid: 'local-3', nickname: '追风者', avatar: 'https://api.dicebear.com/9.x/fun-emoji/svg?seed=Salem', score: 30 },
{ userid: 'local-4', nickname: '千里马', avatar: 'https://api.dicebear.com/9.x/fun-emoji/svg?seed=Midnight', score: 22 },
{ userid: 'local-5', nickname: '飞毛腿', avatar: 'https://api.dicebear.com/9.x/fun-emoji/svg?seed=Lucky', score: 15 },
{ userid: 'local-6', nickname: '烈焰驹', avatar: 'https://api.dicebear.com/9.x/fun-emoji/svg?seed=Bandit', score: 52 },
{ userid: 'local-7', nickname: '暴风战士', avatar: 'https://api.dicebear.com/9.x/fun-emoji/svg?seed=Misty', score: 41 },
{ userid: 'local-8', nickname: '神行者', avatar: 'https://api.dicebear.com/9.x/fun-emoji/svg?seed=Pepper', score: 35 },
{ userid: 'local-9', nickname: '银鞍客', avatar: 'https://api.dicebear.com/9.x/fun-emoji/svg?seed=Oreo', score: 28 },
{ userid: 'local-10', nickname: '踏雪无痕', avatar: 'https://api.dicebear.com/9.x/fun-emoji/svg?seed=Tiger', score: 18 },
];
const loadingPlayers = ref<any[]>(
$is_local_mode()
? mockPlayers
: Array.from({ length: PLAYER_LIMIT }, emptyLoadingPlayer)
)
const playerCount = ref(0)
const rankPlayers = ref<Player[]>(Array.from({ length: RANK_LIMIT }, (_, index) => emptyRankPlayer(index)))
const rank1Ref = ref<InstanceType<typeof Rank1> | null>(null)
......@@ -108,6 +126,8 @@ const gotoRank1WithIntro = async () => {
isPlayingStartAnimation = true
seedRankPlayersFromLoading()
// 进入游戏画面前确保背景音乐播放中
playGame5Music()
screen.value = 'rank1'
await nextTick()
await rank1Ref.value?.startIntro()
......@@ -162,23 +182,41 @@ const { startGame, createRoom, closeRoom, backRoom } = useAdminGameSocket({
})
const startGameWithMusic = () => {
// 确保背景音乐播放
playGame5Music()
// 本地调试模式:跳过 WebSocket,直接进入游戏画面
if ($is_local_mode()) {
console.log('[Game5] 本地模式,直接进入游戏画面')
gotoRank1WithIntro()
return
}
if (playerCount.value == 0) {
// alert('房间中没有玩家')
$toast('房间中没有玩家');
return;
}
playGame5Music()
startGame()
}
const nextRound = () => {
// 立刻停止喝彩音乐并移除指针事件监听,防止点击按钮时重新触发 playApplauseMusic
stopApplauseMusic()
if ($is_local_mode()) {
// 本地模式:回到 loading 页,用户点击"开始挑战"后再进入游戏
gotoLoading(true)
return
}
gotoLoading(true)
// 等待组件卸载完成后再确保 BGM 播放
nextTick().then(() => playGame5Music())
//重开房间
backRoom(5)
}
const nextRoundWithMusic = () => {
playGame5Music()
nextRound()
}
......@@ -193,6 +231,15 @@ onUnmounted(() => {
})
const backHandler = async() => {
// 立刻停止喝彩音乐并移除指针事件监听,防止点击按钮时重新触发 playApplauseMusic
stopApplauseMusic()
if ($is_local_mode()) {
stopAllMusic()
router.replace('/main')
return
}
const ok = await $confirm({
title: '提示',
message: '是否关闭当前房间回到首页',
......
......@@ -38,7 +38,7 @@ const imageUrls = {
const HORSE_TYPES = [1, 2, 3, 4] as const;
const HORSE_FRAME_COUNT = 21; // 每匹马 21 帧(00-20)
const HORSE_WIDTH = 200;
const HORSE_START_X = -330; // 左侧屏外起点
const HORSE_START_X = -100; // 左侧屏外起点,进一步右移让马更快进入屏幕
const HORSE_END_X = 1920 - HORSE_WIDTH; // 右边缘贴齐屏幕右侧(1720px)
......@@ -67,9 +67,9 @@ let horseIdCounter = 0;
const isGameRunning = ref(false);
const emptyPlayer = (index: number): Player => ({
wechat_id: `empty-${index}`,
nickname: "-",
nickname: "虚位以待",
avatar: "",
score: 0,
score: "-",
});
const list = ref<Player[]>(
......@@ -210,8 +210,8 @@ const generateRandomHorses = () => {
for (let i = 0; i < count; i++) {
const type = HORSE_TYPES[i % HORSE_TYPES.length]!;
const lane = lanes[i % 2]!;
const delayMs = i * 2500 + Math.random() * 1000; // 每匹马间隔2.5秒起步,加随机1秒
const durationMs = (40 + Math.random() * 40) * 1000; // 40-80秒,速度浮动更大
const delayMs = i * 50 + Math.random() * 50; // 大幅减少起步延迟,第一匹马几乎立刻出现
const durationMs = (60 + Math.random() * 40) * 1000; // 60-100秒,降低速度,让马跑得更慢
newHorses.push({
id: `horse-${++horseIdCounter}`,
horseType: type,
......@@ -227,6 +227,33 @@ const generateRandomHorses = () => {
horses.value = newHorses;
};
// ========== 本地模拟数据(参考 game3)==========
const mockAvatars = [
'https://api.dicebear.com/9.x/fun-emoji/svg?seed=Felix',
'https://api.dicebear.com/9.x/fun-emoji/svg?seed=Aneka',
'https://api.dicebear.com/9.x/fun-emoji/svg?seed=Salem',
'https://api.dicebear.com/9.x/fun-emoji/svg?seed=Midnight',
'https://api.dicebear.com/9.x/fun-emoji/svg?seed=Lucky',
'https://api.dicebear.com/9.x/fun-emoji/svg?seed=Bandit',
'https://api.dicebear.com/9.x/fun-emoji/svg?seed=Misty',
'https://api.dicebear.com/9.x/fun-emoji/svg?seed=Pepper',
'https://api.dicebear.com/9.x/fun-emoji/svg?seed=Oreo',
'https://api.dicebear.com/9.x/fun-emoji/svg?seed=Tiger',
];
const mockPlayers: Player[] = [
{ userid: 'local-1', nickname: '疾风骑士', avatar: mockAvatars[0], score: 45 },
{ userid: 'local-2', nickname: '闪电侠', avatar: mockAvatars[1], score: 38 },
{ userid: 'local-3', nickname: '追风者', avatar: mockAvatars[2], score: 30 },
{ userid: 'local-4', nickname: '千里马', avatar: mockAvatars[3], score: 22 },
{ userid: 'local-5', nickname: '飞毛腿', avatar: mockAvatars[4], score: 15 },
{ userid: 'local-6', nickname: '烈焰驹', avatar: mockAvatars[5], score: 52 },
{ userid: 'local-7', nickname: '暴风战士', avatar: mockAvatars[6], score: 41 },
{ userid: 'local-8', nickname: '神行者', avatar: mockAvatars[7], score: 35 },
{ userid: 'local-9', nickname: '银鞍客', avatar: mockAvatars[8], score: 28 },
{ userid: 'local-10', nickname: '踏雪无痕', avatar: mockAvatars[9], score: 18 },
];
// ========== 预加载所有马匹帧图片(防止切帧时闪烁/白屏)==========
const preloadHorseFrames = () => {
for (const frames of Object.values(horseFrames)) {
......@@ -240,6 +267,8 @@ const preloadHorseFrames = () => {
onMounted(() => {
preloadHorseFrames();
if ($is_run_local()) {
// 使用模拟玩家数据更新排名列表
updateRankList(mockPlayers);
gameStarted.value = true;
isGameRunning.value = true;
generateRandomHorses();
......@@ -525,11 +554,11 @@ const rankIcon = (index: number) => {
}
.horse-wrapper.horse-lane-top {
bottom: 350px;
bottom: 300px; /* 往下挪 50px */
}
.horse-wrapper.horse-lane-bottom {
bottom: 60px;
bottom: 110px; /* 往上挪 50px */
}
......
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