Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
P
paopao
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
cocktail-party
paopao
Commits
7dd0cad2
提交
7dd0cad2
authored
3月 23, 2026
作者:
lidongxu
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
大方向是对了
上级
7b6d9a2c
显示空白字符变更
内嵌
并排
正在显示
7 个修改的文件
包含
61 行增加
和
34 行删除
+61
-34
main.js
big-screen/src/main.js
+8
-2
bubble.js
big-screen/src/renderer/bubble.js
+27
-5
bubbleGrid.js
big-screen/src/renderer/bubbleGrid.js
+2
-2
explosion.js
big-screen/src/renderer/explosion.js
+6
-6
idleScreen.js
big-screen/src/renderer/idleScreen.js
+5
-5
shooter.js
big-screen/src/renderer/shooter.js
+12
-13
minigame-1
minigame-1
+1
-1
没有找到文件。
big-screen/src/main.js
浏览文件 @
7dd0cad2
...
...
@@ -6,7 +6,7 @@ import { getAllPlayerStates, clearGameState, getCurrentRoom, getPlayerTeam, getC
import
{
initSocket
,
getConnectionStatus
}
from
'./socket.js'
import
{
drawBackground
}
from
'./renderer/background.js'
import
{
drawBubbleGrid
}
from
'./renderer/bubbleGrid.js'
import
{
drawBubble3D
,
BUBBLE_RADIUS
}
from
'./renderer/bubble.js'
import
{
drawBubble3D
,
getBubbleRadius
,
configureBubbleLayout
}
from
'./renderer/bubble.js'
import
{
drawShooter
}
from
'./renderer/shooter.js'
import
{
drawGameInfo
,
drawTeamResultOverlay
}
from
'./renderer/gameinfo.js'
import
{
detectAndCreateBursts
,
updateAndDrawBursts
,
clearPrevGrid
}
from
'./renderer/explosion.js'
...
...
@@ -42,6 +42,12 @@ function applyScaler(playerCount = 1) {
function
renderPlayer
(
state
,
offsetX
,
roomId
)
{
const
pid
=
state
.
playerId
??
1
// 从 grid 数据推算偶数行列数,动态调整泡泡大小
// 偶数行(row 0)的列数决定了整个网格的列配置
if
(
state
.
grid
&&
state
.
grid
.
length
&&
state
.
grid
[
0
])
{
configureBubbleLayout
(
state
.
grid
[
0
].
length
)
}
// 初始化该玩家的碎裂效果列表
if
(
!
playerBursts
.
has
(
pid
))
playerBursts
.
set
(
pid
,
[])
const
bursts
=
playerBursts
.
get
(
pid
)
...
...
@@ -58,7 +64,7 @@ function renderPlayer(state, offsetX, roomId) {
if
(
state
.
fireBubbles
&&
state
.
fireBubbles
.
length
)
{
for
(
const
fb
of
state
.
fireBubbles
)
{
if
(
fb
.
active
!==
false
)
{
drawBubble3D
(
ctx
,
fb
.
x
,
fb
.
y
,
BUBBLE_RADIUS
,
fb
.
color
||
1
)
drawBubble3D
(
ctx
,
fb
.
x
,
fb
.
y
,
getBubbleRadius
()
,
fb
.
color
||
1
)
}
}
}
...
...
big-screen/src/renderer/bubble.js
浏览文件 @
7dd0cad2
...
...
@@ -4,9 +4,31 @@
*/
import
{
SCREEN_WIDTH
,
SAFE_AREA_TOP
}
from
'../constants.js'
// 11 个泡泡平铺满屏幕宽度:SCREEN_WIDTH = 11 × 2R = 22R
export
const
BUBBLE_RADIUS
=
SCREEN_WIDTH
/
22
const
ROW_HEIGHT
=
BUBBLE_RADIUS
*
Math
.
sqrt
(
3
)
// ─── 动态列数适配 ────────────────────────────────────────────
// 默认 11 列(手机端),iPad 端可能 14~15 列
// 大屏端从收到的 grid 数据推算列数,动态调整泡泡大小
export
let
BUBBLE_RADIUS
=
SCREEN_WIDTH
/
22
let
ROW_HEIGHT
=
BUBBLE_RADIUS
*
Math
.
sqrt
(
3
)
let
GRID_OFFSET_X
=
0
let
_evenCols
=
11
/**
* 根据偶数行列数重新计算泡泡大小和网格偏移
* 在每帧渲染前调用,从 grid 数据推算列数
* @param {number} evenCols 偶数行列数
*/
export
function
configureBubbleLayout
(
evenCols
)
{
if
(
evenCols
===
_evenCols
)
return
_evenCols
=
evenCols
BUBBLE_RADIUS
=
SCREEN_WIDTH
/
(
evenCols
*
2
)
ROW_HEIGHT
=
BUBBLE_RADIUS
*
Math
.
sqrt
(
3
)
GRID_OFFSET_X
=
(
SCREEN_WIDTH
-
evenCols
*
2
*
BUBBLE_RADIUS
)
/
2
}
/** 获取当前泡泡半径(供需要实时值的模块使用) */
export
function
getBubbleRadius
()
{
return
BUBBLE_RADIUS
}
/** 获取当前网格偏移 */
export
function
getGridOffsetX
()
{
return
GRID_OFFSET_X
}
/**
* 9 种泡泡颜色(颜色索引 1-9),用于爆炸粒子效果取色。
...
...
@@ -102,7 +124,7 @@ export function getActiveColorCount(score) {
*/
export
function
gridToScreen
(
row
,
col
)
{
const
R
=
BUBBLE_RADIUS
const
x
=
row
%
2
===
0
?
col
*
2
*
R
+
R
:
col
*
2
*
R
+
2
*
R
const
y
=
row
*
ROW_HEIGHT
+
R
+
SAFE_AREA_TOP
const
x
=
GRID_OFFSET_X
+
(
row
%
2
===
0
?
col
*
2
*
R
+
R
:
col
*
2
*
R
+
2
*
R
)
const
y
=
ROW_HEIGHT
*
row
+
R
+
SAFE_AREA_TOP
return
{
x
,
y
}
}
big-screen/src/renderer/bubbleGrid.js
浏览文件 @
7dd0cad2
...
...
@@ -2,7 +2,7 @@
* 泡泡网格渲染(移植自 minigame-1)
* 根据 state 中的 grid 二维数组和 pushAnimOffsetY 绘制网格泡泡
*/
import
{
BUBBLE_RADIUS
,
gridToScreen
,
drawBubble3D
}
from
'./bubble.js'
import
{
getBubbleRadius
,
gridToScreen
,
drawBubble3D
}
from
'./bubble.js'
/**
* 绘制泡泡网格
...
...
@@ -20,7 +20,7 @@ export function drawBubbleGrid(ctx, grid, pushAnimOffsetY = 0) {
const
color
=
rowArr
[
col
]
if
(
!
color
)
continue
const
{
x
,
y
}
=
gridToScreen
(
row
,
col
)
drawBubble3D
(
ctx
,
x
,
y
+
offsetY
,
BUBBLE_RADIUS
,
color
)
drawBubble3D
(
ctx
,
x
,
y
+
offsetY
,
getBubbleRadius
()
,
color
)
}
}
}
big-screen/src/renderer/explosion.js
浏览文件 @
7dd0cad2
...
...
@@ -6,7 +6,7 @@
*
* 动画过程:闪光 → 碎片四散 → 渐隐消失,只播放一次。
*/
import
{
BUBBLE_RADIUS
,
BUBBLE_COLORS
,
gridToScreen
}
from
'./bubble.js'
import
{
getBubbleRadius
,
BUBBLE_COLORS
,
gridToScreen
}
from
'./bubble.js'
// ─── 碎片粒子 ─────────────────────────────────────────────────────────────────
...
...
@@ -68,8 +68,8 @@ class Ring {
this
.
x
=
x
this
.
y
=
y
this
.
color
=
color
this
.
r
=
BUBBLE_RADIUS
*
0.3
this
.
maxR
=
BUBBLE_RADIUS
*
2.2
this
.
r
=
getBubbleRadius
()
*
0.3
this
.
maxR
=
getBubbleRadius
()
*
2.2
this
.
life
=
0
this
.
maxLife
=
40
}
...
...
@@ -81,7 +81,7 @@ class Ring {
update
()
{
this
.
life
++
const
t
=
this
.
life
/
this
.
maxLife
this
.
r
=
BUBBLE_RADIUS
*
0.3
+
(
this
.
maxR
-
BUBBLE_RADIUS
*
0.3
)
*
t
this
.
r
=
getBubbleRadius
()
*
0.3
+
(
this
.
maxR
-
getBubbleRadius
()
*
0.3
)
*
t
this
.
alpha
=
0.6
*
(
1
-
t
)
}
...
...
@@ -107,7 +107,7 @@ class BubbleBurst {
this
.
_y
=
y
const
colorHex
=
BUBBLE_COLORS
[
colorIdx
]
||
'#ffffff'
const
R
=
BUBBLE_RADIUS
const
R
=
getBubbleRadius
()
this
.
flashAlpha
=
1.0
this
.
ring
=
new
Ring
(
x
,
y
,
colorHex
)
...
...
@@ -156,7 +156,7 @@ class BubbleBurst {
ctx
.
globalAlpha
=
this
.
flashAlpha
*
0.7
ctx
.
fillStyle
=
'#ffffff'
ctx
.
beginPath
()
ctx
.
arc
(
this
.
_x
,
this
.
_y
,
BUBBLE_RADIUS
*
1.3
,
0
,
Math
.
PI
*
2
)
ctx
.
arc
(
this
.
_x
,
this
.
_y
,
getBubbleRadius
()
*
1.3
,
0
,
Math
.
PI
*
2
)
ctx
.
fill
()
ctx
.
restore
()
}
...
...
big-screen/src/renderer/idleScreen.js
浏览文件 @
7dd0cad2
...
...
@@ -3,7 +3,7 @@
* 三种状态:未连接、已连接无房间、已连接有房间等待游戏
*/
import
{
SCREEN_WIDTH
,
SCREEN_HEIGHT
}
from
'../constants.js'
import
{
drawBubble3D
,
BUBBLE_RADIUS
}
from
'./bubble.js'
import
{
drawBubble3D
,
getBubbleRadius
}
from
'./bubble.js'
let
_frame
=
0
...
...
@@ -26,7 +26,7 @@ function rr(ctx, x, y, w, h, r) {
// ─── 装饰泡泡(顶部三行漂浮泡泡)────────────────────────────────────────────────
const
_decorBubbles
=
(()
=>
{
const
R
=
BUBBLE_RADIUS
const
R
=
getBubbleRadius
()
const
list
=
[]
let
sx
=
0.456
const
rand
=
()
=>
{
sx
=
(
sx
*
9301
+
49297
)
%
233280
;
return
sx
/
233280
}
...
...
@@ -47,7 +47,7 @@ function drawDecorBubbles(ctx) {
ctx
.
globalAlpha
=
0.55
for
(
const
b
of
_decorBubbles
)
{
const
dy
=
Math
.
sin
(
_frame
*
0.018
+
b
.
phase
)
*
3
drawBubble3D
(
ctx
,
b
.
x
,
b
.
y
+
dy
,
BUBBLE_RADIUS
,
b
.
color
)
drawBubble3D
(
ctx
,
b
.
x
,
b
.
y
+
dy
,
getBubbleRadius
()
,
b
.
color
)
}
ctx
.
restore
()
}
...
...
@@ -344,11 +344,11 @@ export function drawIdleScreen(ctx, width, height, roomId, connStatus, screenNam
drawDecorBubbles
(
ctx
)
// 顶部遮罩(让泡泡看起来更像背景)
const
topMask
=
ctx
.
createLinearGradient
(
0
,
0
,
0
,
BUBBLE_RADIUS
*
4
)
const
topMask
=
ctx
.
createLinearGradient
(
0
,
0
,
0
,
getBubbleRadius
()
*
4
)
topMask
.
addColorStop
(
0
,
'rgba(30,12,60,0)'
)
topMask
.
addColorStop
(
1
,
'rgba(30,12,60,0.55)'
)
ctx
.
fillStyle
=
topMask
ctx
.
fillRect
(
0
,
0
,
width
,
BUBBLE_RADIUS
*
4
)
ctx
.
fillRect
(
0
,
0
,
width
,
getBubbleRadius
()
*
4
)
// 浮动粒子
drawParticles
(
ctx
,
width
,
height
)
...
...
big-screen/src/renderer/shooter.js
浏览文件 @
7dd0cad2
...
...
@@ -3,15 +3,8 @@
* 鸡身体朝向跟随瞄准方向倾斜 + 呼吸浮动 + 弹跳动画
*/
import
{
SCREEN_WIDTH
,
SCREEN_HEIGHT
,
SAFE_AREA_BOTTOM
}
from
'../constants.js'
import
{
BUBBLE_RADIUS
,
drawBubble3D
}
from
'./bubble.js'
// 鸡的尺寸
const
CHICKEN_WIDTH
=
BUBBLE_RADIUS
*
5
const
CHICKEN_HEIGHT
=
BUBBLE_RADIUS
*
6
const
CHICKEN_BOTTOM_MARGIN
=
BUBBLE_RADIUS
*
0.8
const
BUBBLE_TOP_OFFSET
=
BUBBLE_RADIUS
*
0.4
const
NEXT_X_OFFSET
=
BUBBLE_RADIUS
*
3.2
const
NEXT_Y_OFFSET
=
BUBBLE_RADIUS
*
0.5
import
{
getBubbleRadius
,
drawBubble3D
}
from
'./bubble.js'
const
NEXT_SCALE
=
0.65
// 鸡朝向参数
...
...
@@ -20,7 +13,6 @@ const MAX_ANGLE = 165 * Math.PI / 180
const
MAX_LEAN_ANGLE
=
25
*
Math
.
PI
/
180
const
LEAN_LERP
=
0.15
const
BOB_SPEED
=
0.03
const
BOB_AMOUNT
=
BUBBLE_RADIUS
*
0.15
// 加载鸡图片
const
_chickenImg
=
new
Image
()
...
...
@@ -31,7 +23,7 @@ let _currentLean = 0
let
_bobPhase
=
0
function
calcAimPoints
(
originX
,
originY
,
angle
)
{
const
R
=
BUBBLE_RADIUS
const
R
=
getBubbleRadius
()
const
points
=
[{
x
:
originX
,
y
:
originY
}]
let
cx
=
originX
,
cy
=
originY
let
vx
=
Math
.
cos
(
angle
),
vy
=
-
Math
.
sin
(
angle
)
...
...
@@ -76,10 +68,17 @@ function drawAimLine(ctx, aimPoints) {
export
function
drawShooter
(
ctx
,
shooterState
)
{
if
(
!
shooterState
)
return
const
R
=
getBubbleRadius
()
const
CHICKEN_WIDTH
=
R
*
5
const
CHICKEN_HEIGHT
=
R
*
6
const
CHICKEN_BOTTOM_MARGIN
=
R
*
0.8
const
BUBBLE_TOP_OFFSET
=
R
*
0.4
const
NEXT_X_OFFSET
=
R
*
3.2
const
NEXT_Y_OFFSET
=
R
*
0.5
const
x
=
SCREEN_WIDTH
/
2
const
chickenBottom
=
SCREEN_HEIGHT
-
SAFE_AREA_BOTTOM
-
CHICKEN_BOTTOM_MARGIN
const
bubbleBaseY
=
chickenBottom
-
CHICKEN_HEIGHT
-
BUBBLE_TOP_OFFSET
const
R
=
BUBBLE_RADIUS
const
aimAngle
=
shooterState
.
aimAngle
??
Math
.
PI
/
2
const
isAiming
=
shooterState
.
isAiming
??
false
...
...
@@ -100,7 +99,7 @@ export function drawShooter(ctx, shooterState) {
// 呼吸浮动
_bobPhase
+=
BOB_SPEED
if
(
_bobPhase
>
Math
.
PI
*
2
)
_bobPhase
-=
Math
.
PI
*
2
const
bobOffset
=
Math
.
sin
(
_bobPhase
)
*
BOB_AMOUNT
const
bobOffset
=
Math
.
sin
(
_bobPhase
)
*
R
*
0.15
// 瞄准线
const
aimPoints
=
shooterState
.
aimPoints
??
(
isAiming
?
calcAimPoints
(
x
,
bubbleBaseY
,
aimAngle
)
:
[])
...
...
minigame-1
@
6fe51eaf
Subproject commit
8ab3c7c4b7f885eea0ef9c4d9f51f3fa08188665
Subproject commit
6fe51eaf29c8e38ac9804b5991a841aa88ea235f
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论