diff --git a/wwwroot/workbench/workbench.html b/wwwroot/workbench/workbench.html new file mode 100644 index 0000000..54a1b1a --- /dev/null +++ b/wwwroot/workbench/workbench.html @@ -0,0 +1,64 @@ + + + + +元景 · 游戏工作台 + + + +
+

🎮 游戏工作台

+ + + + + +
+
+
+

对象树(世界 1 · 场景 N · 实体 N)

+
加载中…
+
+
+
+ 未选择对象 + + + +
+ +
+
+
+ + + diff --git a/wwwroot/workbench/workbench.js b/wwwroot/workbench/workbench.js new file mode 100644 index 0000000..3cf8314 --- /dev/null +++ b/wwwroot/workbench/workbench.js @@ -0,0 +1,143 @@ +/* 元景游戏工作台:game 聚合根单页编辑器 */ +(function () { + function api(path, params) { + return fetch(path, { + method: 'POST', + headers: {'Content-Type': 'application/json'}, + body: JSON.stringify(params || {}) + }).then(function (r) { return r.json(); }); + } + function base() { return '/scense_game'; } + + var state = { game: null, data: null, sel: null }; // sel: {type, id, name} + + function msg(t, ok) { + var el = document.getElementById('msg'); + el.textContent = t; + el.className = ok ? 'ok' : 'err'; + } + + function saveGame() { + var name = document.getElementById('game_name').value.trim(); + if (state.game) { msg('游戏已存在: ' + state.game.id, true); return; } + if (!name) { msg('先填游戏名称', false); return; } + api(base() + '/game/api/game_create.dspy', {name: name, + description: document.getElementById('game_shared').checked ? 'shared' : 'independent'}) + .then(function (r) { + if (r.success) { msg('游戏创建成功,世界已自动建立', true); reload(); } + else msg(r.message || '创建失败', false); + }); + } + + function reload() { + // 列表取第一个 game 或新建后带入 + api(base() + '/game/api/game_list.dspy', {}).then(function (r) { + var games = (r.data && r.data.games) || []; + if (!games.length) { state.game = null; renderTree(null); return; } + var gid = games[0].game_id || games[0].id; + api(base() + '/game/api/game_workbench.dspy', {game_id: gid}).then(function (w) { + if (!w.success) { msg(w.message, false); return; } + state.game = w.data.game; state.data = w.data; + document.getElementById('game_name').value = (w.data.game && w.data.game.name) || ''; + renderTree(w.data); + if (!state.sel) selectWorld(); + else loadSel(); + }); + }); + } + + function renderTree(d) { + var el = document.getElementById('tree_body'); + if (!d || !d.world) { el.innerHTML = '
尚无游戏,先填名称保存
'; return; } + var h = ''; + h += '
🌍 ' + esc(d.world.name) + '
'; + (d.scenes || []).forEach(function (s) { + h += '
🎬 ' + esc(s.name) + '
'; + }); + h += '
+ 场景
'; + (d.entities || []).forEach(function (e) { + h += '
📦 ' + esc(e.name) + (e.scene_id ? '' : '(世界级)') + '
'; + }); + h += '
+ 实体
'; + el.innerHTML = h; + } + function esc(s) { return String(s || '').replace(/'/g, "\\'").replace(/