提交 f2fef882 authored 作者: lidongxu's avatar lidongxu

大屏碎裂效果完美版本

上级 16dd650a
......@@ -9,7 +9,7 @@ import { drawBubbleGrid } from './renderer/bubbleGrid.js'
import { drawBubble3D, BUBBLE_RADIUS } from './renderer/bubble.js'
import { drawShooter } from './renderer/shooter.js'
import { drawGameInfo, drawTeamResultOverlay } from './renderer/gameinfo.js'
import { updateAndDrawExplosions, appendExplosionsFromState, Explosion, setExplosionQuality } from './renderer/explosion.js'
import { detectAndCreateBursts, updateAndDrawBursts, clearPrevGrid } from './renderer/explosion.js'
import { drawIdleScreen } from './renderer/idleScreen.js'
import { SCREEN_WIDTH, SCREEN_HEIGHT } from './constants.js'
......@@ -19,8 +19,8 @@ const ctx = canvas.getContext('2d')
const SCREEN_NAME = import.meta.env.VITE_SCREEN_NAME || 'big-screen-1'
/** 每个玩家独立的爆炸列表:Map<playerId, Explosion[]> */
const playerExplosions = new Map()
/** 每个玩家独立的碎裂效果列表:Map<playerId, BubbleBurst[]> */
const playerBursts = new Map()
let frameCount = 0
......@@ -42,9 +42,9 @@ function applyScaler(playerCount = 1) {
function renderPlayer(state, offsetX, roomId) {
const pid = state.playerId ?? 1
// 初始化该玩家的爆炸列表
if (!playerExplosions.has(pid)) playerExplosions.set(pid, [])
const explosions = playerExplosions.get(pid)
// 初始化该玩家的碎裂效果列表
if (!playerBursts.has(pid)) playerBursts.set(pid, [])
const bursts = playerBursts.get(pid)
ctx.save()
ctx.translate(offsetX, 0)
......@@ -63,12 +63,11 @@ function renderPlayer(state, offsetX, roomId) {
}
}
// 爆炸特效:消费后立即清空,避免下一帧重复添加
if (state.explosions && state.explosions.length) {
appendExplosionsFromState(explosions, state.explosions)
state.explosions = []
// 碎裂特效:通过对比前后帧grid自动检测消失的球
if (state.grid) {
detectAndCreateBursts(bursts, pid, state.grid, state.pushAnimOffsetY ?? 0)
}
updateAndDrawExplosions(ctx, explosions)
updateAndDrawBursts(ctx, bursts)
// 射击器
if (state.shooter) {
......@@ -196,15 +195,15 @@ function loop() {
const teamBStates = states.filter(s => getPlayerTeam(s.playerId ?? 1) === 'B')
const totalSlots = Math.max(teamAStates.length + teamBStates.length, 1)
// 人数变化时重新计算缩放和爆炸质量
// 人数变化时重新计算缩放
if (totalSlots !== _lastPlayerCount) {
_lastPlayerCount = totalSlots
applyScaler(totalSlots)
setExplosionQuality(totalSlots) // 根据人数调整爆炸效果质量
// 清理消失玩家的爆炸列表
for (const pid of playerExplosions.keys()) {
// 清理消失玩家的碎裂列表和grid快照
for (const pid of playerBursts.keys()) {
if (!states.find(s => (s.playerId ?? 1) === pid)) {
playerExplosions.delete(pid)
playerBursts.delete(pid)
clearPrevGrid(pid)
}
}
}
......@@ -250,11 +249,9 @@ function loop() {
// ── 检测是否所有玩家都结束,显示队伍比分 ─────────────────────────────
const allGameOver = states.every(s => s.isGameOver)
console.log('[BigScreen] 游戏状态检查', { allGameOver, statesCount: states.length, totalSlots, canvasWidth: canvas.width, SCREEN_WIDTH })
if (allGameOver && states.length > 1) {
// 全屏显示队伍比分(传入实际的大屏宽度)
const totalWidth = SCREEN_WIDTH * totalSlots
console.log('[BigScreen] 显示队伍比分', { totalSlots, totalWidth, canvasWidth: canvas.width, states: states.length })
ctx.save()
ctx.setTransform(1, 0, 0, 1, 0, 0)
drawTeamResultOverlay(ctx, states, getPlayerTeam, totalWidth)
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论