提交 2d65fd99 authored 作者: lidongxu's avatar lidongxu

修复分数显示问题

上级 dbee07b8
...@@ -428,15 +428,19 @@ function drawTeamScoreBig(ctx, x, y, team, score, isWinner) { ...@@ -428,15 +428,19 @@ function drawTeamScoreBig(ctx, x, y, team, score, isWinner) {
ctx.fillStyle = color ctx.fillStyle = color
ctx.fillText(`${team}队`, x, y - 28) ctx.fillText(`${team}队`, x, y - 28)
// 分数(胜利方更大更亮) // 分数(胜利方更大更亮,失败方暗淡
ctx.font = isWinner ? 'bold 56px Arial' : 'bold 42px Arial' ctx.font = isWinner ? 'bold 56px Arial' : 'bold 42px Arial'
ctx.shadowColor = glowColor ctx.shadowColor = glowColor
ctx.shadowBlur = isWinner ? 30 : 0 ctx.shadowBlur = isWinner ? 30 : 0
const sg = ctx.createLinearGradient(x - 50, 0, x + 50, 0) if (isWinner) {
sg.addColorStop(0, '#FDE68A') const sg = ctx.createLinearGradient(x - 50, 0, x + 50, 0)
sg.addColorStop(0.5, '#FCD34D') sg.addColorStop(0, '#FDE68A')
sg.addColorStop(1, '#F59E0B') sg.addColorStop(0.5, '#FCD34D')
ctx.fillStyle = sg sg.addColorStop(1, '#F59E0B')
ctx.fillStyle = sg
} else {
ctx.fillStyle = 'rgba(180,160,130,0.5)'
}
ctx.fillText(String(score), x, y + 15) ctx.fillText(String(score), x, y + 15)
ctx.shadowBlur = 0 ctx.shadowBlur = 0
......
...@@ -152,15 +152,18 @@ function _dispatch(event, data) { ...@@ -152,15 +152,18 @@ function _dispatch(event, data) {
*/ */
case 'room:gameOver': { case 'room:gameOver': {
console.log('[Socket] room:gameOver', data) console.log('[Socket] room:gameOver', data)
// 处理所有玩家的分数(新格式) // 处理所有玩家的分数和队伍信息
if (data?.scores) { if (data?.scores) {
Object.entries(data.scores).forEach(([pid, score]) => { Object.entries(data.scores).forEach(([pid, score]) => {
// 使用对应玩家的昵称,如果没有则使用广播中的昵称 const numPid = Number(pid)
const playerNickname = data.nicknames?.[pid] || data.nickname const playerNickname = data.nicknames?.[pid] || data.nickname
setPlayerGameOver(Number(pid), score, playerNickname) // 更新队伍信息(确保结果页分组正确)
if (data.teams?.[pid]) {
setPlayerTeam(numPid, data.teams[pid])
}
setPlayerGameOver(numPid, score, playerNickname)
}) })
} else if (data?.playerId !== undefined) { } else if (data?.playerId !== undefined) {
// 兼容旧格式:单个玩家分数
setPlayerGameOver(data.playerId, data.score, data.nickname) setPlayerGameOver(data.playerId, data.score, data.nickname)
} }
break break
......
...@@ -156,6 +156,28 @@ function registerRoomHandlers(ws, { broadcastToRoom, joinRoom, leaveAllRooms, ro ...@@ -156,6 +156,28 @@ function registerRoomHandlers(ws, { broadcastToRoom, joinRoom, leaveAllRooms, ro
return; return;
} }
// 服务端强制校验队伍人数,防止并发导致某队超员
const perTeamSeats = Math.floor(waiting.totalSeats / 2);
let finalTeam = team || 'A';
const teamACount = waiting.players.filter(p => p.team === 'A').length;
const teamBCount = waiting.players.filter(p => p.team === 'B').length;
if (finalTeam === 'A' && teamACount >= perTeamSeats) {
// A队已满,自动分配到B队
if (teamBCount >= perTeamSeats) {
ws.sendEvent('error', { message: '两队均已满员' });
return;
}
finalTeam = 'B';
} else if (finalTeam === 'B' && teamBCount >= perTeamSeats) {
// B队已满,自动分配到A队
if (teamACount >= perTeamSeats) {
ws.sendEvent('error', { message: '两队均已满员' });
return;
}
finalTeam = 'A';
}
// 分配递增 playerId // 分配递增 playerId
const nextId = (roomPlayerCounter.get(rid) || 0) + 1; const nextId = (roomPlayerCounter.get(rid) || 0) + 1;
roomPlayerCounter.set(rid, nextId); roomPlayerCounter.set(rid, nextId);
...@@ -164,7 +186,7 @@ function registerRoomHandlers(ws, { broadcastToRoom, joinRoom, leaveAllRooms, ro ...@@ -164,7 +186,7 @@ function registerRoomHandlers(ws, { broadcastToRoom, joinRoom, leaveAllRooms, ro
const playerInfo = { const playerInfo = {
playerId: nextId, playerId: nextId,
nickname: nickname || `玩家${nextId}`, nickname: nickname || `玩家${nextId}`,
team: team || 'A' team: finalTeam
}; };
// 加入等待表 // 加入等待表
...@@ -182,8 +204,8 @@ function registerRoomHandlers(ws, { broadcastToRoom, joinRoom, leaveAllRooms, ro ...@@ -182,8 +204,8 @@ function registerRoomHandlers(ws, { broadcastToRoom, joinRoom, leaveAllRooms, ro
console.log(`[Room] 玩家加入房间 ${rid},playerId=${nextId},team=${playerInfo.team},当前 ${joinedCount}/${totalSeats}`); console.log(`[Room] 玩家加入房间 ${rid},playerId=${nextId},team=${playerInfo.team},当前 ${joinedCount}/${totalSeats}`);
// 通知自己加入成功 // 通知自己加入成功(含最终分配的队伍,可能因满员被调整)
ws.sendEvent('room:joined', { roomId: rid, joinedCount, totalSeats, playerId: nextId, players, myPlayerId: nextId }); ws.sendEvent('room:joined', { roomId: rid, joinedCount, totalSeats, playerId: nextId, players, myPlayerId: nextId, team: finalTeam });
// 广播给房间内所有人(含房主,broadcastToRoom 排除自身,自己单独 send) // 广播给房间内所有人(含房主,broadcastToRoom 排除自身,自己单独 send)
broadcastToRoom(rid, 'room:playerJoined', { roomId: rid, joinedCount, totalSeats, players }); broadcastToRoom(rid, 'room:playerJoined', { roomId: rid, joinedCount, totalSeats, players });
...@@ -243,12 +265,12 @@ function registerRoomHandlers(ws, { broadcastToRoom, joinRoom, leaveAllRooms, ro ...@@ -243,12 +265,12 @@ function registerRoomHandlers(ws, { broadcastToRoom, joinRoom, leaveAllRooms, ro
data: { status: 'finished' }, data: { status: 'finished' },
}); });
// 收集该玩家的分数 // 收集该玩家的分数和队伍
if (!gameOverScores.has(roomId)) { if (!gameOverScores.has(roomId)) {
gameOverScores.set(roomId, new Map()); gameOverScores.set(roomId, new Map());
} }
const roomScores = gameOverScores.get(roomId); const roomScores = gameOverScores.get(roomId);
roomScores.set(playerId, { score: score ?? 0, nickname }); roomScores.set(playerId, { score: score ?? 0, nickname, team: ws.ctx.team });
// 获取房间内所有连接的 minigame 玩家数量 // 获取房间内所有连接的 minigame 玩家数量
const subs = roomSubscribers.get(roomId); const subs = roomSubscribers.get(roomId);
...@@ -258,14 +280,16 @@ function registerRoomHandlers(ws, { broadcastToRoom, joinRoom, leaveAllRooms, ro ...@@ -258,14 +280,16 @@ function registerRoomHandlers(ws, { broadcastToRoom, joinRoom, leaveAllRooms, ro
console.log(`[Room] 游戏结束分数收集 roomId=${roomId} playerId=${playerId} score=${score ?? 0} (${reportedPlayers}/${totalPlayers})`); console.log(`[Room] 游戏结束分数收集 roomId=${roomId} playerId=${playerId} score=${score ?? 0} (${reportedPlayers}/${totalPlayers})`);
// 广播当前收集到的分数给所有人(让客户端可以实时显示 // 广播当前收集到的分数给所有人(含队伍信息,让客户端/大屏正确分组
const scoresObj = {}; const scoresObj = {};
const nicknamesObj = {}; const nicknamesObj = {};
const teamsObj = {};
for (const [pid, data] of roomScores) { for (const [pid, data] of roomScores) {
scoresObj[pid] = data.score; scoresObj[pid] = data.score;
nicknamesObj[pid] = data.nickname; nicknamesObj[pid] = data.nickname;
teamsObj[pid] = data.team;
} }
broadcastToRoom(roomId, 'room:gameOver', { roomId, scores: scoresObj, nicknames: nicknamesObj, playerId, nickname }); broadcastToRoom(roomId, 'room:gameOver', { roomId, scores: scoresObj, nicknames: nicknamesObj, teams: teamsObj, playerId, nickname });
// 如果所有玩家都已上报分数,清理收集表 // 如果所有玩家都已上报分数,清理收集表
if (reportedPlayers >= totalPlayers) { if (reportedPlayers >= totalPlayers) {
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论