fea: 添加地图管理

This commit is contained in:
cancerai committed 2026-10-22 23:16:27 +08:00
1 parent cc2883458c
commit 22157d4baa
7 files changed
+201 -44

No files matched your search

+57 -37
View File
@@ -65,7 +65,6 @@ export const Editor = {
this.bind();
$('#ed-w').addEventListener('change', () => this.resize(+$('#ed-w').value, +$('#ed-h').value));
$('#ed-h').addEventListener('change', () => this.resize(+$('#ed-w').value, +$('#ed-h').value));
this.renderMyLevels();
},
buildPalette() {
@@ -133,6 +132,8 @@ export const Editor = {
on('ed-clear', () => { if (typeof confirm === 'function' && !confirm('清空当前面?')) return; const f = this.curFace(); f.grid = blank(f.w, f.h); f.doors = []; f.props = propsBlank(f.w, f.h); this.selTile = null; this.draw(); this.renderProps(); });
on('ed-test', () => this.test());
on('ed-save', () => this.save());
on('ed-import', () => this.openImport());
on('ed-import-cancel', () => this.closeImport());
on('ed-addface', () => this.addFace());
on('ed-copyface', () => this.copyFace());
on('ed-delface', () => this.delFace());
@@ -142,18 +143,33 @@ export const Editor = {
curFace() { return this.faces[this.face]; },
open() {
if (!this.faces) {
const w = +$('#ed-w').value || 25, h = +$('#ed-h').value || 19;
this.faces = [{ name: '面1', w, h, seq: 0, grid: blank(w, h), doors: [], props: propsBlank(w, h) }];
this.face = 0;
}
// 从菜单进入编辑器:始终是新地图(宽高沿用输入框里的值)
const w = +$('#ed-w').value || 25, h = +$('#ed-h').value || 19;
this.faces = [{ name: '面1', w, h, seq: 0, grid: blank(w, h), doors: [], props: propsBlank(w, h) }];
this.face = 0;
this.cur = null; // 未关联任何已存地图 → 首次保存为新建
this.show();
},
/** 仅重绘当前状态(不从零重置):用于试玩后「返回编辑器」等场景,保留正在编辑的地图 */
show() {
if (!this.faces) { this.open(); return; }
this.selTile = null;
$('#ed-w').value = this.curFace().w;
$('#ed-h').value = this.curFace().h;
this.draw();
this.renderFaces();
this.renderProps();
this.renderMyLevels();
this.updateSaveState();
},
/** 「保存」按钮旁的提示:会更新哪张图,还是另存为新图 */
updateSaveState() {
const el = $('#ed-savestate');
if (!el) return;
const l = this.cur ? Save.customs().find(o => o.id === this.cur) : null;
el.textContent = l ? '→ 更新「' + (l.name || 'MY MAP') + '」' : '→ 另存为新图';
el.classList.toggle('on', !!l);
},
resize(w, h) {
@@ -408,41 +424,45 @@ export const Editor = {
save() {
const err = this.validate();
if (err) { alert(err); return; }
const lv = makeCustomLevel(this.buildData());
Save.addCustom(lv);
let lv = makeCustomLevel(this.buildData());
if (this.cur) lv.id = this.cur; // 保存当前地图:沿用已有 id,就地更新
Save.updateCustom(lv);
this.cur = lv.id;
this.renderMyLevels();
this.updateSaveState();
this.api.refresh?.();
},
// ---------------- 我的关卡 ----------------
renderMyLevels() {
const box = $('#my-levels');
// ---------------- 导入地图(从已保存的地图里选) ----------------
openImport() {
const box = $('#ed-importbox');
if (!box) return;
box.innerHTML = '';
const list = Save.customs();
if (!list.length) box.innerHTML = '<div style="color:#666;font-size:.8em">还没有保存的关卡</div>';
list.forEach((l, i) => {
const d = document.createElement('div');
const fn = (l.faces || []).length;
d.className = 'my-lv' + (l.id === this.cur ? ' on' : '');
d.innerHTML = `<span>${i + 1}. ${escapeHtml(l.name)}${fn ? ` <b style="color:#a86bff">[${fn}面]</b>` : ''}</span><span class="x">✕</span>`;
d.querySelector('span').onclick = () => {
this.cur = l.id;
this.hydrate(l);
$('#ed-name').value = l.name || '';
this.afterFaceSwitch();
this.renderMyLevels();
};
d.querySelector('.x').onclick = (e) => {
e.stopPropagation();
if (typeof confirm === 'function' && !confirm('删除 ' + l.name + '?')) return;
Save.removeCustom(l.id);
this.renderMyLevels();
this.api.refresh?.();
};
box.appendChild(d);
});
const list = $('#ed-import-list');
const customs = Save.customs();
list.innerHTML = '';
if (!customs.length) {
list.innerHTML = '<div class="imp-empty">还没有保存过的地图,先「保存」一个吧</div>';
} else {
customs.forEach(l => {
const fn = (l.faces || []).length;
const d = document.createElement('div');
d.className = 'imp-row' + (l.id === this.cur ? ' on' : '');
d.innerHTML = `<span class="imp-nm">${escapeHtml(l.name || 'MY MAP')}</span><span class="imp-meta">${fn ? fn + ' 面' : '单关'}</span>`;
d.onclick = () => this.pickImport(l.id);
list.appendChild(d);
});
}
box.classList.remove('hidden');
},
closeImport() { $('#ed-importbox')?.classList.add('hidden'); },
pickImport(id) {
const l = Save.customs().find(o => o.id === id);
if (!l) return;
this.cur = l.id;
this.hydrate(l);
$('#ed-name').value = l.name || '';
this.closeImport();
this.afterFaceSwitch();
this.updateSaveState();
},
// 从存档/数据对象恢复多面 + 每格属性(按扫描顺序回填 messages/turrets/camzones/bosses)