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

feat: 游戏开始后的添加倒计时;

parent 455ee499
......@@ -64,7 +64,8 @@ offHorseBoost = onSocketMessage((evt, payload) => {
let hasBoost = false;
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;
// 尝试多种字段名: score / boost / acceleration / speed / progress
const raw = item.score ?? item.boost ?? item.acceleration ?? item.speed ?? item.progress;
......
......@@ -46,8 +46,8 @@ const BASE_SPEED_PERCENT_PER_SEC = 100 / BASE_DURATION_SEC; // ≈ 1.111%/s 基
// ========== 瞬时加速脉冲机制 ==========
// H5 每次摇一摇发送累计积分,PC 端检测 score 增长 → 触发短暂加速脉冲 → 迅速衰减
const BOOST_PULSE = 0.8; // 每次操作的加速幅度(+80% 额外速度
const BOOST_DECAY = 0.97; // 每帧衰减系数(60fps 下约 1s 衰减到 16%,约 2s 衰减归零)
const BOOST_PULSE = 1.5; // 每次操作的加速幅度(+150% 额外速度,即 2.5x 基准
const BOOST_DECAY = 0.985; // 每帧衰减系数(60fps 下约 1.5s 衰减到 40%,约 3s 衰减归零)
/** 瞬时加速值: { [userid]: currentBoost },每帧衰减 */
const transientBoosts = ref<Record<string, number>>({});
......@@ -61,8 +61,9 @@ const detectScoreChanges = (players: Player[]) => {
let hasNewBoost = false;
const updated = { ...transientBoosts.value };
players.forEach((p) => {
const id = p.userid || p.wechat_id || "";
players.forEach((p, index) => {
// WebSocket 数据无 userid/wechat_id,用 avatar 作为稳定标识
const id = p.userid || p.wechat_id || p.avatar || `player-${index}`;
if (!id || id.startsWith("empty-")) return;
const newScore = Number(p.score ?? 0);
const prev = prevScores[id] ?? 0;
......@@ -71,6 +72,9 @@ const detectScoreChanges = (players: Player[]) => {
// 积分增长 = 玩家又摇了一次 → 触发瞬时加速脉冲
updated[id] = BOOST_PULSE;
hasNewBoost = true;
console.log(
`[Rank1View] 🚀 ${p.nickname} score ${prev}${newScore}, 触发瞬时加速 pulse=${BOOST_PULSE}`,
);
}
prevScores[id] = newScore;
......@@ -78,10 +82,6 @@ const detectScoreChanges = (players: Player[]) => {
if (hasNewBoost) {
transientBoosts.value = updated;
console.log(
"[Rank1View] 瞬时加速触发:",
JSON.parse(JSON.stringify(transientBoosts.value)),
);
}
};
......@@ -123,7 +123,8 @@ const updateHorses = (players: Player[]) => {
const existingMap = new Map(horses.value.map((h) => [h.id, h]));
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);
return {
id,
......@@ -331,10 +332,13 @@ const startIntro = async () => {
transientBoosts.value = {};
Object.keys(prevScores).forEach((k) => delete prevScores[k]);
// Phase 1: 3 秒开场倒计时(背景动画暂停、马匹不显示)
await designStage.value?.startCountdown(3, 0);
// 启动完整倒计时:3s 开场 + 60s 游戏(DesignStage 内部管理两个阶段的 UI)
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;
isGameRunning.value = true;
startGameLoop();
......@@ -342,20 +346,19 @@ const startIntro = async () => {
startMockBoost();
}
// Phase 3: 等待游戏结束(最多 60 秒 或 所有马跑完)
const maxMs = 60000;
const gameStart = Date.now();
await new Promise<void>((resolve) => {
const check = setInterval(() => {
const allDone = horses.value.length > 0 && horses.value.every((h) => h.xPercent >= 100);
const timeUp = Date.now() - gameStart >= maxMs;
if (allDone || timeUp || !isGameRunning.value) {
clearInterval(check);
resolve();
// 监测提前结束(所有马跑完 → 提前停止倒计时)
const earlyCheck = setInterval(() => {
const allDone =
horses.value.length > 0 &&
horses.value.every((h) => h.xPercent >= 100);
if (allDone && isGameRunning.value) {
designStage.value?.stopCountdown();
}
}, 200);
});
// 等待 60s 游戏倒计时结束
await countdownPromise;
clearInterval(earlyCheck);
stopGame();
};
......
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