更新
This commit is contained in:
+64
@@ -0,0 +1,64 @@
|
||||
"use strict";
|
||||
const common_vendor = require("../../../common/vendor.js");
|
||||
function useGameAuth(proxy) {
|
||||
let loginPromise = null;
|
||||
function hasToken() {
|
||||
return !!String(common_vendor.index.getStorageSync("token") || "").trim();
|
||||
}
|
||||
function clearToken() {
|
||||
common_vendor.index.removeStorageSync("token");
|
||||
}
|
||||
function wxLoginCode() {
|
||||
return new Promise((resolve, reject) => {
|
||||
common_vendor.index.login({
|
||||
provider: "weixin",
|
||||
success: (res) => (res == null ? void 0 : res.code) ? resolve(res.code) : reject(new Error("微信登录未返回 code")),
|
||||
fail: reject
|
||||
});
|
||||
});
|
||||
}
|
||||
async function loginWithCode(code) {
|
||||
var _a;
|
||||
const res = await proxy.apiUrl({
|
||||
url: "/api/login/mnpLogin",
|
||||
method: "POST",
|
||||
data: { code }
|
||||
}, false);
|
||||
if ((res == null ? void 0 : res.code) !== 1 || !((_a = res.data) == null ? void 0 : _a.token)) {
|
||||
clearToken();
|
||||
throw new Error((res == null ? void 0 : res.msg) || "登录失败");
|
||||
}
|
||||
common_vendor.index.setStorageSync("token", res.data.token);
|
||||
common_vendor.index.setStorageSync("userData", res.data);
|
||||
return true;
|
||||
}
|
||||
async function verifyOrLogin() {
|
||||
if (hasToken()) {
|
||||
try {
|
||||
const res = await proxy.apiUrl({ url: "/api/user/info", method: "POST" }, false);
|
||||
if ((res == null ? void 0 : res.code) === 1 && res.data) {
|
||||
common_vendor.index.setStorageSync("userData", res.data);
|
||||
return true;
|
||||
}
|
||||
if ((res == null ? void 0 : res.code) !== -1)
|
||||
return true;
|
||||
} catch (_) {
|
||||
return true;
|
||||
}
|
||||
clearToken();
|
||||
}
|
||||
const code = await wxLoginCode();
|
||||
return loginWithCode(code);
|
||||
}
|
||||
async function ensureLoggedIn() {
|
||||
if (loginPromise)
|
||||
return loginPromise;
|
||||
loginPromise = verifyOrLogin().then((ok) => !!ok).catch(() => false).finally(() => {
|
||||
loginPromise = null;
|
||||
});
|
||||
return loginPromise;
|
||||
}
|
||||
return { ensureLoggedIn };
|
||||
}
|
||||
exports.useGameAuth = useGameAuth;
|
||||
//# sourceMappingURL=../../../../.sourcemap/mp-weixin/tongji/endless-game/composables/useGameAuth.js.map
|
||||
Vendored
+240
@@ -0,0 +1,240 @@
|
||||
"use strict";
|
||||
const common_vendor = require("../../../common/vendor.js");
|
||||
const EMPTY_BOARD = {
|
||||
week_start: "",
|
||||
week_end: "",
|
||||
sex_label: "同行",
|
||||
group_size: 7,
|
||||
member_count: 0,
|
||||
players: [],
|
||||
me: { count: 0, rank: 1, best_score: 0, distance: 0, is_first: true },
|
||||
invite_code: ""
|
||||
};
|
||||
const PENDING_SYNC_KEY = "tongji_endless_pending_sync_v1";
|
||||
function createSessionKey() {
|
||||
const random = Math.random().toString(36).slice(2, 12);
|
||||
return `game_${Date.now().toString(36)}_${random}`;
|
||||
}
|
||||
function readPendingPayloads() {
|
||||
try {
|
||||
const stored = common_vendor.index.getStorageSync(PENDING_SYNC_KEY);
|
||||
if (!Array.isArray(stored))
|
||||
return [];
|
||||
return stored.filter((item) => item && /^[A-Za-z0-9_-]{16,64}$/.test(String(item.session_key || "")) && Number(item.learned_count) >= 0).slice(-8);
|
||||
} catch (_) {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
function useGamePlatform(proxy, ensureLoggedIn) {
|
||||
const connected = common_vendor.ref(false);
|
||||
const loading = common_vendor.ref(false);
|
||||
const syncStatus = common_vendor.ref("idle");
|
||||
const leaderboard = common_vendor.ref({ ...EMPTY_BOARD });
|
||||
const confirmedSessionLearned = common_vendor.ref(0);
|
||||
let sessionKey = createSessionKey();
|
||||
let syncTimer = null;
|
||||
let syncing = false;
|
||||
let queuedPayloads = readPendingPayloads();
|
||||
let connectPromise = null;
|
||||
function persistPendingPayloads() {
|
||||
try {
|
||||
common_vendor.index.setStorageSync(PENDING_SYNC_KEY, queuedPayloads.slice(-8));
|
||||
} catch (_) {
|
||||
}
|
||||
}
|
||||
async function api(request) {
|
||||
if (!(proxy == null ? void 0 : proxy.apiUrl))
|
||||
throw new Error("平台接口未初始化");
|
||||
return proxy.apiUrl(request, false);
|
||||
}
|
||||
function applyLeaderboard(data, confirmedForSession = "") {
|
||||
if (!data || !Array.isArray(data.players))
|
||||
return;
|
||||
const inactiveSessionResponse = confirmedForSession && confirmedForSession !== sessionKey;
|
||||
if (!inactiveSessionResponse) {
|
||||
leaderboard.value = {
|
||||
...EMPTY_BOARD,
|
||||
...data,
|
||||
me: { ...EMPTY_BOARD.me, ...data.me || {} },
|
||||
players: data.players
|
||||
};
|
||||
}
|
||||
if (confirmedForSession === sessionKey && data.confirmed_session_learned != null) {
|
||||
confirmedSessionLearned.value = Number(data.confirmed_session_learned) || 0;
|
||||
}
|
||||
connected.value = true;
|
||||
syncStatus.value = "synced";
|
||||
}
|
||||
async function refreshLeaderboard() {
|
||||
const res = await api({
|
||||
url: "/api/tcm/gameWeeklyLeaderboard",
|
||||
method: "GET"
|
||||
});
|
||||
if ((res == null ? void 0 : res.code) !== 1 || !res.data) {
|
||||
throw new Error((res == null ? void 0 : res.msg) || "同行榜加载失败");
|
||||
}
|
||||
applyLeaderboard(res.data);
|
||||
return res.data;
|
||||
}
|
||||
async function acceptShare(inviteCode) {
|
||||
const code = String(inviteCode || "").trim().toUpperCase();
|
||||
if (!code)
|
||||
return;
|
||||
try {
|
||||
await api({
|
||||
url: "/api/tcm/gameAcceptShare",
|
||||
method: "POST",
|
||||
data: { invite_code: code }
|
||||
});
|
||||
} catch (_) {
|
||||
}
|
||||
}
|
||||
async function connect(inviteCode = "") {
|
||||
if (connectPromise)
|
||||
return connectPromise;
|
||||
connectPromise = (async () => {
|
||||
loading.value = true;
|
||||
try {
|
||||
const loggedIn = await ensureLoggedIn();
|
||||
if (!loggedIn)
|
||||
throw new Error("登录失败");
|
||||
await acceptShare(inviteCode);
|
||||
await refreshLeaderboard();
|
||||
if (queuedPayloads.length)
|
||||
flushProgress();
|
||||
return true;
|
||||
} catch (_) {
|
||||
connected.value = false;
|
||||
syncStatus.value = "offline";
|
||||
return false;
|
||||
} finally {
|
||||
loading.value = false;
|
||||
connectPromise = null;
|
||||
}
|
||||
})();
|
||||
return connectPromise;
|
||||
}
|
||||
function beginSession() {
|
||||
if (syncTimer)
|
||||
clearTimeout(syncTimer);
|
||||
sessionKey = createSessionKey();
|
||||
confirmedSessionLearned.value = 0;
|
||||
syncStatus.value = queuedPayloads.length ? "pending" : connected.value ? "synced" : "offline";
|
||||
return sessionKey;
|
||||
}
|
||||
function queueProgress(learnedCount, score, ended = false) {
|
||||
const nextPayload = {
|
||||
session_key: sessionKey,
|
||||
learned_count: Math.max(0, Number(learnedCount) || 0),
|
||||
score: Math.max(0, Number(score) || 0),
|
||||
ended: ended ? 1 : 0
|
||||
};
|
||||
const existingIndex = queuedPayloads.findIndex((item) => item.session_key === sessionKey);
|
||||
if (existingIndex >= 0) {
|
||||
const existing = queuedPayloads[existingIndex];
|
||||
queuedPayloads[existingIndex] = {
|
||||
...nextPayload,
|
||||
learned_count: Math.max(existing.learned_count, nextPayload.learned_count),
|
||||
score: Math.max(existing.score, nextPayload.score),
|
||||
ended: Math.max(existing.ended, nextPayload.ended)
|
||||
};
|
||||
} else {
|
||||
queuedPayloads.push(nextPayload);
|
||||
}
|
||||
persistPendingPayloads();
|
||||
syncStatus.value = "pending";
|
||||
if (syncTimer)
|
||||
clearTimeout(syncTimer);
|
||||
if (ended) {
|
||||
flushProgress();
|
||||
} else {
|
||||
syncTimer = setTimeout(flushProgress, 1e3);
|
||||
}
|
||||
}
|
||||
async function flushProgress() {
|
||||
if (syncTimer)
|
||||
clearTimeout(syncTimer);
|
||||
syncTimer = null;
|
||||
if (syncing || !queuedPayloads.length)
|
||||
return;
|
||||
const payload = queuedPayloads[0];
|
||||
syncing = true;
|
||||
syncStatus.value = "syncing";
|
||||
try {
|
||||
if (!connected.value) {
|
||||
const loggedIn = await ensureLoggedIn();
|
||||
if (!loggedIn)
|
||||
throw new Error("未登录");
|
||||
}
|
||||
const res = await api({
|
||||
url: "/api/tcm/gameSubmitProgress",
|
||||
method: "POST",
|
||||
data: payload
|
||||
});
|
||||
if ((res == null ? void 0 : res.code) !== 1 || !res.data) {
|
||||
throw new Error((res == null ? void 0 : res.msg) || "成绩保存失败");
|
||||
}
|
||||
applyLeaderboard(res.data, payload.session_key);
|
||||
queuedPayloads = queuedPayloads.filter((item) => item.session_key !== payload.session_key || Number(item.learned_count) > Number(payload.learned_count) || Number(item.score) > Number(payload.score) || Number(item.ended) > Number(payload.ended));
|
||||
persistPendingPayloads();
|
||||
} catch (_) {
|
||||
connected.value = false;
|
||||
syncStatus.value = "offline";
|
||||
persistPendingPayloads();
|
||||
} finally {
|
||||
syncing = false;
|
||||
if (queuedPayloads.length && connected.value) {
|
||||
setTimeout(flushProgress, 80);
|
||||
}
|
||||
}
|
||||
}
|
||||
async function syncAndRefresh(learnedCount, score) {
|
||||
queueProgress(learnedCount, score, false);
|
||||
await flushProgress();
|
||||
if (!connected.value) {
|
||||
await connect();
|
||||
if (queuedPayloads.length)
|
||||
await flushProgress();
|
||||
} else {
|
||||
try {
|
||||
await refreshLeaderboard();
|
||||
} catch (_) {
|
||||
}
|
||||
}
|
||||
}
|
||||
async function recordShare() {
|
||||
var _a;
|
||||
try {
|
||||
if (!connected.value && !await connect())
|
||||
return;
|
||||
const res = await api({ url: "/api/tcm/gameRecordShare", method: "POST" });
|
||||
if ((res == null ? void 0 : res.code) === 1 && ((_a = res.data) == null ? void 0 : _a.invite_code)) {
|
||||
leaderboard.value = { ...leaderboard.value, invite_code: res.data.invite_code };
|
||||
}
|
||||
} catch (_) {
|
||||
}
|
||||
}
|
||||
function dispose() {
|
||||
if (syncTimer)
|
||||
clearTimeout(syncTimer);
|
||||
syncTimer = null;
|
||||
persistPendingPayloads();
|
||||
}
|
||||
return {
|
||||
connected,
|
||||
loading,
|
||||
syncStatus,
|
||||
leaderboard,
|
||||
confirmedSessionLearned,
|
||||
connect,
|
||||
beginSession,
|
||||
queueProgress,
|
||||
flushProgress,
|
||||
syncAndRefresh,
|
||||
refreshLeaderboard,
|
||||
recordShare,
|
||||
dispose
|
||||
};
|
||||
}
|
||||
exports.useGamePlatform = useGamePlatform;
|
||||
//# sourceMappingURL=../../../../.sourcemap/mp-weixin/tongji/endless-game/composables/useGamePlatform.js.map
|
||||
+366
@@ -0,0 +1,366 @@
|
||||
"use strict";
|
||||
const common_vendor = require("../../../common/vendor.js");
|
||||
const STORAGE_KEY = "tongji_game_sfx_enabled";
|
||||
const COS = "https://gz-1349751149.cos.ap-guangzhou.myqcloud.com/uploads/file";
|
||||
const SRC = {
|
||||
tap: `${COS}/20260526/20260526105128557ef8669.mp3`,
|
||||
swoosh: `${COS}/20260527/202605271539371ebe13672.mp3`,
|
||||
pop: `${COS}/20260526/202605261051282a0a94508.mp3`,
|
||||
buzz: `${COS}/20260527/202605271539376ff628472.mp3`,
|
||||
chime: `${COS}/20260528/202605280937077bad76716.mp3`,
|
||||
fanfare: `${COS}/20260528/20260528093707b021f5794.mp3`,
|
||||
blast: `${COS}/20260528/20260528093707ebd4d5733.mp3`,
|
||||
sparkle: `${COS}/20260528/20260528093707016f07427.mp3`,
|
||||
stinger: `${COS}/20260528/20260528093709c669f4659.mp3`
|
||||
};
|
||||
const SFX = {
|
||||
// —— 基础素材别名(供分层音效直接调用)——
|
||||
tap: { src: SRC.tap, volume: 0.32, rate: 1, pool: 3 },
|
||||
pop: { src: SRC.pop, volume: 0.3, rate: 1, pool: 4 },
|
||||
fanfare: { src: SRC.fanfare, volume: 0.56, rate: 1, pool: 2 },
|
||||
blast: { src: SRC.blast, volume: 0.62, rate: 1, pool: 2 },
|
||||
sparkle: { src: SRC.sparkle, volume: 0.5, rate: 1, pool: 2 },
|
||||
// —— 交互 ——
|
||||
select: { src: SRC.tap, volume: 0.32, rate: 1.05, pool: 3 },
|
||||
deselect: { src: SRC.tap, volume: 0.22, rate: 0.82, pool: 2 },
|
||||
hint: { src: SRC.tap, volume: 0.26, rate: 1.28, pool: 2 },
|
||||
swap: { src: SRC.swoosh, volume: 0.38, rate: 1, pool: 3 },
|
||||
swapFail: { src: SRC.buzz, volume: 0.36, rate: 1.18, pool: 2 },
|
||||
drop: { src: SRC.pop, volume: 0.3, rate: 0.88, pool: 4 },
|
||||
dropLight: { src: SRC.pop, volume: 0.22, rate: 1.22, pool: 2 },
|
||||
// —— 消除(按连数)——
|
||||
match3: { src: SRC.chime, volume: 0.48, rate: 1, pool: 4 },
|
||||
match4: { src: SRC.fanfare, volume: 0.54, rate: 1.06, pool: 3 },
|
||||
match5: { src: SRC.blast, volume: 0.62, rate: 1, pool: 3 },
|
||||
// —— 消除(按 GI 主色)——
|
||||
matchLowGi: { src: SRC.chime, volume: 0.42, rate: 0.86, pool: 2 },
|
||||
matchMidGi: { src: SRC.chime, volume: 0.46, rate: 1.02, pool: 2 },
|
||||
matchHighGi: { src: SRC.buzz, volume: 0.44, rate: 0.92, pool: 2 },
|
||||
// —— 连消 ——
|
||||
combo2: { src: SRC.fanfare, volume: 0.56, rate: 1.12, pool: 2 },
|
||||
combo3: { src: SRC.blast, volume: 0.64, rate: 1.08, pool: 2 },
|
||||
comboMega: { src: SRC.blast, volume: 0.72, rate: 1.22, pool: 2 },
|
||||
// —— 道具 ——
|
||||
insulin: { src: SRC.sparkle, volume: 0.5, rate: 1.15, pool: 2 },
|
||||
fiber: { src: SRC.swoosh, volume: 0.48, rate: 1.32, pool: 2 },
|
||||
meal: { src: SRC.stinger, volume: 0.42, rate: 1.35, pool: 1 },
|
||||
reshuffle: { src: SRC.swoosh, volume: 0.46, rate: 0.72, pool: 2 },
|
||||
// —— 反馈 ——
|
||||
score: { src: SRC.tap, volume: 0.28, rate: 1.38, pool: 2 },
|
||||
goalTick: { src: SRC.chime, volume: 0.36, rate: 1.45, pool: 2 },
|
||||
meterWarn: { src: SRC.buzz, volume: 0.5, rate: 1, pool: 2 },
|
||||
meterDanger: { src: SRC.buzz, volume: 0.58, rate: 0.78, pool: 2 },
|
||||
meterStable: { src: SRC.pop, volume: 0.24, rate: 1.05, pool: 1 },
|
||||
win: { src: SRC.fanfare, volume: 0.66, rate: 1, pool: 1 },
|
||||
winStinger: { src: SRC.stinger, volume: 0.38, rate: 1.5, pool: 1 },
|
||||
lose: { src: SRC.buzz, volume: 0.52, rate: 0.68, pool: 1 },
|
||||
// 兼容旧名
|
||||
match: { src: SRC.chime, volume: 0.48, rate: 1, pool: 4 },
|
||||
combo: { src: SRC.fanfare, volume: 0.56, rate: 1.1, pool: 3 },
|
||||
heal: { src: SRC.pop, volume: 0.44, rate: 1.18, pool: 2 },
|
||||
boost: { src: SRC.sparkle, volume: 0.52, rate: 1, pool: 2 },
|
||||
invalid: { src: SRC.buzz, volume: 0.4, rate: 1.15, pool: 2 },
|
||||
danger: { src: SRC.blast, volume: 0.58, rate: 0.95, pool: 2 }
|
||||
};
|
||||
const WARMUP_SFX = [
|
||||
"select",
|
||||
"swap",
|
||||
"swapFail",
|
||||
"drop",
|
||||
"dropLight",
|
||||
"match3",
|
||||
"match4",
|
||||
"match5",
|
||||
"combo2",
|
||||
"combo3",
|
||||
"comboMega",
|
||||
"insulin",
|
||||
"sparkle",
|
||||
"reshuffle",
|
||||
"lose"
|
||||
];
|
||||
function createAudioContext() {
|
||||
if (typeof Audio !== "undefined") {
|
||||
const audio = new Audio();
|
||||
audio.preload = "auto";
|
||||
return {
|
||||
get src() {
|
||||
return audio.src;
|
||||
},
|
||||
set src(value) {
|
||||
audio.src = value;
|
||||
},
|
||||
get volume() {
|
||||
return audio.volume;
|
||||
},
|
||||
set volume(value) {
|
||||
audio.volume = value;
|
||||
},
|
||||
get playbackRate() {
|
||||
return audio.playbackRate;
|
||||
},
|
||||
set playbackRate(value) {
|
||||
audio.playbackRate = value;
|
||||
},
|
||||
play() {
|
||||
const promise = audio.play();
|
||||
if (promise == null ? void 0 : promise.catch)
|
||||
promise.catch(() => {
|
||||
});
|
||||
},
|
||||
stop() {
|
||||
audio.pause();
|
||||
try {
|
||||
audio.currentTime = 0;
|
||||
} catch (_) {
|
||||
}
|
||||
},
|
||||
seek(time) {
|
||||
try {
|
||||
audio.currentTime = time;
|
||||
} catch (_) {
|
||||
}
|
||||
},
|
||||
destroy() {
|
||||
audio.pause();
|
||||
audio.removeAttribute("src");
|
||||
}
|
||||
};
|
||||
}
|
||||
return common_vendor.index.createInnerAudioContext();
|
||||
}
|
||||
class SfxPool {
|
||||
constructor(src, size, volume, rate = 1) {
|
||||
this.src = src;
|
||||
this.size = size;
|
||||
this.volume = volume;
|
||||
this.rate = rate;
|
||||
this.list = [];
|
||||
this.cursor = 0;
|
||||
this.warmedUp = false;
|
||||
}
|
||||
createOne() {
|
||||
const ctx = createAudioContext();
|
||||
ctx.src = this.src;
|
||||
ctx.obeyMuteSwitch = false;
|
||||
ctx.autoplay = false;
|
||||
ctx.volume = this.volume;
|
||||
try {
|
||||
ctx.playbackRate = this.rate;
|
||||
} catch (_) {
|
||||
}
|
||||
this.list.push(ctx);
|
||||
return ctx;
|
||||
}
|
||||
create() {
|
||||
while (this.list.length < this.size)
|
||||
this.createOne();
|
||||
}
|
||||
warmUp() {
|
||||
if (this.warmedUp)
|
||||
return;
|
||||
const ctx = this.list[0] || this.createOne();
|
||||
try {
|
||||
ctx.volume = 0;
|
||||
ctx.play();
|
||||
setTimeout(() => {
|
||||
try {
|
||||
ctx.stop();
|
||||
ctx.volume = this.volume;
|
||||
} catch (_) {
|
||||
}
|
||||
}, 60);
|
||||
} catch (_) {
|
||||
}
|
||||
if (this.size > 1)
|
||||
this.cursor = 1;
|
||||
this.warmedUp = true;
|
||||
}
|
||||
play(scale = 1, rateMul = 1) {
|
||||
if (this.list.length < this.size)
|
||||
this.create();
|
||||
const ctx = this.list[this.cursor % this.list.length];
|
||||
this.cursor += 1;
|
||||
const vol = Math.min(1, this.volume * scale);
|
||||
const rate = Math.min(2, Math.max(0.5, this.rate * rateMul));
|
||||
try {
|
||||
ctx.volume = vol;
|
||||
try {
|
||||
ctx.playbackRate = rate;
|
||||
} catch (_) {
|
||||
}
|
||||
ctx.stop();
|
||||
ctx.seek(0);
|
||||
ctx.play();
|
||||
} catch (_) {
|
||||
try {
|
||||
ctx.play();
|
||||
} catch (e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
destroy() {
|
||||
this.list.forEach((ctx) => {
|
||||
try {
|
||||
ctx.stop();
|
||||
ctx.destroy();
|
||||
} catch (_) {
|
||||
}
|
||||
});
|
||||
this.list = [];
|
||||
this.warmedUp = false;
|
||||
}
|
||||
}
|
||||
function dominantGi(tiles = []) {
|
||||
const cnt = { low: 0, mid: 0, high: 0 };
|
||||
tiles.forEach((t) => {
|
||||
var _a;
|
||||
const g = (_a = t == null ? void 0 : t.type) == null ? void 0 : _a.gi;
|
||||
if (g && cnt[g] !== void 0)
|
||||
cnt[g] += 1;
|
||||
});
|
||||
let best = "mid";
|
||||
let max = 0;
|
||||
Object.entries(cnt).forEach(([k, v]) => {
|
||||
if (v > max) {
|
||||
max = v;
|
||||
best = k;
|
||||
}
|
||||
});
|
||||
return best;
|
||||
}
|
||||
function useGameSfx() {
|
||||
const enabled = common_vendor.ref(true);
|
||||
const pools = {};
|
||||
try {
|
||||
const stored = common_vendor.index.getStorageSync(STORAGE_KEY);
|
||||
if (stored === false || stored === "0" || stored === 0) {
|
||||
enabled.value = false;
|
||||
}
|
||||
} catch (_) {
|
||||
}
|
||||
function ensureAudioOption() {
|
||||
try {
|
||||
common_vendor.index.setInnerAudioOption({
|
||||
obeyMuteSwitch: false,
|
||||
mixWithOther: true
|
||||
});
|
||||
} catch (_) {
|
||||
}
|
||||
}
|
||||
function getPool(name) {
|
||||
const cfg = SFX[name];
|
||||
if (!cfg)
|
||||
return null;
|
||||
if (!pools[name]) {
|
||||
pools[name] = new SfxPool(cfg.src, cfg.pool, cfg.volume, cfg.rate ?? 1);
|
||||
}
|
||||
return pools[name];
|
||||
}
|
||||
function warmUp() {
|
||||
if (!enabled.value)
|
||||
return;
|
||||
ensureAudioOption();
|
||||
const names = typeof Audio !== "undefined" ? ["select"] : WARMUP_SFX;
|
||||
names.forEach((name) => {
|
||||
var _a;
|
||||
(_a = getPool(name)) == null ? void 0 : _a.warmUp();
|
||||
});
|
||||
}
|
||||
function play(name, scale = 1, rateMul = 1) {
|
||||
var _a;
|
||||
if (!enabled.value)
|
||||
return;
|
||||
(_a = getPool(name)) == null ? void 0 : _a.play(scale, rateMul);
|
||||
}
|
||||
function playLayer(primary, secondary, delayMs = 70, secScale = 0.6) {
|
||||
play(primary);
|
||||
if (secondary) {
|
||||
setTimeout(() => play(secondary, secScale), delayMs);
|
||||
}
|
||||
}
|
||||
function playMatch({ matchCount = 3, chain = 0, tiles = [] } = {}) {
|
||||
if (!enabled.value)
|
||||
return;
|
||||
const giTrack = (() => {
|
||||
const gi = dominantGi(tiles);
|
||||
if (gi === "low")
|
||||
return "matchLowGi";
|
||||
if (gi === "high")
|
||||
return "matchHighGi";
|
||||
return "matchMidGi";
|
||||
})();
|
||||
if (chain >= 3) {
|
||||
playLayer("comboMega", giTrack, 90, 0.55);
|
||||
return;
|
||||
}
|
||||
if (chain === 2) {
|
||||
playLayer("combo3", giTrack, 80, 0.5);
|
||||
return;
|
||||
}
|
||||
if (chain === 1) {
|
||||
playLayer("combo2", giTrack, 70, 0.45);
|
||||
return;
|
||||
}
|
||||
if (matchCount >= 5) {
|
||||
playLayer("match5", "matchHighGi", 85, 0.5);
|
||||
} else if (matchCount >= 4) {
|
||||
playLayer("match4", giTrack, 65, 0.48);
|
||||
} else {
|
||||
play(giTrack, 1, 1);
|
||||
setTimeout(() => play("match3", 0.85), 40);
|
||||
}
|
||||
}
|
||||
function playDrop(count = 1) {
|
||||
if (!enabled.value || count <= 0)
|
||||
return;
|
||||
const name = count >= 4 ? "drop" : "dropLight";
|
||||
play(name, Math.min(1.2, 0.85 + count * 0.04), count >= 6 ? 0.9 : 1);
|
||||
}
|
||||
function playMeter(delta, level) {
|
||||
if (!enabled.value)
|
||||
return;
|
||||
if (level > 70)
|
||||
play("meterDanger", 1 + (level - 70) * 0.02);
|
||||
else if (level < 30)
|
||||
play("meterWarn", 0.9, 0.95);
|
||||
else if (delta > 8)
|
||||
play("meterWarn", 0.75);
|
||||
else if (delta < -5)
|
||||
play("meterStable", 1.1);
|
||||
}
|
||||
function toggleEnabled() {
|
||||
enabled.value = !enabled.value;
|
||||
try {
|
||||
common_vendor.index.setStorageSync(STORAGE_KEY, enabled.value ? "1" : "0");
|
||||
} catch (_) {
|
||||
}
|
||||
if (enabled.value) {
|
||||
warmUp();
|
||||
play("select");
|
||||
}
|
||||
}
|
||||
function destroyAll() {
|
||||
Object.keys(pools).forEach((key) => {
|
||||
var _a;
|
||||
(_a = pools[key]) == null ? void 0 : _a.destroy();
|
||||
delete pools[key];
|
||||
});
|
||||
}
|
||||
common_vendor.onUnmounted(() => {
|
||||
destroyAll();
|
||||
});
|
||||
return {
|
||||
enabled,
|
||||
play,
|
||||
playLayer,
|
||||
playMatch,
|
||||
playDrop,
|
||||
playMeter,
|
||||
warmUp,
|
||||
toggleEnabled,
|
||||
destroyAll
|
||||
};
|
||||
}
|
||||
exports.useGameSfx = useGameSfx;
|
||||
//# sourceMappingURL=../../../../.sourcemap/mp-weixin/tongji/endless-game/composables/useGameSfx.js.map
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"navigationStyle": "custom",
|
||||
"navigationBarTitleText": "识糖小课堂",
|
||||
"backgroundColor": "#eefbf4",
|
||||
"disableScroll": false,
|
||||
"enableShareAppMessage": true,
|
||||
"enableShareTimeline": true,
|
||||
"usingComponents": {
|
||||
"tongji-icon": "../components/TongjiIcon"
|
||||
}
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user