60 lines
1.9 KiB
JavaScript
60 lines
1.9 KiB
JavaScript
// 本地存档:通关记录、最佳成绩、自制关卡
|
|
const KEY = 'iwbtc_fan_v1';
|
|
|
|
const blank = () => ({ cleared: {}, customs: [], audio: true });
|
|
|
|
export const Save = {
|
|
data: blank(),
|
|
|
|
load() {
|
|
try {
|
|
const s = localStorage.getItem(KEY);
|
|
if (s) this.data = Object.assign(blank(), JSON.parse(s));
|
|
} catch (e) { this.data = blank(); }
|
|
return this.data;
|
|
},
|
|
flush() {
|
|
try { localStorage.setItem(KEY, JSON.stringify(this.data)); } catch (e) { }
|
|
},
|
|
get(id) { return this.data.cleared[id] || null; },
|
|
isCleared(id) { return !!this.data.cleared[id]; },
|
|
/** 记录通关,返回是否刷新纪录 */
|
|
clear(id, deaths, ms, apples) {
|
|
const old = this.data.cleared[id];
|
|
const rec = { deaths, time: ms, apples: apples || 0, at: Date.now() };
|
|
let better = false;
|
|
if (!old) { this.data.cleared[id] = rec; better = true; }
|
|
else {
|
|
const nd = Math.min(old.deaths, deaths);
|
|
const nt = Math.min(old.time, ms);
|
|
better = deaths < old.deaths || ms < old.time;
|
|
this.data.cleared[id] = { ...old, deaths: nd, time: nt, apples: Math.max(old.apples || 0, apples || 0) };
|
|
}
|
|
this.flush();
|
|
return better;
|
|
},
|
|
wipe() { this.data = blank(); this.flush(); },
|
|
|
|
customs() { return this.data.customs || []; },
|
|
addCustom(lv) {
|
|
this.data.customs = this.data.customs || [];
|
|
this.data.customs.push(lv);
|
|
this.flush();
|
|
return lv;
|
|
},
|
|
/** 更新已保存的自制关卡(按 id 就地替换,不新增);id 不存在则追加 */
|
|
updateCustom(lv) {
|
|
this.data.customs = this.data.customs || [];
|
|
const i = this.data.customs.findIndex(l => l.id === lv.id);
|
|
if (i >= 0) this.data.customs[i] = lv;
|
|
else this.data.customs.push(lv);
|
|
this.flush();
|
|
return lv;
|
|
},
|
|
removeCustom(id) {
|
|
this.data.customs = (this.data.customs || []).filter(l => l.id !== id);
|
|
this.flush();
|
|
},
|
|
setAudio(on) { this.data.audio = on; this.flush(); },
|
|
};
|