1631 lines
67 KiB
JavaScript
1631 lines
67 KiB
JavaScript
"use strict";
|
||
const common_vendor = require("../../common/vendor.js");
|
||
const tongji_endlessGame_composables_useGameSfx = require("./composables/useGameSfx.js");
|
||
const tongji_endlessGame_composables_useGamePlatform = require("./composables/useGamePlatform.js");
|
||
const tongji_endlessGame_composables_useGameAuth = require("./composables/useGameAuth.js");
|
||
if (!Math) {
|
||
TongjiIcon();
|
||
}
|
||
const TongjiIcon = () => "../components/TongjiIcon.js";
|
||
const FOOD_IMAGE_BASE_URL = "https://gz-1349751149.cos.ap-guangzhou.myqcloud.com/games/food/";
|
||
const ROWS = 5;
|
||
const COLS = 4;
|
||
const GAME_DIFFICULTY = 5;
|
||
const HIGH_CAP = 3;
|
||
const MAX_CAMEL_COUNT = 5;
|
||
const OVERFLOW_CAMEL_SCORE = 100;
|
||
const MAX_CASCADE_WAVES = 3;
|
||
const COMBO_TASK_WAVE = 2;
|
||
const COMBO_TASK_TARGET = 2;
|
||
const COMBO_PITY_TURNS = 6;
|
||
const MEGA_COMBO_SCORE = 300;
|
||
const _sfc_main = {
|
||
__name: "index",
|
||
setup(__props) {
|
||
const DANGER_DROP_CHANCE = 0.05 + GAME_DIFFICULTY * 0.01;
|
||
const COLUMN_GROUP_BIAS = 0.86 - GAME_DIFFICULTY * 0.028;
|
||
const CHEER_MESSAGES = [
|
||
{ source: "同行鼓励", text: "你需要加油哦!再向前一点,就能超过上一名。", tone: "warm" },
|
||
{ source: "同行鼓励", text: "你太棒了!今天也在认真认识食物。", tone: "bright" },
|
||
{ source: "开心鼓励", text: "你肯定是个大美女(大帅哥)!保持好心情。", tone: "bright" },
|
||
{ source: "亲友留言示例", text: "游戏虽好,可不要贪吃哦!", tone: "family" },
|
||
{ source: "亲友留言示例", text: "差不多行了,赶快洗洗睡吧!", tone: "family" },
|
||
{ source: "亲友留言示例", text: "你太努力了,你是我的榜样!", tone: "warm" },
|
||
{ source: "亲友留言示例", text: "好样的!", tone: "bright" },
|
||
{ source: "亲友自定义留言示例", text: "我血糖已经正常了,你们玩吧。", tone: "family", userGenerated: true }
|
||
];
|
||
const FOODS = {
|
||
corn: { name: "玉米", short: "玉米", emoji: "🌽", color: "yellow", level: "mid", levelLabel: "中糖" },
|
||
egg: { name: "鸡蛋", short: "鸡蛋", emoji: "🥚", color: "cream", level: "low", levelLabel: "低糖" },
|
||
tomato: { name: "番茄", short: "番茄", emoji: "🍅", color: "red", level: "low", levelLabel: "低糖" },
|
||
potato: { name: "红薯", short: "红薯", emoji: "🍠", color: "purple", level: "mid", levelLabel: "中糖" },
|
||
cucumber: { name: "黄瓜", short: "黄瓜", emoji: "🥒", color: "yellow", level: "low", levelLabel: "低糖" },
|
||
lettuce: { name: "生菜", short: "生菜", emoji: "🥬", color: "cream", level: "low", levelLabel: "低糖" },
|
||
grainMantou: { name: "杂粮馒头", short: "杂粮馒头", emoji: "🫓", color: "red", level: "mid", levelLabel: "中糖" },
|
||
wonton: { name: "馄饨", short: "馄饨", emoji: "🥟", color: "purple", level: "mid", levelLabel: "中糖" },
|
||
celery: { name: "芹菜", short: "芹菜", emoji: "🌿", color: "yellow", level: "low", levelLabel: "低糖" },
|
||
mushroom: { name: "香菇", short: "香菇", emoji: "🍄", color: "cream", level: "low", levelLabel: "低糖" },
|
||
chicken: { name: "鸡肉", short: "鸡肉", emoji: "🍗", color: "red", level: "mid", levelLabel: "中糖" },
|
||
taro: { name: "芋头", short: "芋头", emoji: "🥔", color: "purple", level: "mid", levelLabel: "中糖" },
|
||
broccoli: { name: "西兰花", short: "西兰花", emoji: "🥦", color: "yellow", level: "low", levelLabel: "低糖" },
|
||
milk: { name: "牛奶", short: "牛奶", emoji: "🥛", color: "cream", level: "low", levelLabel: "低糖" },
|
||
brownRice: { name: "糙米饭", short: "糙米饭", emoji: "🍙", color: "red", level: "mid", levelLabel: "中糖" },
|
||
apple: { name: "苹果", short: "苹果", emoji: "🍎", color: "yellow", level: "low", levelLabel: "低糖" },
|
||
strawberry: { name: "草莓", short: "草莓", emoji: "🍓", color: "cream", level: "low", levelLabel: "低糖" },
|
||
banana: { name: "香蕉", short: "香蕉", emoji: "🍌", color: "red", level: "mid", levelLabel: "中糖" },
|
||
mango: { name: "芒果", short: "芒果", emoji: "🥭", color: "purple", level: "mid", levelLabel: "中糖" },
|
||
tea: { name: "红茶", short: "红茶", emoji: "🍵", color: "yellow", level: "low", levelLabel: "低糖" },
|
||
blackCoffee: { name: "黑咖啡", short: "黑咖啡", emoji: "☕", color: "cream", level: "low", levelLabel: "低糖" },
|
||
coffee: { name: "咖啡", short: "咖啡", emoji: "☕", color: "red", level: "mid", levelLabel: "中糖" },
|
||
pineapple: { name: "菠萝", short: "菠萝", emoji: "🍍", color: "purple", level: "mid", levelLabel: "中糖" },
|
||
pepper: { name: "青椒", short: "青椒", emoji: "🫑", color: "yellow", level: "low", levelLabel: "低糖" },
|
||
greenBean: { name: "四季豆", short: "四季豆", emoji: "🫛", color: "cream", level: "low", levelLabel: "低糖" },
|
||
shrimp: { name: "虾仁", short: "虾仁", emoji: "🦐", color: "red", level: "mid", levelLabel: "中糖" },
|
||
udon: { name: "乌冬面", short: "乌冬面", emoji: "🍲", color: "purple", level: "mid", levelLabel: "中糖" },
|
||
onion: { name: "洋葱", short: "洋葱", emoji: "🧅", color: "yellow", level: "low", levelLabel: "低糖" },
|
||
congee: {
|
||
name: "白米粥",
|
||
short: "白粥",
|
||
emoji: "🥣",
|
||
color: "orange",
|
||
level: "high",
|
||
levelLabel: "高糖",
|
||
high: true,
|
||
replaceable: true,
|
||
tip: "白米粥煮得软烂,消化吸收通常较快。糖尿病患者应结合食用量、搭配和个人血糖情况,在医生或营养师指导下合理选择。"
|
||
},
|
||
eightCongee: { name: "八宝粥", short: "八宝粥", emoji: "🥣", color: "orange", level: "high", levelLabel: "高糖", high: true, replaceable: true, tip: "八宝粥常含糯米、豆类或添加糖,实际影响与配方和食用量有关,请留意营养成分。" },
|
||
centuryCongee: { name: "皮蛋瘦肉粥", short: "瘦肉粥", emoji: "🥣", color: "orange", level: "high", levelLabel: "高糖", high: true, replaceable: true, tip: "粥类煮得软烂后通常吸收较快,搭配和食用量需要结合个人情况。" },
|
||
milletCongee: { name: "小米粥", short: "小米粥", emoji: "🥣", color: "orange", level: "high", levelLabel: "高糖", high: true, replaceable: true, tip: "小米粥的升糖影响与浓稠度和食用量有关,游戏等级需由医生最终审核。" },
|
||
orangeJuice: { name: "柳橙汁", short: "橙汁", emoji: "🧃", color: "orange", level: "high", levelLabel: "高糖", high: true, replaceable: true, tip: "果汁缺少完整水果的部分膳食纤维,饮用量和是否添加糖都需要注意。" },
|
||
soda: { name: "含糖汽水", short: "汽水", emoji: "🥤", color: "orange", level: "high", levelLabel: "高糖", high: true, replaceable: true, tip: "含糖饮料中的糖吸收较快,日常应优先选择不加糖的饮品。" },
|
||
riceNoodleSoup: { name: "汤粉", short: "汤粉", emoji: "🍜", color: "orange", level: "high", levelLabel: "高糖", high: true, replaceable: true, tip: "汤粉以精制米粉为主,实际影响与分量和配菜有关,应注意搭配。" },
|
||
noodleSoup: { name: "汤面", short: "汤面", emoji: "🍜", color: "orange", level: "high", levelLabel: "高糖", high: true, replaceable: true, tip: "汤面以精细面食为主,汤汁和分量需要注意,具体建议以医生审核为准。" },
|
||
milkTea: { name: "含糖奶茶", short: "奶茶", emoji: "🧋", color: "orange", level: "high", levelLabel: "高糖", high: true, replaceable: true, tip: "含糖奶茶可能同时含有较多添加糖和能量,应关注配方与饮用量。" },
|
||
camel: { name: "驼乳", short: "驼乳", emoji: "🥛", color: "milk", level: "prop", levelLabel: "道具", product: true }
|
||
};
|
||
Object.keys(FOODS).forEach((key) => {
|
||
FOODS[key].img = `${FOOD_IMAGE_BASE_URL}${key}.jpg`;
|
||
});
|
||
const FOOD_GROUPS = [
|
||
{ title: "中式早餐", safe: ["egg", "cucumber", "corn", "grainMantou"], danger: "congee" },
|
||
{ title: "家常粥餐", safe: ["celery", "mushroom", "chicken", "taro"], danger: "centuryCongee" },
|
||
{ title: "粗粮早餐", safe: ["broccoli", "milk", "brownRice", "potato"], danger: "milletCongee" },
|
||
{ title: "水果饮品", safe: ["apple", "strawberry", "banana", "mango"], danger: "orangeJuice" },
|
||
{ title: "日常饮品", safe: ["milk", "tea", "blackCoffee", "coffee"], danger: "soda" },
|
||
{ title: "南方汤粉", safe: ["pepper", "greenBean", "shrimp", "udon"], danger: "riceNoodleSoup" },
|
||
{ title: "北方面食", safe: ["onion", "celery", "corn", "grainMantou"], danger: "noodleSoup" }
|
||
];
|
||
const {
|
||
enabled: sfxEnabled,
|
||
play: playSfx,
|
||
playLayer: playSfxLayer,
|
||
playDrop: playDropSfx,
|
||
warmUp: warmUpSfx
|
||
} = tongji_endlessGame_composables_useGameSfx.useGameSfx();
|
||
const { proxy } = common_vendor.getCurrentInstance();
|
||
const { ensureLoggedIn } = tongji_endlessGame_composables_useGameAuth.useGameAuth(proxy);
|
||
const {
|
||
connected: platformConnected,
|
||
loading: platformLoading,
|
||
syncStatus: platformSyncStatus,
|
||
leaderboard: platformLeaderboard,
|
||
confirmedSessionLearned,
|
||
connect: connectPlatform,
|
||
beginSession: beginPlatformSession,
|
||
queueProgress: queuePlatformProgress,
|
||
flushProgress: flushPlatformProgress,
|
||
syncAndRefresh: syncAndRefreshPlatform,
|
||
recordShare: recordPlatformShare,
|
||
dispose: disposePlatform
|
||
} = tongji_endlessGame_composables_useGamePlatform.useGamePlatform(proxy, ensureLoggedIn);
|
||
const board = common_vendor.ref([]);
|
||
const selected = common_vendor.ref(-1);
|
||
const score = common_vendor.ref(0);
|
||
const bestScore = common_vendor.ref(0);
|
||
const learned = common_vendor.ref(0);
|
||
const combo = common_vendor.ref(0);
|
||
const feastMoves = common_vendor.ref(0);
|
||
const camelCount = common_vendor.ref(3);
|
||
const camelMode = common_vendor.ref(false);
|
||
const busy = common_vendor.ref(false);
|
||
const gameOver = common_vendor.ref(false);
|
||
const themeIndex = common_vendor.ref(0);
|
||
const endedFood = common_vendor.ref(FOODS.congee);
|
||
const taskIndex = common_vendor.ref(0);
|
||
const taskProgress = common_vendor.ref(0);
|
||
const comboDryTurns = common_vendor.ref(0);
|
||
const taskRewardVisible = common_vendor.ref(false);
|
||
const taskRewardKey = common_vendor.ref(0);
|
||
const statusText = common_vendor.ref("交换相邻食物,三个相同即可消除");
|
||
const navStyle = common_vendor.ref({ paddingTop: "20px" });
|
||
const touch = { x: 0, y: 0, index: -1 };
|
||
const dragIndex = common_vendor.ref(-1);
|
||
const dragTarget = common_vendor.ref(-1);
|
||
const dragX = common_vendor.ref(0);
|
||
const dragY = common_vendor.ref(0);
|
||
const clearingIndices = common_vendor.ref([]);
|
||
const fireClearingIndices = common_vendor.ref([]);
|
||
const impactText = common_vendor.ref("");
|
||
const impactLevel = common_vendor.ref(1);
|
||
const camelJackpot = common_vendor.ref({ visible: false, count: 0, kicker: "", title: "", reward: "" });
|
||
const stageVisible = common_vendor.ref(false);
|
||
const stageMeta = common_vendor.ref({ number: 1, title: "", foods: [] });
|
||
const reshuffleVisible = common_vendor.ref(false);
|
||
const reshuffleDone = common_vendor.ref(false);
|
||
const reshuffling = common_vendor.ref(false);
|
||
const confettiVisible = common_vendor.ref(false);
|
||
const weeklyRankVisible = common_vendor.ref(false);
|
||
const cheerIndex = common_vendor.ref(0);
|
||
const CONFETTI_COLORS = ["#ff3154", "#ffd928", "#28c76f", "#4d8dff", "#a855f7", "#ff7a1a"];
|
||
const confettiPieces = Array.from({ length: 34 }, (_, index) => ({
|
||
id: index,
|
||
emoji: index % 8 === 0 ? "🎉" : index % 11 === 0 ? "★" : "",
|
||
style: {
|
||
left: `${(index * 37 + 7) % 100}%`,
|
||
backgroundColor: index % 8 === 0 ? "transparent" : CONFETTI_COLORS[index % CONFETTI_COLORS.length],
|
||
animationDelay: `${index % 9 * 0.065}s`,
|
||
animationDuration: `${3.7 + index % 5 * 0.36}s`,
|
||
width: `${12 + index % 3 * 5}rpx`,
|
||
height: `${22 + index % 4 * 6}rpx`
|
||
}
|
||
}));
|
||
let suppressTapUntil = 0;
|
||
let tileId = 1;
|
||
let hintTimer = null;
|
||
let jackpotTimer = null;
|
||
let confettiTimer = null;
|
||
let stageTimer = null;
|
||
let taskRewardTimer = null;
|
||
let pendingThemeMatchCount = 0;
|
||
let taskRewardStatusUntil = 0;
|
||
let sfxGesturePrimed = false;
|
||
let incomingInviteCode = "";
|
||
const currentTheme = common_vendor.computed(() => FOOD_GROUPS[themeIndex.value % FOOD_GROUPS.length]);
|
||
const currentTask = common_vendor.computed(() => {
|
||
const safe = currentTheme.value.safe;
|
||
const templates = [
|
||
{ key: safe[0], label: `消除 7 个${foodOf(safe[0]).short}`, target: 7, kind: "food" },
|
||
{ key: "special", label: "制造 1 个惊喜棋子", target: 1, kind: "special" },
|
||
{ key: "combo", label: "完成连消 ×2", target: COMBO_TASK_TARGET, kind: "combo" },
|
||
{ key: safe[1], label: `消除 8 个${foodOf(safe[1]).short}`, target: 8, kind: "food" }
|
||
];
|
||
return templates[taskIndex.value % templates.length];
|
||
});
|
||
const taskPercent = common_vendor.computed(() => Math.min(100, taskProgress.value / currentTask.value.target * 100));
|
||
const highCount = common_vendor.computed(() => board.value.filter((tile) => tile && foodOf(tile.key).high).length);
|
||
const boardRows = common_vendor.computed(() => Array.from({ length: ROWS }, (_, row) => board.value.slice(row * COLS, row * COLS + COLS).map((tile, col) => ({ ...tile, index: row * COLS + col }))));
|
||
const pendingWeeklyLearned = common_vendor.computed(() => Math.max(0, learned.value - confirmedSessionLearned.value));
|
||
const weeklyMyCount = common_vendor.computed(() => {
|
||
var _a;
|
||
return Number(((_a = platformLeaderboard.value.me) == null ? void 0 : _a.count) || 0) + pendingWeeklyLearned.value;
|
||
});
|
||
const weeklyRankRows = common_vendor.computed(() => {
|
||
const remote = Array.isArray(platformLeaderboard.value.players) ? platformLeaderboard.value.players : [];
|
||
const userData = common_vendor.index.getStorageSync("userData") || {};
|
||
const fallbackName = String(userData.nickname || "我");
|
||
const source = remote.length ? remote.map((player, index) => ({
|
||
...player,
|
||
isMe: !!(player.is_me || player.isMe),
|
||
avatarUrl: player.avatar || "",
|
||
avatar: String(player.name || "同行").slice(0, 1),
|
||
tone: index % 7 + 1,
|
||
count: player.is_me || player.isMe ? weeklyMyCount.value : Number(player.count || 0)
|
||
})) : [{
|
||
id: "local-me",
|
||
name: fallbackName,
|
||
avatar: fallbackName.slice(0, 1) || "我",
|
||
avatarUrl: userData.avatar || "",
|
||
count: weeklyMyCount.value,
|
||
tone: 1,
|
||
isMe: true
|
||
}];
|
||
return source.sort((a, b) => b.count - a.count || Number(b.best_score || 0) - Number(a.best_score || 0)).map((player, index) => ({ ...player, rank: index + 1 }));
|
||
});
|
||
const weeklyMyRank = common_vendor.computed(() => {
|
||
var _a;
|
||
return ((_a = weeklyRankRows.value.find((player) => player.isMe)) == null ? void 0 : _a.rank) || 1;
|
||
});
|
||
const weeklyRankRise = common_vendor.computed(() => 0);
|
||
const weeklyIsFirst = common_vendor.computed(() => weeklyMyRank.value === 1);
|
||
const weeklyDistance = common_vendor.computed(() => {
|
||
const mineIndex = weeklyRankRows.value.findIndex((player) => player.isMe);
|
||
if (mineIndex <= 0)
|
||
return 0;
|
||
return Math.max(1, weeklyRankRows.value[mineIndex - 1].count - weeklyMyCount.value + 1);
|
||
});
|
||
const currentCheer = common_vendor.computed(() => CHEER_MESSAGES[cheerIndex.value % CHEER_MESSAGES.length]);
|
||
const weeklyRangeLabel = common_vendor.computed(() => {
|
||
const start = platformLeaderboard.value.week_start;
|
||
const end = platformLeaderboard.value.week_end;
|
||
if (!start || !end)
|
||
return getWeekRangeLabel(/* @__PURE__ */ new Date());
|
||
return `${formatWeekDate(start)}—${formatWeekDate(end)}`;
|
||
});
|
||
const weeklySexLabel = common_vendor.computed(() => platformLeaderboard.value.sex_label || "同行");
|
||
const weeklyMemberCount = common_vendor.computed(() => Math.max(1, Number(platformLeaderboard.value.member_count || weeklyRankRows.value.length)));
|
||
const weeklyStatusLabel = common_vendor.computed(() => {
|
||
if (platformLoading.value)
|
||
return "连接中";
|
||
if (!platformConnected.value)
|
||
return "离线记录中";
|
||
if (platformSyncStatus.value === "pending" || platformSyncStatus.value === "syncing")
|
||
return "保存中";
|
||
return "真实周榜";
|
||
});
|
||
common_vendor.onShareAppMessage(() => {
|
||
recordPlatformShare();
|
||
return {
|
||
title: gameShareTitle(),
|
||
path: gameSharePath()
|
||
};
|
||
});
|
||
common_vendor.onShareTimeline(() => {
|
||
recordPlatformShare();
|
||
const inviteCode = String(platformLeaderboard.value.invite_code || "");
|
||
return {
|
||
title: gameShareTitle(),
|
||
query: inviteCode ? `from=share&invite_code=${encodeURIComponent(inviteCode)}` : "from=share"
|
||
};
|
||
});
|
||
function initNavLayout() {
|
||
var _a;
|
||
let paddingTop = 20;
|
||
let paddingRight = common_vendor.index.upx2px(28);
|
||
try {
|
||
const info = common_vendor.index.getSystemInfoSync();
|
||
paddingTop = Number(((_a = info.safeAreaInsets) == null ? void 0 : _a.top) || info.statusBarHeight) || 20;
|
||
const menu = typeof common_vendor.index.getMenuButtonBoundingClientRect === "function" ? common_vendor.index.getMenuButtonBoundingClientRect() : null;
|
||
if (menu && menu.width > 0) {
|
||
paddingTop = Math.max(paddingTop, Number(menu.top) || 0);
|
||
paddingRight = Math.max(
|
||
paddingRight,
|
||
(Number(info.windowWidth) || 0) - Number(menu.left) + common_vendor.index.upx2px(8)
|
||
);
|
||
}
|
||
} catch (_) {
|
||
}
|
||
navStyle.value = {
|
||
paddingTop: `${paddingTop}px`,
|
||
paddingRight: `${paddingRight}px`
|
||
};
|
||
}
|
||
common_vendor.onLoad((options = {}) => {
|
||
initNavLayout();
|
||
bestScore.value = Number(common_vendor.index.getStorageSync("tongji_endless_best") || 0);
|
||
incomingInviteCode = String(options.invite_code || "").trim();
|
||
startGame();
|
||
weeklyRankVisible.value = true;
|
||
connectPlatform(incomingInviteCode);
|
||
});
|
||
common_vendor.onShow(() => {
|
||
connectPlatform(incomingInviteCode).then((ok) => {
|
||
if (ok)
|
||
flushPlatformProgress();
|
||
});
|
||
});
|
||
common_vendor.onUnload(() => {
|
||
if (learned.value > 0 || gameOver.value) {
|
||
queuePlatformProgress(learned.value, score.value, gameOver.value);
|
||
flushPlatformProgress();
|
||
}
|
||
disposePlatform();
|
||
if (hintTimer)
|
||
clearTimeout(hintTimer);
|
||
if (jackpotTimer)
|
||
clearTimeout(jackpotTimer);
|
||
if (confettiTimer)
|
||
clearTimeout(confettiTimer);
|
||
if (stageTimer)
|
||
clearTimeout(stageTimer);
|
||
if (taskRewardTimer)
|
||
clearTimeout(taskRewardTimer);
|
||
});
|
||
function makeTile(key, special = "") {
|
||
return { id: tileId++, key, special };
|
||
}
|
||
function foodOf(key) {
|
||
return FOODS[key] || FOODS.corn;
|
||
}
|
||
function getWeekRangeLabel(now) {
|
||
const date = new Date(now);
|
||
const day = date.getDay() || 7;
|
||
const monday = new Date(date);
|
||
monday.setDate(date.getDate() - day + 1);
|
||
const sunday = new Date(monday);
|
||
sunday.setDate(monday.getDate() + 6);
|
||
const label = (value) => `${value.getMonth() + 1}月${value.getDate()}日`;
|
||
return `${label(monday)}—${label(sunday)}`;
|
||
}
|
||
function formatWeekDate(value) {
|
||
const parts = String(value).split("-").map(Number);
|
||
if (parts.length !== 3)
|
||
return String(value);
|
||
return `${parts[1]}月${parts[2]}日`;
|
||
}
|
||
function gameShareTitle() {
|
||
if (learned.value > 0) {
|
||
return `我在识糖小课堂认识了${learned.value}份食物,一起来挑战吧`;
|
||
}
|
||
return "识糖小课堂:边玩边认识常见食物";
|
||
}
|
||
function gameSharePath() {
|
||
const inviteCode = String(platformLeaderboard.value.invite_code || "");
|
||
const query = inviteCode ? `?from=share&invite_code=${encodeURIComponent(inviteCode)}` : "?from=share";
|
||
return `/tongji/endless-game/index${query}`;
|
||
}
|
||
function openWeeklyRank() {
|
||
primeSfxFromGesture();
|
||
if (gameOver.value)
|
||
return;
|
||
if (busy.value || reshuffling.value || stageVisible.value || camelJackpot.value.visible) {
|
||
statusText.value = "本次消除完成后即可查看同行榜";
|
||
return;
|
||
}
|
||
weeklyRankVisible.value = true;
|
||
syncAndRefreshPlatform(learned.value, score.value);
|
||
playSfx("select", 0.72);
|
||
}
|
||
function closeWeeklyRank() {
|
||
primeSfxFromGesture();
|
||
weeklyRankVisible.value = false;
|
||
playSfx("select", 0.86);
|
||
scheduleHint();
|
||
}
|
||
function cycleCheer() {
|
||
primeSfxFromGesture();
|
||
cheerIndex.value = (cheerIndex.value + 1) % CHEER_MESSAGES.length;
|
||
playSfx("select", 0.68);
|
||
}
|
||
function startGame() {
|
||
if (hintTimer)
|
||
clearTimeout(hintTimer);
|
||
beginPlatformSession();
|
||
themeIndex.value = 0;
|
||
board.value = buildPlayableBoard(openingKeysForTheme(currentTheme.value));
|
||
selected.value = -1;
|
||
score.value = 0;
|
||
learned.value = 0;
|
||
combo.value = 0;
|
||
feastMoves.value = 0;
|
||
camelCount.value = 3;
|
||
camelMode.value = false;
|
||
busy.value = false;
|
||
gameOver.value = false;
|
||
taskIndex.value = 0;
|
||
taskProgress.value = 0;
|
||
comboDryTurns.value = 0;
|
||
taskRewardVisible.value = false;
|
||
clearingIndices.value = [];
|
||
fireClearingIndices.value = [];
|
||
impactText.value = "";
|
||
camelJackpot.value.visible = false;
|
||
stageVisible.value = false;
|
||
reshuffleVisible.value = false;
|
||
reshuffleDone.value = false;
|
||
reshuffling.value = false;
|
||
confettiVisible.value = false;
|
||
pendingThemeMatchCount = 0;
|
||
taskRewardStatusUntil = 0;
|
||
resetDrag();
|
||
statusText.value = "交换相邻食物,三个相同即可消除";
|
||
scheduleHint();
|
||
}
|
||
function goBack() {
|
||
const pages = getCurrentPages();
|
||
if (pages.length > 1) {
|
||
common_vendor.index.navigateBack({
|
||
delta: 1,
|
||
fail: () => common_vendor.index.redirectTo({ url: "/tongji/pages/weekly" })
|
||
});
|
||
return;
|
||
}
|
||
common_vendor.index.redirectTo({ url: "/tongji/pages/weekly" });
|
||
}
|
||
function showRules() {
|
||
common_vendor.index.showModal({
|
||
title: "玩法说明",
|
||
content: `当前难度:${GAME_DIFFICULTY}/10
|
||
|
||
交换相邻食物,三个相同即可消除。四连、直线五连会生成火焰惊喜棋子;横向三个与竖向三个相交的 L/T 形五消,会生成范围爆破棋子,再次消除可清除周围九格。连消×2会计入连消小目标,连续普通消除后会出现一次连消机会;连消×3可获得额外惊喜奖励。完成小目标直接获得 1 罐驼乳粉;驼乳粉可替换本组指定稀食或饮品,三个驼乳连消后进入下一组食品。主动三消“高糖”食物代表吃掉,会结束本局;火焰特效波及高糖食物代表将它移出餐盘,不算吃掉。没有可走步时会自动洗牌。`,
|
||
showCancel: false,
|
||
confirmText: "知道了"
|
||
});
|
||
}
|
||
function toggleSfx() {
|
||
sfxEnabled.value = !sfxEnabled.value;
|
||
try {
|
||
common_vendor.index.setStorageSync("tongji_game_sfx_enabled", sfxEnabled.value ? "1" : "0");
|
||
} catch (_) {
|
||
}
|
||
if (sfxEnabled.value) {
|
||
primeSfxFromGesture();
|
||
playSfx("select", 0.8);
|
||
}
|
||
common_vendor.index.showToast({ title: sfxEnabled.value ? "音效已开启" : "音效已关闭", icon: "none" });
|
||
}
|
||
function primeSfxFromGesture() {
|
||
if (sfxGesturePrimed || !sfxEnabled.value)
|
||
return;
|
||
sfxGesturePrimed = true;
|
||
warmUpSfx();
|
||
}
|
||
function cellClasses(tile) {
|
||
const food = foodOf(tile.key);
|
||
return [
|
||
`is-${food.color}`,
|
||
`is-level-${food.level}`,
|
||
{
|
||
"is-selected": selected.value === tile.index,
|
||
"is-high": food.high,
|
||
"is-camel-target": camelMode.value && food.replaceable,
|
||
"is-clearing": clearingIndices.value.includes(tile.index),
|
||
"is-fire-clearing": fireClearingIndices.value.includes(tile.index),
|
||
"is-dragging": dragIndex.value === tile.index || dragTarget.value === tile.index
|
||
}
|
||
];
|
||
}
|
||
function cellMotionStyle(index) {
|
||
if (dragIndex.value === index)
|
||
return { transform: `translate(${dragX.value}px, ${dragY.value}px) scale(1.05)`, zIndex: 6 };
|
||
if (dragTarget.value === index)
|
||
return { transform: `translate(${-dragX.value * 0.72}px, ${-dragY.value * 0.72}px) scale(.96)`, zIndex: 4 };
|
||
return {};
|
||
}
|
||
function touchStart(event, index) {
|
||
var _a;
|
||
primeSfxFromGesture();
|
||
const point = (_a = event.touches) == null ? void 0 : _a[0];
|
||
if (!point)
|
||
return;
|
||
touch.x = point.clientX;
|
||
touch.y = point.clientY;
|
||
touch.index = index;
|
||
dragIndex.value = index;
|
||
dragTarget.value = -1;
|
||
dragX.value = 0;
|
||
dragY.value = 0;
|
||
}
|
||
function touchMove(event, index) {
|
||
var _a;
|
||
const point = (_a = event.touches) == null ? void 0 : _a[0];
|
||
if (!point || touch.index !== index || busy.value)
|
||
return;
|
||
const rawX = point.clientX - touch.x;
|
||
const rawY = point.clientY - touch.y;
|
||
const horizontal = Math.abs(rawX) > Math.abs(rawY);
|
||
dragX.value = horizontal ? Math.max(-82, Math.min(82, rawX)) : 0;
|
||
dragY.value = horizontal ? 0 : Math.max(-82, Math.min(82, rawY));
|
||
let target = index;
|
||
if (horizontal && Math.abs(rawX) > 10)
|
||
target += rawX > 0 ? 1 : -1;
|
||
if (!horizontal && Math.abs(rawY) > 10)
|
||
target += rawY > 0 ? COLS : -COLS;
|
||
dragTarget.value = target >= 0 && target < ROWS * COLS && isAdjacent(index, target) ? target : -1;
|
||
}
|
||
async function touchEnd(event, index) {
|
||
var _a;
|
||
const point = (_a = event.changedTouches) == null ? void 0 : _a[0];
|
||
if (!point || touch.index !== index) {
|
||
resetDrag();
|
||
return;
|
||
}
|
||
const dx = point.clientX - touch.x;
|
||
const dy = point.clientY - touch.y;
|
||
if (Math.max(Math.abs(dx), Math.abs(dy)) < 32) {
|
||
resetDrag();
|
||
return;
|
||
}
|
||
let target = index;
|
||
if (Math.abs(dx) > Math.abs(dy))
|
||
target += dx > 0 ? 1 : -1;
|
||
else
|
||
target += dy > 0 ? COLS : -COLS;
|
||
suppressTapUntil = Date.now() + 350;
|
||
if (target >= 0 && target < ROWS * COLS && isAdjacent(index, target)) {
|
||
const horizontal = Math.abs(dx) > Math.abs(dy);
|
||
dragX.value = horizontal ? dx > 0 ? 78 : -78 : 0;
|
||
dragY.value = horizontal ? 0 : dy > 0 ? 78 : -78;
|
||
dragTarget.value = target;
|
||
playSfx("swap", 0.85);
|
||
await wait(85);
|
||
resetDrag();
|
||
trySwap(index, target, true);
|
||
} else {
|
||
resetDrag();
|
||
playSfx("swapFail", 0.65);
|
||
}
|
||
}
|
||
function resetDrag() {
|
||
dragIndex.value = -1;
|
||
dragTarget.value = -1;
|
||
dragX.value = 0;
|
||
dragY.value = 0;
|
||
}
|
||
async function tapTile(index) {
|
||
primeSfxFromGesture();
|
||
if (Date.now() < suppressTapUntil)
|
||
return;
|
||
if (busy.value || gameOver.value)
|
||
return;
|
||
const tile = board.value[index];
|
||
if (camelMode.value) {
|
||
if (!foodOf(tile.key).replaceable) {
|
||
statusText.value = `本组驼乳粉用于替换${foodOf(currentTheme.value.danger).short}`;
|
||
return;
|
||
}
|
||
board.value[index] = makeTile("camel");
|
||
board.value = [...board.value];
|
||
camelCount.value -= 1;
|
||
camelMode.value = false;
|
||
selected.value = -1;
|
||
playSfxLayer("insulin", "sparkle", 55, 0.5);
|
||
vibrate("light");
|
||
const groups = findMatches(board.value);
|
||
if (groups.length) {
|
||
busy.value = true;
|
||
statusText.value = "驼乳棋子连起来了!";
|
||
await resolveMatches(groups, index);
|
||
busy.value = false;
|
||
finishTurn();
|
||
} else {
|
||
statusText.value = `已将${foodOf(currentTheme.value.danger).short}移出餐盘,凑齐三个驼乳可换主题`;
|
||
if (!checkBoardHealth())
|
||
scheduleHint();
|
||
}
|
||
return;
|
||
}
|
||
if (selected.value < 0) {
|
||
selected.value = index;
|
||
playSfx("select", 0.75);
|
||
statusText.value = "再选择一个相邻食物进行交换";
|
||
return;
|
||
}
|
||
if (selected.value === index) {
|
||
selected.value = -1;
|
||
playSfx("deselect", 0.65);
|
||
return;
|
||
}
|
||
if (!isAdjacent(selected.value, index)) {
|
||
selected.value = index;
|
||
statusText.value = "只能交换上下左右相邻的食物";
|
||
return;
|
||
}
|
||
const from = selected.value;
|
||
selected.value = -1;
|
||
trySwap(from, index);
|
||
}
|
||
function toggleCamel() {
|
||
primeSfxFromGesture();
|
||
if (busy.value || camelCount.value <= 0 || gameOver.value)
|
||
return;
|
||
camelMode.value = !camelMode.value;
|
||
selected.value = -1;
|
||
statusText.value = camelMode.value ? `请选择橙色边框的${foodOf(currentTheme.value.danger).short}进行替换` : "已取消使用驼乳粉";
|
||
}
|
||
function isAdjacent(a, b) {
|
||
const ar = Math.floor(a / COLS);
|
||
const ac = a % COLS;
|
||
const br = Math.floor(b / COLS);
|
||
const bc = b % COLS;
|
||
return Math.abs(ar - br) + Math.abs(ac - bc) === 1;
|
||
}
|
||
async function trySwap(a, b, soundPlayed = false) {
|
||
if (busy.value || gameOver.value)
|
||
return;
|
||
busy.value = true;
|
||
if (!soundPlayed)
|
||
playSfx("swap", 0.85);
|
||
swap(a, b);
|
||
await wait(130);
|
||
const groups = findMatches(board.value);
|
||
if (!groups.length) {
|
||
swap(a, b);
|
||
playSfx("swapFail", 0.8);
|
||
vibrate("light");
|
||
statusText.value = "这一步没有形成三连,再试一次";
|
||
busy.value = false;
|
||
if (!checkBoardHealth())
|
||
scheduleHint();
|
||
return;
|
||
}
|
||
const directIndices = new Set(groups.flatMap((group) => group.indices));
|
||
const highTile = [...directIndices].map((i) => board.value[i]).find((tile) => foodOf(tile.key).high);
|
||
if (highTile) {
|
||
playSfx("lose", 0.9);
|
||
vibrate("heavy");
|
||
endedFood.value = foodOf(highTile.key);
|
||
saveBest();
|
||
gameOver.value = true;
|
||
queuePlatformProgress(learned.value, score.value, true);
|
||
busy.value = false;
|
||
return;
|
||
}
|
||
await resolveMatches(groups, b);
|
||
busy.value = false;
|
||
if (!gameOver.value)
|
||
finishTurn();
|
||
}
|
||
function swap(a, b) {
|
||
const next = [...board.value];
|
||
[next[a], next[b]] = [next[b], next[a]];
|
||
board.value = next;
|
||
}
|
||
async function resolveMatches(initialGroups, movedIndex) {
|
||
const comboTaskAtStart = currentTask.value.kind === "combo";
|
||
let groups = initialGroups;
|
||
let wave = 0;
|
||
let turnConsumed = 0;
|
||
let madeSpecial = 0;
|
||
let firstWave = true;
|
||
while (groups.length && wave < MAX_CASCADE_WAVES) {
|
||
wave += 1;
|
||
combo.value = wave;
|
||
const remove = new Set(groups.flatMap((group) => group.indices));
|
||
let keeper = -1;
|
||
let keeperSpecial = "";
|
||
const bentMatch = firstWave ? findBentFiveMatch(groups) : null;
|
||
if (firstWave) {
|
||
const large = groups.find((group) => group.indices.length >= 4);
|
||
if (bentMatch) {
|
||
keeper = bentMatch.intersection;
|
||
keeperSpecial = "burst";
|
||
remove.delete(keeper);
|
||
madeSpecial = 1;
|
||
} else if (large) {
|
||
keeper = large.indices.includes(movedIndex) ? movedIndex : large.indices[0];
|
||
keeperSpecial = large.indices.length >= 5 ? "all" : large.direction;
|
||
remove.delete(keeper);
|
||
madeSpecial = 1;
|
||
}
|
||
}
|
||
fireClearingIndices.value = [];
|
||
const specialEffects = expandSpecials(remove);
|
||
const camelGroup = groups.filter((group) => group.indices.every((index) => {
|
||
var _a;
|
||
return ((_a = board.value[index]) == null ? void 0 : _a.key) === "camel";
|
||
})).sort((a, b) => b.indices.length - a.indices.length)[0];
|
||
const bentIndices = bentMatch ? [.../* @__PURE__ */ new Set([...bentMatch.row.indices, ...bentMatch.col.indices])] : [];
|
||
const bentCamelCount = bentIndices.length === 5 && bentIndices.every((index) => {
|
||
var _a;
|
||
return ((_a = board.value[index]) == null ? void 0 : _a.key) === "camel";
|
||
}) ? 5 : 0;
|
||
const camelMatchCount = Math.max(bentCamelCount, (camelGroup == null ? void 0 : camelGroup.indices.length) || 0);
|
||
if (camelMatchCount >= 3)
|
||
applyCamelJackpot(camelMatchCount, remove);
|
||
const removedTiles = [...remove].map((i) => board.value[i]).filter(Boolean);
|
||
const removedNormal = removedTiles.filter((tile) => {
|
||
const food = foodOf(tile.key);
|
||
return !food.high && !food.product;
|
||
});
|
||
const fireRemovedHigh = fireClearingIndices.value.some((index) => {
|
||
var _a;
|
||
return foodOf((_a = board.value[index]) == null ? void 0 : _a.key).high;
|
||
});
|
||
const largestMatch = Math.max(
|
||
...groups.map((group) => group.indices.length),
|
||
keeperSpecial === "burst" || specialEffects.hasBurst ? 5 : 3
|
||
);
|
||
clearingIndices.value = [...remove];
|
||
const triggeredSpecial = fireRemovedHigh ? "fire-high" : specialEffects.hasBurst ? "burst-triggered" : specialEffects.hasFire ? "fire-triggered" : keeperSpecial;
|
||
showImpact(largestMatch, wave, triggeredSpecial);
|
||
playMatchImpact(largestMatch, wave);
|
||
vibrate(largestMatch >= 5 || wave >= 3 ? "medium" : "light");
|
||
turnConsumed += removedNormal.length;
|
||
learned.value += removedNormal.length;
|
||
updateFoodTask(removedNormal);
|
||
const multiplier = feastMoves.value > 0 ? 2 : 1;
|
||
score.value += (removedNormal.length * 12 + Math.max(0, wave - 1) * 20 + madeSpecial * 35) * multiplier;
|
||
queuePlatformProgress(learned.value, score.value, false);
|
||
await wait(specialEffects.hasFire ? 330 : 210);
|
||
const next = [...board.value];
|
||
remove.forEach((index) => {
|
||
next[index] = null;
|
||
});
|
||
if (keeper >= 0 && next[keeper])
|
||
next[keeper] = { ...next[keeper], special: keeperSpecial };
|
||
board.value = next;
|
||
clearingIndices.value = [];
|
||
fireClearingIndices.value = [];
|
||
if (madeSpecial && currentTask.value.kind === "special")
|
||
advanceTask(madeSpecial);
|
||
await wait(70);
|
||
const shouldGuaranteeCombo = firstWave && comboTaskAtStart && comboDryTurns.value >= COMBO_PITY_TURNS - 1;
|
||
collapseAndFill(shouldGuaranteeCombo);
|
||
playDropSfx(remove.size);
|
||
await wait(190);
|
||
groups = findMatches(board.value);
|
||
const automaticHighMatch = groups.some((group) => group.indices.some((index) => {
|
||
var _a;
|
||
return foodOf((_a = board.value[index]) == null ? void 0 : _a.key).high;
|
||
}));
|
||
if (automaticHighMatch) {
|
||
board.value = makeStablePlayableBoard(board.value);
|
||
groups = [];
|
||
statusText.value = "自动掉落避开了高糖连消,棋盘已整理";
|
||
} else if (wave >= MAX_CASCADE_WAVES && groups.length) {
|
||
board.value = makeStablePlayableBoard(board.value);
|
||
groups = [];
|
||
statusText.value = "连消奖励已结算,棋盘已稳定";
|
||
}
|
||
firstWave = false;
|
||
madeSpecial = 0;
|
||
}
|
||
if (wave >= 3)
|
||
rewardMegaCombo(wave);
|
||
if (comboTaskAtStart) {
|
||
if (wave >= COMBO_TASK_WAVE) {
|
||
comboDryTurns.value = 0;
|
||
advanceTask(1);
|
||
} else {
|
||
comboDryTurns.value += 1;
|
||
}
|
||
}
|
||
if (turnConsumed > 0 && feastMoves.value > 0)
|
||
feastMoves.value -= 1;
|
||
if (pendingThemeMatchCount >= 3) {
|
||
const matchedCount = pendingThemeMatchCount;
|
||
pendingThemeMatchCount = 0;
|
||
const celebrationDelay = matchedCount >= 5 ? 2300 : matchedCount === 4 ? 2e3 : 1250;
|
||
await wait(celebrationDelay);
|
||
advanceFoodTheme();
|
||
}
|
||
}
|
||
function playMatchImpact(matchSize, wave) {
|
||
if (wave >= 3)
|
||
playSfxLayer("comboMega", "blast", 70, 0.55);
|
||
else if (wave === 2)
|
||
playSfxLayer("combo3", "pop", 60, 0.5);
|
||
else if (matchSize >= 5)
|
||
playSfxLayer("match5", "blast", 65, 0.55);
|
||
else if (matchSize >= 4)
|
||
playSfxLayer("match4", "sparkle", 55, 0.5);
|
||
else
|
||
playSfxLayer("match3", "pop", 45, 0.45);
|
||
}
|
||
function planCamelReward(requested) {
|
||
const available = Math.max(0, MAX_CAMEL_COUNT - camelCount.value);
|
||
const granted = Math.min(requested, available);
|
||
const overflow = requested - granted;
|
||
return { granted, overflow, overflowScore: overflow * OVERFLOW_CAMEL_SCORE };
|
||
}
|
||
function grantCamelReward(requested) {
|
||
const reward = planCamelReward(requested);
|
||
camelCount.value += reward.granted;
|
||
score.value += reward.overflowScore;
|
||
return reward;
|
||
}
|
||
function rewardMegaCombo(wave) {
|
||
score.value += MEGA_COMBO_SCORE;
|
||
const camelReward = grantCamelReward(1);
|
||
const rewardText = camelRewardText(camelReward);
|
||
statusText.value = `${wave} 连消惊喜:+${MEGA_COMBO_SCORE} 分${rewardText ? ` · ${rewardText}` : ""}`;
|
||
taskRewardStatusUntil = Date.now() + 1800;
|
||
if (camelReward.granted > 0)
|
||
showTaskCamelReward();
|
||
startConfetti();
|
||
playSfxLayer("comboMega", "fanfare", 100, 0.82);
|
||
vibrate("medium");
|
||
common_vendor.index.showToast({
|
||
title: `${wave} 连消惊喜:+${MEGA_COMBO_SCORE} 分${camelReward.granted > 0 ? "、驼乳粉 +1" : ""}`,
|
||
icon: "none"
|
||
});
|
||
}
|
||
function camelRewardText(reward) {
|
||
const parts = [];
|
||
if (reward.granted > 0)
|
||
parts.push(`驼乳粉 ×${reward.granted}`);
|
||
if (reward.overflow > 0)
|
||
parts.push(`满仓多余奖励换 ${reward.overflowScore} 分`);
|
||
return parts.join(" · ");
|
||
}
|
||
function applyCamelJackpot(count, remove) {
|
||
pendingThemeMatchCount = Math.max(pendingThemeMatchCount, count);
|
||
if (count >= 5) {
|
||
score.value += 1554;
|
||
const camelReward = grantCamelReward(4);
|
||
feastMoves.value = Math.max(feastMoves.value, 6);
|
||
board.value.forEach((tile, index) => {
|
||
if (foodOf(tile == null ? void 0 : tile.key).high)
|
||
remove.add(index);
|
||
});
|
||
showCamelJackpot(5, "驼乳五连双倍大奖", `+1554 分 · ${camelRewardText(camelReward)} · 双倍得分 ×6`);
|
||
startConfetti();
|
||
playJackpotSequence();
|
||
return;
|
||
}
|
||
if (count === 4) {
|
||
score.value += 288;
|
||
const camelReward = grantCamelReward(1);
|
||
const highIndex = board.value.findIndex((tile, index) => foodOf(tile == null ? void 0 : tile.key).high && !remove.has(index));
|
||
if (highIndex >= 0)
|
||
remove.add(highIndex);
|
||
showCamelJackpot(4, "驼乳超级四连", `+288 分 · ${camelRewardText(camelReward)} · 移出一份高糖食物`);
|
||
playSfxLayer("match5", "fanfare", 90, 0.7);
|
||
setTimeout(() => playSfx("tap", 1.16, 0.58), 260);
|
||
vibrate("medium");
|
||
return;
|
||
}
|
||
score.value += 77;
|
||
showCamelJackpot(3, "驼乳幸运三连", "+77 分 · 轻量连消奖励");
|
||
playSfxLayer("match3", "sparkle", 44, 0.38);
|
||
vibrate("light");
|
||
}
|
||
function advanceFoodTheme() {
|
||
const previous = currentTheme.value;
|
||
themeIndex.value = (themeIndex.value + 1) % FOOD_GROUPS.length;
|
||
const nextTheme = currentTheme.value;
|
||
const mapping = {};
|
||
previous.safe.forEach((key, index) => {
|
||
mapping[key] = nextTheme.safe[index];
|
||
});
|
||
mapping[previous.danger] = nextTheme.danger;
|
||
const mappedBoard = board.value.map((tile) => {
|
||
if (!tile || !mapping[tile.key])
|
||
return tile;
|
||
return { ...tile, key: mapping[tile.key] };
|
||
});
|
||
board.value = mappedBoard;
|
||
if (findMatches(mappedBoard).length || !hasSafeMoveIn(mappedBoard)) {
|
||
board.value = buildPlayableBoard(openingKeysForTheme(nextTheme));
|
||
}
|
||
taskIndex.value = 0;
|
||
taskProgress.value = 0;
|
||
comboDryTurns.value = 0;
|
||
selected.value = -1;
|
||
camelMode.value = false;
|
||
endedFood.value = foodOf(nextTheme.danger);
|
||
stageMeta.value = {
|
||
number: themeIndex.value + 1,
|
||
title: nextTheme.title,
|
||
foods: [...nextTheme.safe, nextTheme.danger].map((key) => ({ key, ...foodOf(key) }))
|
||
};
|
||
stageVisible.value = true;
|
||
statusText.value = `已进入${nextTheme.title},橙框${foodOf(nextTheme.danger).short}可替换`;
|
||
playSfxLayer("fanfare", "sparkle", 100, 0.65);
|
||
if (stageTimer)
|
||
clearTimeout(stageTimer);
|
||
stageTimer = setTimeout(() => {
|
||
stageVisible.value = false;
|
||
}, 1800);
|
||
}
|
||
function showCamelJackpot(count, title, reward) {
|
||
if (jackpotTimer)
|
||
clearTimeout(jackpotTimer);
|
||
camelJackpot.value = {
|
||
visible: true,
|
||
count,
|
||
kicker: count >= 5 ? "JACKPOT · 777" : count === 4 ? "ONE MORE · 再来一罐" : "LUCKY · 小惊喜",
|
||
title,
|
||
reward
|
||
};
|
||
const duration = count >= 5 ? 2200 : count === 4 ? 1900 : 1150;
|
||
jackpotTimer = setTimeout(() => {
|
||
camelJackpot.value.visible = false;
|
||
}, duration);
|
||
}
|
||
function startConfetti() {
|
||
if (confettiTimer)
|
||
clearTimeout(confettiTimer);
|
||
confettiVisible.value = false;
|
||
setTimeout(() => {
|
||
confettiVisible.value = true;
|
||
}, 20);
|
||
confettiTimer = setTimeout(() => {
|
||
confettiVisible.value = false;
|
||
}, 6e3);
|
||
}
|
||
function playJackpotSequence() {
|
||
playSfx("tap", 0.9, 0.82);
|
||
setTimeout(() => playSfx("tap", 1, 1.05), 150);
|
||
setTimeout(() => playSfx("tap", 1.08, 1.35), 300);
|
||
setTimeout(() => playSfxLayer("comboMega", "fanfare", 100, 0.85), 430);
|
||
setTimeout(() => playSfxLayer("blast", "sparkle", 90, 0.75), 690);
|
||
vibrate("medium");
|
||
setTimeout(() => vibrate("medium"), 170);
|
||
setTimeout(() => vibrate("heavy"), 430);
|
||
}
|
||
function showImpact(matchSize, wave, specialType = "") {
|
||
impactLevel.value = Math.min(3, wave >= 3 ? 3 : matchSize >= 5 ? 3 : matchSize >= 4 ? 2 : 1);
|
||
if (specialType === "fire-high")
|
||
impactText.value = "火焰移出高糖!";
|
||
else if (wave >= 3)
|
||
impactText.value = `${wave} 连消!`;
|
||
else if (specialType === "fire-triggered")
|
||
impactText.value = "火焰清除!";
|
||
else if (specialType === "burst-triggered")
|
||
impactText.value = "范围爆破!";
|
||
else if (specialType === "burst")
|
||
impactText.value = "L形惊喜!";
|
||
else if (matchSize >= 5)
|
||
impactText.value = "五连惊喜!";
|
||
else if (matchSize >= 4)
|
||
impactText.value = "四连!";
|
||
else
|
||
impactText.value = "消除!";
|
||
setTimeout(() => {
|
||
impactText.value = "";
|
||
}, 520);
|
||
}
|
||
function vibrate(type = "light") {
|
||
try {
|
||
common_vendor.index.vibrateShort({ type });
|
||
} catch (_) {
|
||
}
|
||
}
|
||
function expandSpecials(remove) {
|
||
const queue = [...remove];
|
||
const seen = /* @__PURE__ */ new Set();
|
||
const fire = /* @__PURE__ */ new Set();
|
||
let hasBurst = false;
|
||
let hasFire = false;
|
||
while (queue.length) {
|
||
const index = queue.shift();
|
||
if (seen.has(index))
|
||
continue;
|
||
seen.add(index);
|
||
const tile = board.value[index];
|
||
if (!(tile == null ? void 0 : tile.special))
|
||
continue;
|
||
hasFire = true;
|
||
const extra = [];
|
||
if (tile.special === "row") {
|
||
const row = Math.floor(index / COLS);
|
||
for (let col = 0; col < COLS; col += 1)
|
||
extra.push(row * COLS + col);
|
||
} else if (tile.special === "col") {
|
||
const col = index % COLS;
|
||
for (let row = 0; row < ROWS; row += 1)
|
||
extra.push(row * COLS + col);
|
||
} else if (tile.special === "burst") {
|
||
hasBurst = true;
|
||
const centerRow = Math.floor(index / COLS);
|
||
const centerCol = index % COLS;
|
||
for (let row = Math.max(0, centerRow - 1); row <= Math.min(ROWS - 1, centerRow + 1); row += 1) {
|
||
for (let col = Math.max(0, centerCol - 1); col <= Math.min(COLS - 1, centerCol + 1); col += 1) {
|
||
extra.push(row * COLS + col);
|
||
}
|
||
}
|
||
} else {
|
||
board.value.forEach((item, i) => {
|
||
if ((item == null ? void 0 : item.key) === tile.key)
|
||
extra.push(i);
|
||
});
|
||
}
|
||
extra.forEach((i) => fire.add(i));
|
||
extra.forEach((i) => {
|
||
if (!remove.has(i)) {
|
||
remove.add(i);
|
||
queue.push(i);
|
||
}
|
||
});
|
||
}
|
||
fireClearingIndices.value = [...fire];
|
||
return { hasBurst, hasFire };
|
||
}
|
||
function collapseAndFill(forceSafeMatch = false) {
|
||
const next = Array(ROWS * COLS).fill(null);
|
||
for (let col = 0; col < COLS; col += 1) {
|
||
const existing = [];
|
||
for (let row = ROWS - 1; row >= 0; row -= 1) {
|
||
const tile = board.value[row * COLS + col];
|
||
if (tile)
|
||
existing.push(tile);
|
||
}
|
||
existing.forEach((tile, offset) => {
|
||
next[(ROWS - 1 - offset) * COLS + col] = tile;
|
||
});
|
||
}
|
||
const forcedIndices = forceSafeMatch ? findForcedDropMatch(next) : [];
|
||
const forcedSet = new Set(forcedIndices);
|
||
const forcedKey = forcedIndices.length ? pickForcedDropKey(next, forcedIndices) : "";
|
||
for (let row = 0; row < ROWS; row += 1) {
|
||
for (let col = 0; col < COLS; col += 1) {
|
||
const index = row * COLS + col;
|
||
if (!next[index]) {
|
||
const key = forcedSet.has(index) ? forcedKey : pickDropFoodKey(next, index, col);
|
||
next[index] = makeTile(key);
|
||
}
|
||
}
|
||
}
|
||
board.value = next;
|
||
return forcedIndices.length === 3;
|
||
}
|
||
function findForcedDropMatch(snapshot) {
|
||
const empty = new Set(snapshot.map((tile, index) => tile ? -1 : index).filter((index) => index >= 0));
|
||
for (let row = 0; row < ROWS; row += 1) {
|
||
for (let col = 0; col <= COLS - 3; col += 1) {
|
||
const indices = [0, 1, 2].map((offset) => row * COLS + col + offset);
|
||
if (indices.every((index) => empty.has(index)))
|
||
return indices;
|
||
}
|
||
}
|
||
for (let col = 0; col < COLS; col += 1) {
|
||
for (let row = 0; row <= ROWS - 3; row += 1) {
|
||
const indices = [0, 1, 2].map((offset) => (row + offset) * COLS + col);
|
||
if (indices.every((index) => empty.has(index)))
|
||
return indices;
|
||
}
|
||
}
|
||
return [];
|
||
}
|
||
function pickForcedDropKey(snapshot, indices) {
|
||
var _a;
|
||
return ((_a = currentTheme.value.safe.map((key) => ({
|
||
key,
|
||
nearby: snapshot.reduce((count, tile, index) => (tile == null ? void 0 : tile.key) === key && indices.some((target) => isAdjacent(target, index)) ? count + 1 : count, 0)
|
||
})).sort((a, b) => a.nearby - b.nearby)[0]) == null ? void 0 : _a.key) || currentTheme.value.safe[0];
|
||
}
|
||
function pickDropFoodKey(snapshot, index, col) {
|
||
for (let attempt = 0; attempt < 16; attempt += 1) {
|
||
const key = randomFoodKey(snapshot, col);
|
||
if (!wouldCreateMatchAt(snapshot, index, key))
|
||
return key;
|
||
}
|
||
const fallback = [...currentTheme.value.safe, currentTheme.value.danger].find((key) => !wouldCreateMatchAt(snapshot, index, key));
|
||
return fallback || currentTheme.value.safe[(index + col) % currentTheme.value.safe.length];
|
||
}
|
||
function wouldCreateMatchAt(source, index, key) {
|
||
const row = Math.floor(index / COLS);
|
||
const col = index % COLS;
|
||
const keyAt = (target) => {
|
||
var _a;
|
||
return target === index ? key : (_a = source[target]) == null ? void 0 : _a.key;
|
||
};
|
||
let horizontal = 1;
|
||
for (let c = col - 1; c >= 0 && keyAt(row * COLS + c) === key; c -= 1)
|
||
horizontal += 1;
|
||
for (let c = col + 1; c < COLS && keyAt(row * COLS + c) === key; c += 1)
|
||
horizontal += 1;
|
||
if (horizontal >= 3)
|
||
return true;
|
||
let vertical = 1;
|
||
for (let r = row - 1; r >= 0 && keyAt(r * COLS + col) === key; r -= 1)
|
||
vertical += 1;
|
||
for (let r = row + 1; r < ROWS && keyAt(r * COLS + col) === key; r += 1)
|
||
vertical += 1;
|
||
return vertical >= 3;
|
||
}
|
||
function randomFoodKey(snapshot, col = -1) {
|
||
const highs = snapshot.filter((tile) => tile && foodOf(tile.key).high).length;
|
||
if (highs < HIGH_CAP && Math.random() < DANGER_DROP_CHANCE)
|
||
return currentTheme.value.danger;
|
||
const keys = currentTheme.value.safe;
|
||
if (col >= 0 && Math.random() < COLUMN_GROUP_BIAS)
|
||
return keys[col % keys.length];
|
||
return keys[Math.floor(Math.random() * keys.length)];
|
||
}
|
||
function findBentFiveMatch(groups) {
|
||
const rows = groups.filter((group) => group.direction === "row" && group.indices.length === 3);
|
||
const cols = groups.filter((group) => group.direction === "col" && group.indices.length === 3);
|
||
for (const row of rows) {
|
||
for (const col of cols) {
|
||
const intersection = row.indices.find((index) => col.indices.includes(index));
|
||
if (intersection !== void 0)
|
||
return { intersection, row, col };
|
||
}
|
||
}
|
||
return null;
|
||
}
|
||
function findMatches(source) {
|
||
var _a, _b, _c, _d;
|
||
const groups = [];
|
||
for (let row = 0; row < ROWS; row += 1) {
|
||
let start = 0;
|
||
while (start < COLS) {
|
||
let end = start + 1;
|
||
while (end < COLS && ((_a = source[row * COLS + end]) == null ? void 0 : _a.key) === ((_b = source[row * COLS + start]) == null ? void 0 : _b.key))
|
||
end += 1;
|
||
if (source[row * COLS + start] && end - start >= 3) {
|
||
groups.push({ direction: "row", indices: Array.from({ length: end - start }, (_, n) => row * COLS + start + n) });
|
||
}
|
||
start = end;
|
||
}
|
||
}
|
||
for (let col = 0; col < COLS; col += 1) {
|
||
let start = 0;
|
||
while (start < ROWS) {
|
||
let end = start + 1;
|
||
while (end < ROWS && ((_c = source[end * COLS + col]) == null ? void 0 : _c.key) === ((_d = source[start * COLS + col]) == null ? void 0 : _d.key))
|
||
end += 1;
|
||
if (source[start * COLS + col] && end - start >= 3) {
|
||
groups.push({ direction: "col", indices: Array.from({ length: end - start }, (_, n) => (start + n) * COLS + col) });
|
||
}
|
||
start = end;
|
||
}
|
||
}
|
||
return groups;
|
||
}
|
||
function updateFoodTask(tiles) {
|
||
if (currentTask.value.kind !== "food")
|
||
return;
|
||
advanceTask(tiles.filter((tile) => tile.key === currentTask.value.key).length);
|
||
}
|
||
function advanceTask(amount) {
|
||
if (!amount)
|
||
return;
|
||
taskProgress.value += amount;
|
||
if (taskProgress.value < currentTask.value.target)
|
||
return;
|
||
score.value += 120;
|
||
const camelReward = grantCamelReward(1);
|
||
if (camelReward.granted > 0) {
|
||
showTaskCamelReward();
|
||
statusText.value = "小目标完成,驼乳粉已放入道具栏";
|
||
} else {
|
||
statusText.value = `驼乳粉已满,多余奖励换 ${camelReward.overflowScore} 分`;
|
||
}
|
||
common_vendor.index.showToast({
|
||
title: camelReward.granted > 0 ? "小目标完成:驼乳粉 +1" : `驼乳粉已满:奖励换 ${camelReward.overflowScore} 分`,
|
||
icon: "none"
|
||
});
|
||
taskIndex.value = (taskIndex.value + 1) % 4;
|
||
taskProgress.value = 0;
|
||
comboDryTurns.value = 0;
|
||
}
|
||
function showTaskCamelReward() {
|
||
if (taskRewardTimer)
|
||
clearTimeout(taskRewardTimer);
|
||
taskRewardKey.value += 1;
|
||
taskRewardVisible.value = true;
|
||
taskRewardStatusUntil = Date.now() + 1600;
|
||
playSfxLayer("boost", "sparkle", 75, 0.55);
|
||
vibrate("light");
|
||
taskRewardTimer = setTimeout(() => {
|
||
taskRewardVisible.value = false;
|
||
}, 1150);
|
||
}
|
||
function finishTurn() {
|
||
saveBest();
|
||
if (checkBoardHealth())
|
||
return;
|
||
if (stageVisible.value) {
|
||
scheduleHint();
|
||
return;
|
||
}
|
||
if (Date.now() < taskRewardStatusUntil) {
|
||
scheduleHint();
|
||
return;
|
||
}
|
||
statusText.value = combo.value >= 2 ? `漂亮!完成 ${combo.value} 连消` : "食物已从上方补充,继续挑战";
|
||
scheduleHint();
|
||
}
|
||
function checkBoardHealth() {
|
||
if (hasSafeMove() || reshuffling.value)
|
||
return false;
|
||
performReshuffle();
|
||
return true;
|
||
}
|
||
function hasSafeMove() {
|
||
return hasSafeMoveIn(board.value);
|
||
}
|
||
function hasSafeMoveIn(source) {
|
||
return Boolean(findSafeMoveIn(source));
|
||
}
|
||
function findSafeMoveIn(source) {
|
||
for (let i = 0; i < source.length; i += 1) {
|
||
const candidates = [];
|
||
if (i % COLS < COLS - 1)
|
||
candidates.push(i + 1);
|
||
if (i + COLS < source.length)
|
||
candidates.push(i + COLS);
|
||
for (const j of candidates) {
|
||
const copy = source.map((tile) => ({ ...tile }));
|
||
[copy[i], copy[j]] = [copy[j], copy[i]];
|
||
const groups = findMatches(copy);
|
||
if (groups.length && !groups.flatMap((group) => group.indices).some((index) => foodOf(copy[index].key).high)) {
|
||
return { from: i, to: j };
|
||
}
|
||
}
|
||
}
|
||
return null;
|
||
}
|
||
async function performReshuffle() {
|
||
if (reshuffling.value || gameOver.value)
|
||
return;
|
||
reshuffling.value = true;
|
||
busy.value = true;
|
||
reshuffleDone.value = false;
|
||
reshuffleVisible.value = true;
|
||
selected.value = -1;
|
||
camelMode.value = false;
|
||
statusText.value = "没有可消除组合,正在重新洗牌";
|
||
playSfx("reshuffle", 0.9);
|
||
vibrate("medium");
|
||
await wait(760);
|
||
const source = board.value.map((tile) => ({ ...tile }));
|
||
let candidate = null;
|
||
for (let attempt = 0; attempt < 240; attempt += 1) {
|
||
const shuffled = shuffleTiles(source);
|
||
if (findMatches(shuffled).length)
|
||
continue;
|
||
if (!hasSafeMoveIn(shuffled))
|
||
continue;
|
||
candidate = shuffled;
|
||
break;
|
||
}
|
||
board.value = candidate || buildGuaranteedBoard();
|
||
reshuffleDone.value = true;
|
||
statusText.value = "洗牌完成,新的消除机会已经出现";
|
||
playSfxLayer("drop", "sparkle", 70, 0.55);
|
||
vibrate("light");
|
||
await wait(520);
|
||
reshuffleVisible.value = false;
|
||
reshuffling.value = false;
|
||
busy.value = false;
|
||
scheduleHint();
|
||
}
|
||
function shuffleTiles(source) {
|
||
const result = source.map((tile) => ({ ...tile }));
|
||
for (let i = result.length - 1; i > 0; i -= 1) {
|
||
const j = Math.floor(Math.random() * (i + 1));
|
||
[result[i], result[j]] = [result[j], result[i]];
|
||
}
|
||
return result;
|
||
}
|
||
function buildGuaranteedBoard() {
|
||
return buildPlayableBoard(openingKeysForTheme(currentTheme.value));
|
||
}
|
||
function openingKeysForTheme(theme) {
|
||
const [a, b, c, d] = theme.safe;
|
||
const danger = theme.danger;
|
||
return [
|
||
a,
|
||
b,
|
||
c,
|
||
d,
|
||
b,
|
||
c,
|
||
d,
|
||
a,
|
||
c,
|
||
d,
|
||
a,
|
||
danger,
|
||
d,
|
||
a,
|
||
danger,
|
||
b,
|
||
a,
|
||
b,
|
||
c,
|
||
d
|
||
];
|
||
}
|
||
function buildPlayableBoard(keys) {
|
||
let candidate = keys.map((key) => makeTile(key));
|
||
for (let attempt = 0; attempt < 240; attempt += 1) {
|
||
if (!findMatches(candidate).length && hasSafeMoveIn(candidate))
|
||
return candidate;
|
||
candidate = shuffleTiles(candidate);
|
||
}
|
||
return forcedPlayableKeysForTheme(currentTheme.value).map((key) => makeTile(key));
|
||
}
|
||
function forcedPlayableKeysForTheme(theme) {
|
||
const [a, b, c, d] = theme.safe;
|
||
const danger = theme.danger;
|
||
return [
|
||
d,
|
||
a,
|
||
danger,
|
||
c,
|
||
d,
|
||
c,
|
||
b,
|
||
danger,
|
||
c,
|
||
a,
|
||
b,
|
||
a,
|
||
d,
|
||
d,
|
||
a,
|
||
a,
|
||
b,
|
||
d,
|
||
c,
|
||
b
|
||
];
|
||
}
|
||
function makeStablePlayableBoard(source) {
|
||
const tiles = source.filter(Boolean).map((tile) => ({ ...tile }));
|
||
if (tiles.length === ROWS * COLS) {
|
||
for (let attempt = 0; attempt < 300; attempt += 1) {
|
||
const candidate = shuffleTiles(tiles);
|
||
if (!findMatches(candidate).length && hasSafeMoveIn(candidate))
|
||
return candidate;
|
||
}
|
||
}
|
||
return buildGuaranteedBoard();
|
||
}
|
||
function safeMoveHint(move) {
|
||
var _a, _b;
|
||
if (!move)
|
||
return "";
|
||
const from = foodOf((_a = board.value[move.from]) == null ? void 0 : _a.key).short;
|
||
const to = foodOf((_b = board.value[move.to]) == null ? void 0 : _b.key).short;
|
||
const direction = move.to === move.from + 1 ? "向右" : "向下";
|
||
return `提示:把${from}${direction}与${to}交换`;
|
||
}
|
||
function scheduleHint() {
|
||
if (hintTimer)
|
||
clearTimeout(hintTimer);
|
||
hintTimer = setTimeout(() => {
|
||
if (busy.value || gameOver.value || stageVisible.value)
|
||
return;
|
||
const move = findSafeMoveIn(board.value);
|
||
if (!move) {
|
||
performReshuffle();
|
||
return;
|
||
}
|
||
statusText.value = safeMoveHint(move);
|
||
}, 5e3);
|
||
}
|
||
function saveBest() {
|
||
if (score.value <= bestScore.value)
|
||
return;
|
||
bestScore.value = score.value;
|
||
common_vendor.index.setStorageSync("tongji_endless_best", bestScore.value);
|
||
}
|
||
function wait(ms) {
|
||
return new Promise((resolve) => setTimeout(resolve, ms));
|
||
}
|
||
return (_ctx, _cache) => {
|
||
return common_vendor.e({
|
||
a: confettiVisible.value
|
||
}, confettiVisible.value ? {
|
||
b: common_vendor.f(common_vendor.unref(confettiPieces), (piece, k0, i0) => {
|
||
return {
|
||
a: common_vendor.t(piece.emoji),
|
||
b: piece.id,
|
||
c: piece.emoji ? 1 : "",
|
||
d: common_vendor.s(piece.style)
|
||
};
|
||
})
|
||
} : {}, {
|
||
c: common_vendor.p({
|
||
name: "chevron-left",
|
||
size: "md",
|
||
color: "#155e4b"
|
||
}),
|
||
d: common_vendor.o(goBack, "cd"),
|
||
e: common_vendor.t(themeIndex.value + 1),
|
||
f: common_vendor.t(currentTheme.value.title),
|
||
g: common_vendor.p({
|
||
name: "volume",
|
||
size: "sm",
|
||
color: common_vendor.unref(sfxEnabled) ? "#155e4b" : "#94a3b8"
|
||
}),
|
||
h: common_vendor.o(toggleSfx, "35"),
|
||
i: common_vendor.p({
|
||
name: "info",
|
||
size: "sm",
|
||
color: "#155e4b"
|
||
}),
|
||
j: common_vendor.o(showRules, "e4"),
|
||
k: common_vendor.s(navStyle.value),
|
||
l: common_vendor.t(learned.value),
|
||
m: common_vendor.t(score.value),
|
||
n: common_vendor.t(weeklyMyRank.value),
|
||
o: busy.value || reshuffling.value || stageVisible.value || camelJackpot.value.visible ? 1 : "",
|
||
p: common_vendor.o(openWeeklyRank, "7c"),
|
||
q: common_vendor.p({
|
||
name: "trophy",
|
||
size: "sm",
|
||
color: "#8a5a10"
|
||
}),
|
||
r: common_vendor.t(currentTask.value.label),
|
||
s: common_vendor.t(Math.min(taskProgress.value, currentTask.value.target)),
|
||
t: common_vendor.t(currentTask.value.target),
|
||
v: taskPercent.value + "%",
|
||
w: taskRewardVisible.value
|
||
}, taskRewardVisible.value ? {
|
||
x: foodOf("camel").img,
|
||
y: taskRewardKey.value
|
||
} : {}, {
|
||
z: common_vendor.t(Math.max(combo.value, 1)),
|
||
A: combo.value >= 3 ? 1 : "",
|
||
B: feastMoves.value > 0
|
||
}, feastMoves.value > 0 ? {
|
||
C: common_vendor.t(feastMoves.value)
|
||
} : {}, {
|
||
D: common_vendor.t(highCount.value),
|
||
E: common_vendor.f(3, (n, k0, i0) => {
|
||
return {
|
||
a: n,
|
||
b: n <= highCount.value ? 1 : ""
|
||
};
|
||
}),
|
||
F: common_vendor.f(boardRows.value, (row, rowIndex, i0) => {
|
||
return {
|
||
a: common_vendor.f(row, (tile, k1, i1) => {
|
||
return common_vendor.e({
|
||
a: tile.special
|
||
}, tile.special ? common_vendor.e({
|
||
b: tile.special === "row" || tile.special === "col"
|
||
}, tile.special === "row" || tile.special === "col" ? {} : tile.special === "burst" ? {} : {}, {
|
||
c: tile.special === "burst",
|
||
d: common_vendor.n(`is-${tile.special}`)
|
||
}) : {}, {
|
||
e: fireClearingIndices.value.includes(tile.index)
|
||
}, fireClearingIndices.value.includes(tile.index) ? {} : {}, {
|
||
f: foodOf(tile.key).img,
|
||
g: common_vendor.t(foodOf(tile.key).short),
|
||
h: common_vendor.t(foodOf(tile.key).levelLabel || "低糖"),
|
||
i: common_vendor.n(`is-${foodOf(tile.key).level || "low"}`),
|
||
j: camelMode.value && foodOf(tile.key).replaceable
|
||
}, camelMode.value && foodOf(tile.key).replaceable ? {} : {}, {
|
||
k: tile.id,
|
||
l: common_vendor.n(cellClasses(tile)),
|
||
m: common_vendor.s(cellMotionStyle(tile.index)),
|
||
n: common_vendor.o(($event) => tapTile(tile.index), tile.id),
|
||
o: common_vendor.o(($event) => touchStart($event, tile.index), tile.id),
|
||
p: common_vendor.o(($event) => touchMove($event, tile.index), tile.id),
|
||
q: common_vendor.o(($event) => touchEnd($event, tile.index), tile.id)
|
||
});
|
||
}),
|
||
b: rowIndex
|
||
};
|
||
}),
|
||
G: busy.value ? 1 : "",
|
||
H: impactText.value
|
||
}, impactText.value ? {
|
||
I: common_vendor.t(impactText.value),
|
||
J: common_vendor.n(`is-level-${impactLevel.value}`)
|
||
} : {}, {
|
||
K: camelJackpot.value.visible
|
||
}, camelJackpot.value.visible ? common_vendor.e({
|
||
L: common_vendor.t(camelJackpot.value.kicker),
|
||
M: camelJackpot.value.count === 3
|
||
}, camelJackpot.value.count === 3 ? {
|
||
N: common_vendor.f(3, (n, k0, i0) => {
|
||
return {
|
||
a: n
|
||
};
|
||
}),
|
||
O: foodOf("camel").img
|
||
} : camelJackpot.value.count === 4 ? {
|
||
Q: common_vendor.f(5, (n, k0, i0) => {
|
||
return common_vendor.e({
|
||
a: n < 5
|
||
}, n < 5 ? {
|
||
b: foodOf("camel").img
|
||
} : {}, {
|
||
c: n,
|
||
d: n === 5 ? 1 : ""
|
||
});
|
||
})
|
||
} : {
|
||
R: common_vendor.f(5, (n, k0, i0) => {
|
||
return {
|
||
a: n
|
||
};
|
||
}),
|
||
S: foodOf("camel").img,
|
||
T: common_vendor.f(3, (n, k0, i0) => {
|
||
return {
|
||
a: n
|
||
};
|
||
})
|
||
}, {
|
||
P: camelJackpot.value.count === 4,
|
||
U: common_vendor.t(camelJackpot.value.title),
|
||
V: camelJackpot.value.count >= 5
|
||
}, camelJackpot.value.count >= 5 ? {} : {}, {
|
||
W: common_vendor.t(camelJackpot.value.reward),
|
||
X: common_vendor.n(`is-match-${camelJackpot.value.count}`)
|
||
}) : {}, {
|
||
Y: common_vendor.p({
|
||
name: "bulb",
|
||
size: "sm",
|
||
color: "#9a6718"
|
||
}),
|
||
Z: common_vendor.t(statusText.value),
|
||
aa: foodOf("camel").img,
|
||
ab: common_vendor.p({
|
||
name: "refresh",
|
||
size: "sm",
|
||
color: "#ffffff"
|
||
}),
|
||
ac: common_vendor.t(foodOf(currentTheme.value.danger).short),
|
||
ad: common_vendor.t(camelCount.value),
|
||
ae: camelMode.value ? 1 : "",
|
||
af: camelCount.value <= 0 || busy.value ? 1 : "",
|
||
ag: common_vendor.o(toggleCamel, "1c"),
|
||
ah: weeklyRankVisible.value
|
||
}, weeklyRankVisible.value ? common_vendor.e({
|
||
ai: common_vendor.t(weeklyStatusLabel.value),
|
||
aj: !common_vendor.unref(platformConnected) ? 1 : "",
|
||
ak: common_vendor.t(weeklyRangeLabel.value),
|
||
al: common_vendor.t(weeklySexLabel.value),
|
||
am: common_vendor.t(weeklyMemberCount.value),
|
||
an: common_vendor.t(weeklyMyRank.value),
|
||
ao: common_vendor.t(weeklyMyCount.value),
|
||
ap: weeklyRankRise.value > 0
|
||
}, weeklyRankRise.value > 0 ? {
|
||
aq: common_vendor.t(weeklyMyRank.value),
|
||
ar: common_vendor.t(weeklyRankRise.value)
|
||
} : {
|
||
as: common_vendor.t(weeklyMyRank.value)
|
||
}, {
|
||
at: weeklyIsFirst.value
|
||
}, weeklyIsFirst.value ? {} : {
|
||
av: common_vendor.t(weeklyDistance.value)
|
||
}, {
|
||
aw: common_vendor.f(weeklyRankRows.value, (player, k0, i0) => {
|
||
return common_vendor.e({
|
||
a: common_vendor.t(player.rank),
|
||
b: player.avatarUrl
|
||
}, player.avatarUrl ? {
|
||
c: player.avatarUrl
|
||
} : {
|
||
d: common_vendor.t(player.avatar)
|
||
}, {
|
||
e: common_vendor.n(`is-tone-${player.tone}`),
|
||
f: common_vendor.t(player.name),
|
||
g: player.isMe
|
||
}, player.isMe ? {} : {}, {
|
||
h: common_vendor.t(player.count),
|
||
i: player.id,
|
||
j: player.isMe ? 1 : ""
|
||
});
|
||
}),
|
||
ax: common_vendor.t(currentCheer.value.source),
|
||
ay: common_vendor.o(cycleCheer, "02"),
|
||
az: common_vendor.t(currentCheer.value.text),
|
||
aA: currentCheer.value.userGenerated
|
||
}, currentCheer.value.userGenerated ? {} : {}, {
|
||
aB: common_vendor.n(`is-${currentCheer.value.tone}`),
|
||
aC: common_vendor.o(closeWeeklyRank, "f2"),
|
||
aD: common_vendor.o(() => {
|
||
}, "9c")
|
||
}) : {}, {
|
||
aE: reshuffleVisible.value
|
||
}, reshuffleVisible.value ? {
|
||
aF: common_vendor.p({
|
||
name: "refresh",
|
||
size: "lg",
|
||
color: "#ffffff"
|
||
}),
|
||
aG: common_vendor.t(reshuffleDone.value ? "洗牌完成" : "没有可消除组合"),
|
||
aH: common_vendor.t(reshuffleDone.value ? "新的消除机会已经出现" : "正在为您重新洗牌,请稍候"),
|
||
aI: common_vendor.o(() => {
|
||
}, "40")
|
||
} : {}, {
|
||
aJ: stageVisible.value
|
||
}, stageVisible.value ? {
|
||
aK: common_vendor.t(stageMeta.value.number),
|
||
aL: common_vendor.t(stageMeta.value.title),
|
||
aM: common_vendor.f(stageMeta.value.foods, (food, k0, i0) => {
|
||
return {
|
||
a: food.img,
|
||
b: common_vendor.t(food.short),
|
||
c: food.key,
|
||
d: food.high ? 1 : ""
|
||
};
|
||
}),
|
||
aN: common_vendor.o(() => {
|
||
}, "01")
|
||
} : {}, {
|
||
aO: gameOver.value
|
||
}, gameOver.value ? {
|
||
aP: common_vendor.t(endedFood.value.name),
|
||
aQ: common_vendor.t(endedFood.value.tip),
|
||
aR: common_vendor.t(score.value),
|
||
aS: common_vendor.t(bestScore.value),
|
||
aT: common_vendor.o(startGame, "33"),
|
||
aU: common_vendor.o(goBack, "98"),
|
||
aV: common_vendor.o(() => {
|
||
}, "72")
|
||
} : {}, {
|
||
aW: common_vendor.o(primeSfxFromGesture, "77"),
|
||
aX: common_vendor.o(primeSfxFromGesture, "a4")
|
||
});
|
||
};
|
||
}
|
||
};
|
||
const MiniProgramPage = /* @__PURE__ */ common_vendor._export_sfc(_sfc_main, [["__scopeId", "data-v-ace1d107"]]);
|
||
_sfc_main.__runtimeHooks = 6;
|
||
wx.createPage(MiniProgramPage);
|
||
//# sourceMappingURL=../../../.sourcemap/mp-weixin/tongji/endless-game/index.js.map
|