285 lines
15 KiB
XML
285 lines
15 KiB
XML
{
|
||
"widgettype": "VBox",
|
||
"options": {
|
||
"width": "100%",
|
||
"height": "100%",
|
||
"css": "filler"
|
||
},
|
||
"subwidgets": [
|
||
{
|
||
"widgettype": "HBox",
|
||
"options": {
|
||
"padding": "8px 12px",
|
||
"gap": "8px",
|
||
"alignItems": "center",
|
||
"borderBottom": "1px solid #e5e7eb"
|
||
},
|
||
"subwidgets": [
|
||
{
|
||
"widgettype": "Text",
|
||
"options": {
|
||
"text": "🎮 游戏工作台",
|
||
"cfontsize": 1.2,
|
||
"fontWeight": "bold",
|
||
"halign": "left"
|
||
}
|
||
},
|
||
{
|
||
"widgettype": "Button",
|
||
"id": "wb_new_game",
|
||
"options": {
|
||
"label": "+ 新建游戏"
|
||
},
|
||
"binds": [
|
||
{
|
||
"wid": "self",
|
||
"event": "click",
|
||
"actiontype": "script",
|
||
"target": "self",
|
||
"script": "var pw=new bricks.PopupWindow({title:'新建游戏',cwidth:32,cheight:10,auto_open:true,id:'wb_ng_popup'});var vb=new bricks.VBox({padding:'12px',gap:'10px'});var inp=new bricks.UiText({name:'wb_ng_name',placeholder:'游戏名称',cwidth:28});var chk=new bricks.UiCheck({name:'wb_ng_shared',value:false,label:'世界共享'});vb.add_widget(inp);vb.add_widget(chk);var bt=new bricks.Button({label:'创建游戏',css:'primary'});bt.bind('click',function(){var n=inp.resultValue();if(!n||!n.trim())return;var b=new URLSearchParams();b.append('name',n.trim());b.append('description',chk.resultValue()?'shared':'independent');fetch('/scense_game/game/api/game_create.dspy',{method:'POST',body:b}).then(function(r){return r.json()}).then(function(r){var ms=bricks.getWidgetById('wb_msg',bricks.app);if(ms)ms.set_text(r.success?'✔ 游戏已创建,世界已自动建立':'✘ '+(r.message||'创建失败'));var w=bricks.getWidgetById('wb_ng_popup',bricks.app);if(w){w.dismiss();w.destroy()};var t=bricks.getWidgetById('wb_tree',bricks.app);if(t&&t.container){t.container.clear_widgets();t.get_children_data(t)}})});vb.add_widget(bt);pw.content_w.add_widget(vb);setTimeout(function(){var el=inp.dom_element?inp.dom_element.querySelector('input,textarea'):null;if(el)el.focus()},300)"
|
||
}
|
||
]
|
||
},
|
||
{
|
||
"widgettype": "Text",
|
||
"id": "wb_msg",
|
||
"options": {
|
||
"text": "选择对象树节点开始编程",
|
||
"color": "#6b7280",
|
||
"halign": "left"
|
||
}
|
||
},
|
||
{
|
||
"widgettype": "Filler"
|
||
},
|
||
{
|
||
"widgettype": "Button",
|
||
"id": "wb_test",
|
||
"options": {
|
||
"label": "▶ 测试(新窗口运行demo)",
|
||
"css": "primary"
|
||
},
|
||
"binds": [
|
||
{
|
||
"wid": "self",
|
||
"event": "click",
|
||
"actiontype": "script",
|
||
"target": "self",
|
||
"script": "var t=bricks.getWidgetById('wb_tree',bricks.app);var wid='';var gid='';if(t&&t.selected_node){var u=t.selected_node.user_data||{};gid=wb_state.game_id||'';if(u.obj_type==='world')wid=u.real_id;else{var w=t.container?null:null;var sel=t.selected_node;while(sel&&sel.parent_widget){if(sel.user_data&&sel.user_data.obj_type==='world'){wid=sel.user_data.real_id;break}sel=sel.parent_widget}}}if(!wid){var ms=bricks.getWidgetById('wb_msg',bricks.app);if(ms)ms.set_text('请先选中一个世界节点再测试');return}window.open('/scense_demo/demo_viewer.ui?world_id='+encodeURIComponent(wid)+'&game_id='+encodeURIComponent(gid),'_blank')"
|
||
}
|
||
]
|
||
}
|
||
]
|
||
},
|
||
{
|
||
"widgettype": "HBox",
|
||
"options": {
|
||
"css": "filler",
|
||
"width": "100%"
|
||
},
|
||
"subwidgets": [
|
||
{
|
||
"widgettype": "VBox",
|
||
"options": {
|
||
"width": "280px",
|
||
"borderRight": "1px solid #e5e7eb",
|
||
"padding": "8px"
|
||
},
|
||
"subwidgets": [
|
||
{
|
||
"widgettype": "HBox",
|
||
"options": {
|
||
"gap": "6px",
|
||
"alignItems": "center",
|
||
"marginBottom": "6px"
|
||
},
|
||
"subwidgets": [
|
||
{
|
||
"widgettype": "Text",
|
||
"options": {
|
||
"text": "对象树",
|
||
"fontWeight": "bold",
|
||
"halign": "left"
|
||
}
|
||
},
|
||
{
|
||
"widgettype": "Filler"
|
||
},
|
||
{
|
||
"widgettype": "Button",
|
||
"options": {
|
||
"label": "+场景",
|
||
"css": "small"
|
||
},
|
||
"binds": [
|
||
{
|
||
"wid": "self",
|
||
"event": "click",
|
||
"actiontype": "script",
|
||
"target": "self",
|
||
"params": {
|
||
"add_type": "scene",
|
||
"scene_id": "",
|
||
"hint": "新场景将加入当前游戏的世界下"
|
||
},
|
||
"script": "window.wb_state=window.wb_state||{};var wb_state=window.wb_state;window.wb_add_type=params.add_type;window.wb_add_scene_id=params.scene_id||'';var pw=new bricks.PopupWindow({title:params.add_type==='scene'?'添加场景':'添加实体',cwidth:28,cheight:8,auto_open:true,id:'wb_add_popup'});var vb=new bricks.VBox({padding:'12px',gap:'10px'});var inp=new bricks.UiText({name:'wb_add_name',placeholder:'输入名称',cwidth:24});vb.add_widget(new bricks.Text({text:params.hint,halign:'left'}));vb.add_widget(inp);var bt=new bricks.Button({label:'添加',css:'primary'});bt.bind('click',function(){window.wb_state=window.wb_state||{};var wb_state=window.wb_state;var inp=bricks.getWidgetById('wb_add_name',bricks.app);var name=inp?inp.resultValue():'';if(!name||!name.trim()){return}var b=new URLSearchParams();b.append('game_id',wb_state.game_id||'');b.append('scene_id',wb_add_scene_id||'');b.append('name',name.trim());var url=wb_add_type==='scene'?'/scense_game/game/api/scene_add.dspy':'/scense_game/game/api/entity_add.dspy';fetch(url,{method:'POST',body:b}).then(function(r){return r.json()}).then(function(r){var ms=bricks.getWidgetById('wb_msg',bricks.app);if(ms)ms.set_text(r.success?'✔ 已添加':'✘ '+(r.message||'添加失败'));var w=bricks.getWidgetById('wb_add_popup',bricks.app);if(w){w.dismiss();w.destroy()};var t=bricks.getWidgetById('wb_tree',bricks.app);if(t&&t.container){t.container.clear_widgets();t.get_children_data(t)}})});vb.add_widget(bt);pw.content_w.add_widget(vb);setTimeout(function(){var el=inp.dom_element?inp.dom_element.querySelector('input,textarea'):null;if(el)el.focus()},300)"
|
||
}
|
||
]
|
||
},
|
||
{
|
||
"widgettype": "Button",
|
||
"options": {
|
||
"label": "+实体",
|
||
"css": "small"
|
||
},
|
||
"binds": [
|
||
{
|
||
"wid": "self",
|
||
"event": "click",
|
||
"actiontype": "script",
|
||
"target": "self",
|
||
"params": {
|
||
"add_type": "entity",
|
||
"scene_id": "",
|
||
"hint": "选中场景节点则加入该场景,否则为世界级实体"
|
||
},
|
||
"script": "window.wb_state=window.wb_state||{};var wb_state=window.wb_state;window.wb_add_type=params.add_type;window.wb_add_scene_id=params.scene_id||'';var pw=new bricks.PopupWindow({title:params.add_type==='scene'?'添加场景':'添加实体',cwidth:28,cheight:8,auto_open:true,id:'wb_add_popup'});var vb=new bricks.VBox({padding:'12px',gap:'10px'});var inp=new bricks.UiText({name:'wb_add_name',placeholder:'输入名称',cwidth:24});vb.add_widget(new bricks.Text({text:params.hint,halign:'left'}));vb.add_widget(inp);var bt=new bricks.Button({label:'添加',css:'primary'});bt.bind('click',function(){window.wb_state=window.wb_state||{};var wb_state=window.wb_state;var inp=bricks.getWidgetById('wb_add_name',bricks.app);var name=inp?inp.resultValue():'';if(!name||!name.trim()){return}var b=new URLSearchParams();b.append('game_id',wb_state.game_id||'');b.append('scene_id',wb_add_scene_id||'');b.append('name',name.trim());var url=wb_add_type==='scene'?'/scense_game/game/api/scene_add.dspy':'/scense_game/game/api/entity_add.dspy';fetch(url,{method:'POST',body:b}).then(function(r){return r.json()}).then(function(r){var ms=bricks.getWidgetById('wb_msg',bricks.app);if(ms)ms.set_text(r.success?'✔ 已添加':'✘ '+(r.message||'添加失败'));var w=bricks.getWidgetById('wb_add_popup',bricks.app);if(w){w.dismiss();w.destroy()};var t=bricks.getWidgetById('wb_tree',bricks.app);if(t&&t.container){t.container.clear_widgets();t.get_children_data(t)}})});vb.add_widget(bt);pw.content_w.add_widget(vb);setTimeout(function(){var el=inp.dom_element?inp.dom_element.querySelector('input,textarea'):null;if(el)el.focus()},300)"
|
||
}
|
||
]
|
||
}
|
||
]
|
||
},
|
||
{
|
||
"widgettype": "VScrollPanel",
|
||
"options": {
|
||
"css": "filler"
|
||
},
|
||
"subwidgets": [
|
||
{
|
||
"widgettype": "Tree",
|
||
"id": "wb_tree",
|
||
"options": {
|
||
"dataurl": "{{entire_url('/scense_game/workbench/api/tree.dspy')}}",
|
||
"method": "POST",
|
||
"idField": "id",
|
||
"textField": "text",
|
||
"select_only": true,
|
||
"title": ""
|
||
},
|
||
"binds": [
|
||
{
|
||
"wid": "self",
|
||
"event": "node_selected",
|
||
"actiontype": "script",
|
||
"target": "self",
|
||
"script": "window.wb_state=window.wb_state||{};var wb_state=window.wb_state;var t=bricks.getWidgetById('wb_tree',bricks.app);if(!event.params||!event.params.id)return;var ot=event.params.obj_type||'';var oid=event.params.real_id||'';var lbl=bricks.getWidgetById('wb_cur_obj',bricks.app);if(lbl)lbl.set_text(({'game':'🎮 游戏','world':'🌍 世界','scene':'🎬 场景','entity':'📦 实体'})[ot]+' · '+event.params.text);wb_state.obj_type=ot;wb_state.obj_id=oid;wb_state.game_id=(ot==='game')?oid:(event.params.game_id||wb_state.game_id);var es=bricks.getWidgetById('wb_event_sel',bricks.app);var evt=es?es.resultValue():'event_start';if(!oid)return;var b=new URLSearchParams();b.append('obj_type',ot);b.append('obj_id',oid);b.append('trigger_event',evt);fetch('/scense_game/workbench/api/load_script.dspy',{method:'POST',body:b}).then(function(r){return r.json()}).then(function(r){var ed=bricks.getWidgetById('wb_code',bricks.app);if(ed&&r.success){ed.set_value(r.data?r.data.content:'')}})"
|
||
}
|
||
]
|
||
}
|
||
]
|
||
}
|
||
]
|
||
},
|
||
{
|
||
"widgettype": "VBox",
|
||
"options": {
|
||
"css": "filler",
|
||
"padding": "10px",
|
||
"gap": "8px"
|
||
},
|
||
"subwidgets": [
|
||
{
|
||
"widgettype": "HBox",
|
||
"options": {
|
||
"gap": "10px",
|
||
"alignItems": "center"
|
||
},
|
||
"subwidgets": [
|
||
{
|
||
"widgettype": "Text",
|
||
"id": "wb_cur_obj",
|
||
"options": {
|
||
"text": "未选择对象",
|
||
"fontWeight": "bold",
|
||
"halign": "left"
|
||
}
|
||
},
|
||
{
|
||
"widgettype": "UiCode",
|
||
"id": "wb_event_sel",
|
||
"options": {
|
||
"name": "wb_event_sel",
|
||
"data": [
|
||
{
|
||
"value": "event_start",
|
||
"text": "事件:开始"
|
||
},
|
||
{
|
||
"value": "event_click",
|
||
"text": "事件:点击"
|
||
},
|
||
{
|
||
"value": "event_timer",
|
||
"text": "事件:定时"
|
||
},
|
||
{
|
||
"value": "event_collision",
|
||
"text": "事件:碰撞"
|
||
}
|
||
],
|
||
"valueField": "value",
|
||
"textField": "text",
|
||
"cwidth": 10
|
||
}
|
||
},
|
||
{
|
||
"widgettype": "Filler"
|
||
},
|
||
{
|
||
"widgettype": "Button",
|
||
"options": {
|
||
"label": "校验"
|
||
},
|
||
"binds": [
|
||
{
|
||
"wid": "self",
|
||
"event": "click",
|
||
"actiontype": "script",
|
||
"target": "self",
|
||
"script": "var ms=bricks.getWidgetById('wb_msg',bricks.app);var ed=bricks.getWidgetById('wb_code',bricks.app);var code=ed?ed.get_value():'';var b=new URLSearchParams();b.append('content',code);fetch('/script_engine/api/validate_script.dspy',{method:'POST',body:b}).then(function(r){return r.json()}).then(function(r){if(ms)ms.set_text(r.success!==false?'✔ 语法校验通过':'✘ '+(r.error||r.message||'校验失败'))})"
|
||
}
|
||
]
|
||
},
|
||
{
|
||
"widgettype": "Button",
|
||
"options": {
|
||
"label": "💾 保存脚本",
|
||
"css": "primary"
|
||
},
|
||
"binds": [
|
||
{
|
||
"wid": "self",
|
||
"event": "click",
|
||
"actiontype": "script",
|
||
"target": "self",
|
||
"script": "window.wb_state=window.wb_state||{};var wb_state=window.wb_state;var ms=bricks.getWidgetById('wb_msg',bricks.app);if(!wb_state.obj_id){if(ms)ms.set_text('先在左侧树选择对象');return}var es=bricks.getWidgetById('wb_event_sel',bricks.app);var evt=es?es.resultValue():'event_start';var ed=bricks.getWidgetById('wb_code',bricks.app);var code=ed?ed.get_value():'';var b=new URLSearchParams();b.append('obj_type',wb_state.obj_type);b.append('obj_id',wb_state.obj_id);b.append('game_id',wb_state.game_id||'');b.append('trigger_event',evt);b.append('content',code);fetch('/scense_game/workbench/api/save_script.dspy',{method:'POST',body:b}).then(function(r){return r.json()}).then(function(r){if(ms)ms.set_text(r.success?'✔ 脚本已保存':'✘ '+(r.message||'保存失败'))})"
|
||
}
|
||
]
|
||
}
|
||
]
|
||
},
|
||
{
|
||
"widgettype": "CodeEditor",
|
||
"id": "wb_code",
|
||
"options": {
|
||
"css": "filler",
|
||
"mode": "python",
|
||
"value": "# 选择左侧对象后,为它的事件编写逻辑脚本"
|
||
}
|
||
}
|
||
]
|
||
}
|
||
]
|
||
}
|
||
]
|
||
} |