Add map editor save and deploy actions
This commit is contained in:
@@ -10,6 +10,7 @@ const state = {
|
||||
imageLoading: new Set(),
|
||||
imageFailures: new Set(),
|
||||
previewLoadToken: 0,
|
||||
serverAvailable: false,
|
||||
history: [],
|
||||
dragging: null,
|
||||
};
|
||||
@@ -26,6 +27,7 @@ document.addEventListener("DOMContentLoaded", () => {
|
||||
function bindElements() {
|
||||
for (const id of [
|
||||
"mapCanvas", "fileInput", "loadSampleButton", "downloadButton", "undoButton",
|
||||
"saveProjectButton", "deployButton",
|
||||
"graphicFileInput",
|
||||
"mapIdInput", "worldWidthInput", "worldHeightInput", "gridSizeInput",
|
||||
"hitFilterInput",
|
||||
@@ -45,6 +47,8 @@ function bindEvents() {
|
||||
elements.fileInput.addEventListener("change", openFile);
|
||||
elements.graphicFileInput.addEventListener("change", importGraphicAsset);
|
||||
elements.downloadButton.addEventListener("click", saveAndDownloadMap);
|
||||
elements.saveProjectButton.addEventListener("click", saveProjectMap);
|
||||
elements.deployButton.addEventListener("click", deployProjectMap);
|
||||
elements.undoButton.addEventListener("click", undoLast);
|
||||
elements.deleteButton.addEventListener("click", deleteSelected);
|
||||
elements.moveLayerUpButton.addEventListener("click", () => moveSelectedLayer(-1));
|
||||
@@ -93,6 +97,26 @@ function bindEvents() {
|
||||
canvas.addEventListener("mouseup", onCanvasMouseUp);
|
||||
canvas.addEventListener("mouseleave", onCanvasMouseUp);
|
||||
canvas.addEventListener("wheel", onCanvasWheel, { passive: false });
|
||||
|
||||
detectServerFeatures();
|
||||
}
|
||||
|
||||
async function detectServerFeatures() {
|
||||
try {
|
||||
const response = await fetch("/api/map-editor/status", { cache: "no-store" });
|
||||
const data = response.ok ? await response.json() : null;
|
||||
state.serverAvailable = Boolean(data && data.writable);
|
||||
} catch (error) {
|
||||
state.serverAvailable = false;
|
||||
}
|
||||
updateServerButtons();
|
||||
}
|
||||
|
||||
function updateServerButtons() {
|
||||
elements.saveProjectButton.disabled = !state.serverAvailable;
|
||||
elements.deployButton.disabled = !state.serverAvailable;
|
||||
elements.saveProjectButton.title = state.serverAvailable ? "保存到 game/assets/map/stage_01.map" : "需要用 node tools/map_editor/server.js 启动编辑器";
|
||||
elements.deployButton.title = state.serverAvailable ? "保存并同步到已有 PC/Switch build 资源目录" : "需要用 node tools/map_editor/server.js 启动编辑器";
|
||||
}
|
||||
|
||||
async function loadSampleMap() {
|
||||
@@ -1120,6 +1144,42 @@ function saveAndDownloadMap() {
|
||||
setStatus(`已保存导出文本并下载 ${state.map.id || "stage"}.map`);
|
||||
}
|
||||
|
||||
async function saveProjectMap() {
|
||||
await writeMapToServer("/api/map-editor/save", "已保存到项目资源目录。");
|
||||
}
|
||||
|
||||
async function deployProjectMap() {
|
||||
await writeMapToServer("/api/map-editor/deploy", "已保存并部署到项目和已有 build 资源目录。");
|
||||
}
|
||||
|
||||
async function writeMapToServer(url, successPrefix) {
|
||||
if (!state.serverAvailable) {
|
||||
setStatus("当前是静态服务模式,不能直接写入项目文件。请用 node tools/map_editor/server.js 启动。");
|
||||
return;
|
||||
}
|
||||
|
||||
const mapText = serializeMap(state.map);
|
||||
elements.saveProjectButton.disabled = true;
|
||||
elements.deployButton.disabled = true;
|
||||
try {
|
||||
const response = await fetch(url, {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ mapText }),
|
||||
});
|
||||
const data = await response.json().catch(() => ({}));
|
||||
if (!response.ok || !data.ok) {
|
||||
throw new Error(data.error || `HTTP ${response.status}`);
|
||||
}
|
||||
const targets = Array.isArray(data.targets) ? data.targets.length : 0;
|
||||
setStatus(targets ? `${successPrefix} 写入 ${targets} 个文件。` : successPrefix);
|
||||
} catch (error) {
|
||||
setStatus(`保存失败:${error.message}`);
|
||||
} finally {
|
||||
updateServerButtons();
|
||||
}
|
||||
}
|
||||
|
||||
function undoLast() {
|
||||
const entry = state.history.pop();
|
||||
if (!entry) return;
|
||||
|
||||
Reference in New Issue
Block a user