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

fix: 修复大屏马的生成数据和动画;

parent 2a8c14a9
...@@ -55,36 +55,48 @@ const renderPlayers = (data: any) => { ...@@ -55,36 +55,48 @@ const renderPlayers = (data: any) => {
} }
const updateRankPlayers = (data: any) => { const updateRankPlayers = (data: any) => {
if (!Array.isArray(data)) return // 兼容多种数据格式:纯数组 / {list:[]} / {players:[]} / {data:[]}
let arr: any[] | null = null;
if (Array.isArray(data)) {
arr = data;
} else if (Array.isArray(data?.list)) {
arr = data.list;
} else if (Array.isArray(data?.players)) {
arr = data.players;
} else if (Array.isArray(data?.data)) {
arr = data.data;
}
rankPlayers.value = Array.from( if (!arr || arr.length === 0) {
{ length: RANK_LIMIT }, console.warn('[game3] updateRankPlayers: 无法解析排行数据', data);
(_, index) => data[index] ?? emptyRankPlayer(index), return;
) }
}
const playerToRankPlayer = (player: any, index: number): Player => ({ // 打印第一条原始数据的所有字段名,用于排查字段不匹配问题
telephone: player?.telephone ?? '', console.log('[game3] updateRankPlayers: 收到排行数据', arr.length, '条, 第1条字段:', Object.keys(arr[0] || {}), ', 第1条值:', JSON.parse(JSON.stringify(arr[0])));
userid: player?.userid ?? '',
wechat_id: player?.wechat_id || `empty-${index}`, // 将 WS 数据标准化为 Player 格式(同时保留 userid / wechat_id)
nickname: player?.nickname || '虚位以待', // ⚠️ 当 WS 返回的数据没有 userid/openid/wechat_id 等ID字段时,用 avatar 作为唯一标识
avatar: player?.avatar || '', const normalized = arr.map((item: any, i: number) => {
score: player?.score ?? '-', const hasId = item.userid || item.openid || item.user_id || item.wechat_id;
}) const avatar = item.avatar || item.headimgurl || '';
const nickname = item.nickname || item.name || '虚位以待';
const isRealPlayer = nickname && nickname !== '-' && nickname !== '虚位以待';
const wechat_id = hasId || (isRealPlayer && avatar ? `avt:${avatar}` : `empty-${i}`);
return {
...item,
userid: hasId || (isRealPlayer && avatar ? `avt:${avatar}` : ''),
wechat_id,
nickname,
avatar,
score: item.score ?? 0,
};
});
const seedRankPlayersFromLoading = () => {
rankPlayers.value = Array.from( rankPlayers.value = Array.from(
{ length: RANK_LIMIT }, { length: RANK_LIMIT },
(_, index) => { (_, index) => normalized[index] ?? emptyRankPlayer(index),
const player = loadingPlayers.value[index] );
if (!player?.userid && !player?.wechat_id) {
return emptyRankPlayer(index)
}
return playerToRankPlayer(player, index)
},
)
} }
const resetRoundState = () => { const resetRoundState = () => {
...@@ -107,7 +119,7 @@ const gotoRank1WithIntro = async () => { ...@@ -107,7 +119,7 @@ const gotoRank1WithIntro = async () => {
if (isPlayingStartAnimation) return if (isPlayingStartAnimation) return
isPlayingStartAnimation = true isPlayingStartAnimation = true
seedRankPlayersFromLoading() // ⚠️ 不要用 seedRankPlayersFromLoading,由 WS room_rank_result 驱动马匹数据
screen.value = 'rank1' screen.value = 'rank1'
await nextTick() await nextTick()
await rank1Ref.value?.startIntro() await rank1Ref.value?.startIntro()
...@@ -129,8 +141,16 @@ function handleRoomState(data: any) { ...@@ -129,8 +141,16 @@ function handleRoomState(data: any) {
gotoLoading() gotoLoading()
break break
case 2: case 2:
seedRankPlayersFromLoading() // 重连/中途进房时游戏已在运行,直接进入赛马画面
if (isPlayingStartAnimation) break;
isPlayingStartAnimation = true;
screen.value = 'rank1' screen.value = 'rank1'
console.log('[game3] handleRoomState: status=2, 直接启动赛马动画');
nextTick(() => {
rank1Ref.value?.startIntro().finally(() => {
isPlayingStartAnimation = false;
});
});
break break
case 3: case 3:
screen.value = 'rank2' screen.value = 'rank2'
...@@ -143,24 +163,58 @@ const { startGame, createRoom, backRoom, closeRoom } = useAdminGameSocket({ ...@@ -143,24 +163,58 @@ const { startGame, createRoom, backRoom, closeRoom } = useAdminGameSocket({
onAny: (evt, payload) => { onAny: (evt, payload) => {
// 兜底处理所有非标准事件,解析玩家实时分数(对齐 game4) // 兜底处理所有非标准事件,解析玩家实时分数(对齐 game4)
const data = payload?.data ?? payload; const data = payload?.data ?? payload;
if (!Array.isArray(data)) return;
// 尝试从 data 中提取数组
const boosts: Record<string, number> = {}; let arr: any[] | null = null;
let hasBoost = false; if (Array.isArray(data)) {
arr = data;
data.forEach((item: any) => { } else if (Array.isArray(data?.list)) {
const id = item.userid || item.wechat_id || item.avatar || ""; arr = data.list;
if (!id) return; } else if (Array.isArray(data?.data)) {
const raw = item.score ?? item.boost ?? item.acceleration ?? item.speed ?? item.progress; arr = data.data;
if (raw === undefined || raw === null) return; }
const val = Number(raw);
if (isNaN(val)) return; if (arr && arr.length > 0) {
boosts[id] = Math.max(0, val); const boosts: Record<string, number> = {};
hasBoost = true; const normalized = arr.map((item: any, i: number) => {
}); const hasId = item.userid || item.openid || item.user_id || item.wechat_id;
const avatar = item.avatar || item.headimgurl || '';
if (hasBoost) { const nickname = item.nickname || item.name || '虚位以待';
horseBoosts.value = { ...boosts }; const isRealPlayer = nickname && nickname !== '-' && nickname !== '虚位以待';
const wechat_id = hasId || (isRealPlayer && avatar ? `avt:${avatar}` : `empty-${i}`);
return {
...item,
userid: hasId || (isRealPlayer && avatar ? `avt:${avatar}` : ''),
wechat_id,
};
});
const hasAnyPlayer = normalized.some((item: any) => {
const id = item.userid || item.wechat_id || '';
return !!id && !id.startsWith('empty-');
});
if (hasAnyPlayer) {
// 同时更新 rankPlayers(确保马匹列表有真实玩家)
rankPlayers.value = Array.from(
{ length: RANK_LIMIT },
(_, index) => normalized[index] ?? emptyRankPlayer(index),
);
}
normalized.forEach((item: any) => {
const id = item.userid || item.wechat_id || '';
if (!id || id.startsWith('empty-')) return;
const raw = item.score ?? item.boost ?? item.acceleration ?? item.speed ?? item.progress;
if (raw === undefined || raw === null) return;
const val = Number(raw);
if (isNaN(val)) return;
boosts[id] = Math.max(0, val);
});
if (Object.keys(boosts).length > 0) {
horseBoosts.value = { ...horseBoosts.value, ...boosts };
}
} }
}, },
onRoomState: handleRoomState, onRoomState: handleRoomState,
...@@ -232,5 +286,7 @@ watch(screen, (value) => { ...@@ -232,5 +286,7 @@ watch(screen, (value) => {
<template> <template>
<Loading v-if="screen === 'loading'" :players="loadingPlayers" :player-count="playerCount" <Loading v-if="screen === 'loading'" :players="loadingPlayers" :player-count="playerCount"
@start="startGameWithMusic" @back="backHandler" /> @start="startGameWithMusic" @back="backHandler" />
<Rank1 v-else ref="rank1Ref" :rank-list="rankPlayers" :horse-boosts="horseBoosts" @start="startGameWithMusic" @next="nextRoundWithMusic" @back="backHandler" /> <Rank1 v-if="screen === 'rank1'" ref="rank1Ref" :rank-list="rankPlayers" :horse-boosts="horseBoosts"
@start="startGameWithMusic" @next="nextRoundWithMusic" @back="backHandler" />
<Rank2 v-if="screen === 'rank2'" :rank-list="rankPlayers" @next="nextRoundWithMusic" @back="backHandler" />
</template> </template>
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