Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
F
fc-minigame
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
陈冲
fc-minigame
Commits
d2280fec
Commit
d2280fec
authored
Jun 04, 2026
by
董政锦
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: 游戏开始后的添加倒计时;
parent
455ee499
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
30 additions
and
26 deletions
+30
-26
Game4.vue
frontend-large/src/pages/game4/Game4.vue
+2
-1
Rank1View.vue
frontend-large/src/pages/game4/views/Rank1View.vue
+28
-25
No files found.
frontend-large/src/pages/game4/Game4.vue
View file @
d2280fec
...
@@ -64,7 +64,8 @@ offHorseBoost = onSocketMessage((evt, payload) => {
...
@@ -64,7 +64,8 @@ offHorseBoost = onSocketMessage((evt, payload) => {
let
hasBoost
=
false
;
let
hasBoost
=
false
;
data
.
forEach
((
item
:
any
)
=>
{
data
.
forEach
((
item
:
any
)
=>
{
const
id
=
item
.
userid
||
item
.
wechat_id
||
""
;
// WebSocket 数据无 userid/wechat_id,用 avatar 作为稳定标识
const
id
=
item
.
userid
||
item
.
wechat_id
||
item
.
avatar
||
""
;
if
(
!
id
)
return
;
if
(
!
id
)
return
;
// 尝试多种字段名: score / boost / acceleration / speed / progress
// 尝试多种字段名: score / boost / acceleration / speed / progress
const
raw
=
item
.
score
??
item
.
boost
??
item
.
acceleration
??
item
.
speed
??
item
.
progress
;
const
raw
=
item
.
score
??
item
.
boost
??
item
.
acceleration
??
item
.
speed
??
item
.
progress
;
...
...
frontend-large/src/pages/game4/views/Rank1View.vue
View file @
d2280fec
...
@@ -46,8 +46,8 @@ const BASE_SPEED_PERCENT_PER_SEC = 100 / BASE_DURATION_SEC; // ≈ 1.111%/s 基
...
@@ -46,8 +46,8 @@ const BASE_SPEED_PERCENT_PER_SEC = 100 / BASE_DURATION_SEC; // ≈ 1.111%/s 基
// ========== 瞬时加速脉冲机制 ==========
// ========== 瞬时加速脉冲机制 ==========
// H5 每次摇一摇发送累计积分,PC 端检测 score 增长 → 触发短暂加速脉冲 → 迅速衰减
// H5 每次摇一摇发送累计积分,PC 端检测 score 增长 → 触发短暂加速脉冲 → 迅速衰减
const
BOOST_PULSE
=
0.8
;
// 每次操作的加速幅度(+80% 额外速度
)
const
BOOST_PULSE
=
1.5
;
// 每次操作的加速幅度(+150% 额外速度,即 2.5x 基准
)
const
BOOST_DECAY
=
0.9
7
;
// 每帧衰减系数(60fps 下约 1s 衰减到 16%,约 2
s 衰减归零)
const
BOOST_DECAY
=
0.9
85
;
// 每帧衰减系数(60fps 下约 1.5s 衰减到 40%,约 3
s 衰减归零)
/** 瞬时加速值: { [userid]: currentBoost },每帧衰减 */
/** 瞬时加速值: { [userid]: currentBoost },每帧衰减 */
const
transientBoosts
=
ref
<
Record
<
string
,
number
>>
({});
const
transientBoosts
=
ref
<
Record
<
string
,
number
>>
({});
...
@@ -61,8 +61,9 @@ const detectScoreChanges = (players: Player[]) => {
...
@@ -61,8 +61,9 @@ const detectScoreChanges = (players: Player[]) => {
let
hasNewBoost
=
false
;
let
hasNewBoost
=
false
;
const
updated
=
{
...
transientBoosts
.
value
};
const
updated
=
{
...
transientBoosts
.
value
};
players
.
forEach
((
p
)
=>
{
players
.
forEach
((
p
,
index
)
=>
{
const
id
=
p
.
userid
||
p
.
wechat_id
||
""
;
// WebSocket 数据无 userid/wechat_id,用 avatar 作为稳定标识
const
id
=
p
.
userid
||
p
.
wechat_id
||
p
.
avatar
||
`player-
${
index
}
`
;
if
(
!
id
||
id
.
startsWith
(
"empty-"
))
return
;
if
(
!
id
||
id
.
startsWith
(
"empty-"
))
return
;
const
newScore
=
Number
(
p
.
score
??
0
);
const
newScore
=
Number
(
p
.
score
??
0
);
const
prev
=
prevScores
[
id
]
??
0
;
const
prev
=
prevScores
[
id
]
??
0
;
...
@@ -71,6 +72,9 @@ const detectScoreChanges = (players: Player[]) => {
...
@@ -71,6 +72,9 @@ const detectScoreChanges = (players: Player[]) => {
// 积分增长 = 玩家又摇了一次 → 触发瞬时加速脉冲
// 积分增长 = 玩家又摇了一次 → 触发瞬时加速脉冲
updated
[
id
]
=
BOOST_PULSE
;
updated
[
id
]
=
BOOST_PULSE
;
hasNewBoost
=
true
;
hasNewBoost
=
true
;
console
.
log
(
`[Rank1View] 🚀
${
p
.
nickname
}
score
${
prev
}
→
${
newScore
}
, 触发瞬时加速 pulse=
${
BOOST_PULSE
}
`
,
);
}
}
prevScores
[
id
]
=
newScore
;
prevScores
[
id
]
=
newScore
;
...
@@ -78,10 +82,6 @@ const detectScoreChanges = (players: Player[]) => {
...
@@ -78,10 +82,6 @@ const detectScoreChanges = (players: Player[]) => {
if
(
hasNewBoost
)
{
if
(
hasNewBoost
)
{
transientBoosts
.
value
=
updated
;
transientBoosts
.
value
=
updated
;
console
.
log
(
"[Rank1View] 瞬时加速触发:"
,
JSON
.
parse
(
JSON
.
stringify
(
transientBoosts
.
value
)),
);
}
}
};
};
...
@@ -123,7 +123,8 @@ const updateHorses = (players: Player[]) => {
...
@@ -123,7 +123,8 @@ const updateHorses = (players: Player[]) => {
const
existingMap
=
new
Map
(
horses
.
value
.
map
((
h
)
=>
[
h
.
id
,
h
]));
const
existingMap
=
new
Map
(
horses
.
value
.
map
((
h
)
=>
[
h
.
id
,
h
]));
horses
.
value
=
validPlayers
.
map
((
player
,
index
)
=>
{
horses
.
value
=
validPlayers
.
map
((
player
,
index
)
=>
{
const
id
=
player
.
userid
||
player
.
wechat_id
||
`horse-
${
index
}
`
;
// WebSocket 数据无 userid/wechat_id,用 avatar 作为稳定标识
const
id
=
player
.
userid
||
player
.
wechat_id
||
player
.
avatar
||
`horse-
${
index
}
`
;
const
existing
=
existingMap
.
get
(
id
);
const
existing
=
existingMap
.
get
(
id
);
return
{
return
{
id
,
id
,
...
@@ -331,10 +332,13 @@ const startIntro = async () => {
...
@@ -331,10 +332,13 @@ const startIntro = async () => {
transientBoosts
.
value
=
{};
transientBoosts
.
value
=
{};
Object
.
keys
(
prevScores
).
forEach
((
k
)
=>
delete
prevScores
[
k
]);
Object
.
keys
(
prevScores
).
forEach
((
k
)
=>
delete
prevScores
[
k
]);
// Phase 1: 3 秒开场倒计时(背景动画暂停、马匹不显示)
// 启动完整倒计时:3s 开场 + 60s 游戏(DesignStage 内部管理两个阶段的 UI)
await
designStage
.
value
?.
startCountdown
(
3
,
0
);
const
countdownPromise
=
designStage
.
value
?.
startCountdown
(
3
,
60
);
// 等待 3-2-1 开场倒计时结束(~3.5s 后安全触发)
await
new
Promise
((
r
)
=>
setTimeout
(
r
,
3500
));
// Phase 2: 倒计时结束 → 游戏正式开始
// Phase 2: 倒计时结束 → 游戏正式开始
,背景动画+马匹启动
gameStarted
.
value
=
true
;
gameStarted
.
value
=
true
;
isGameRunning
.
value
=
true
;
isGameRunning
.
value
=
true
;
startGameLoop
();
startGameLoop
();
...
@@ -342,20 +346,19 @@ const startIntro = async () => {
...
@@ -342,20 +346,19 @@ const startIntro = async () => {
startMockBoost
();
startMockBoost
();
}
}
// Phase 3: 等待游戏结束(最多 60 秒 或 所有马跑完)
// 监测提前结束(所有马跑完 → 提前停止倒计时)
const
maxMs
=
60000
;
const
earlyCheck
=
setInterval
(()
=>
{
const
gameStart
=
Date
.
now
();
const
allDone
=
await
new
Promise
<
void
>
((
resolve
)
=>
{
horses
.
value
.
length
>
0
&&
const
check
=
setInterval
(()
=>
{
horses
.
value
.
every
((
h
)
=>
h
.
xPercent
>=
100
);
const
allDone
=
horses
.
value
.
length
>
0
&&
horses
.
value
.
every
((
h
)
=>
h
.
xPercent
>=
100
);
if
(
allDone
&&
isGameRunning
.
value
)
{
const
timeUp
=
Date
.
now
()
-
gameStart
>=
maxMs
;
designStage
.
value
?.
stopCountdown
();
if
(
allDone
||
timeUp
||
!
isGameRunning
.
value
)
{
}
clearInterval
(
check
);
},
200
);
resolve
();
}
},
200
);
});
// 等待 60s 游戏倒计时结束
await
countdownPromise
;
clearInterval
(
earlyCheck
);
stopGame
();
stopGame
();
};
};
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment