editor_blockly = function () { var editor_blockly = {}; initscript = String.raw` (function(){ var getCategory = function(name){ for(var node of document.getElementById('toolbox').children) { if(node.getAttribute('name')==name) return node; } var node = document.createElement('category'); node.setAttribute('name',name); document.getElementById('toolbox').appendChild(node); return node; } var toolboxObj = { '入口方块':[ MotaActionFunctions.actionParser.parse([ "欢迎使用事件编辑器", "本事件触发一次后会消失", {"type": "hide", "time": 500}, ],'event'), MotaActionBlocks['changeFloor_m'].xmlText(), //MotaActionFunctions.actionParser.parse({"type": "choices", "choices": [ // {"text": "攻击+\${point}", "action": [ // {"type": "setValue", "name": "status:atk", "value": "status:atk+\${point}"}, // ]}, // {"text": "防御+\${2*point}", "action": [ // {"type": "setValue", "name": "status:def", "value": "status:def+\${2*point}"}, // ]}, // {"text": "生命+\${200*point}", "action": [ // {"type": "setValue", "name": "status:hp", "value": "status:hp+\${200*point}"}, // ]}, //]},'point'), MotaActionFunctions.actionParser.parse([{ "id": "moneyShop1", "name": "贪婪之神", "icon": "blueShop", "textInList": "1F金币商店", "use": "money", "need": "20+10*times*(times+1)", "text": "勇敢的武士啊,给我\${need}金币就可以:", "choices": [ {"text": "生命+800", "effect": "status:hp+=800"}, {"text": "攻击+4", "effect": "status:atk+=4"}, {"text": "防御+4", "effect": "status:def+=4"}, {"text": "魔防+10", "effect": "status:mdef+=10"} ] }],'shop'), MotaActionBlocks['afterBattle_m'].xmlText(), MotaActionBlocks['afterGetItem_m'].xmlText(), MotaActionBlocks['afterOpenDoor_m'].xmlText(), MotaActionBlocks['firstArrive_m'].xmlText(), MotaActionBlocks['level_m'].xmlText(), ], '显示文字':[ MotaActionBlocks['text_0_s'].xmlText(), MotaActionBlocks['text_1_s'].xmlText(), MotaActionBlocks['comment_s'].xmlText(), MotaActionFunctions.actionParser.parseList({"type": "choices", "text": "是否跳过剧情", "choices": [ {"text": "是", "action": []}, {"text": "否", "action": [ {"type": "autoText", "text": "\\t[小妖精,fairy]双击方块进入多行编辑\\n用户无法跳过自动剧情文本,大段剧情文本请添加“是否跳过剧情”的提示\\n自动剧情文本\\n自动剧情文本\\n自动剧情文本", "time" :3000}, {"type": "autoText", "text": "(可以右键方块后点复制)", "time" :3000}, ]}, ]}), MotaActionBlocks['setText_s'].xmlText(), MotaActionBlocks['showImage_0_s'].xmlText(), MotaActionBlocks['animateImage_0_s'].xmlText(), MotaActionBlocks['animateImage_1_s'].xmlText(), MotaActionBlocks['showImage_1_s'].xmlText(), MotaActionBlocks['showGif_0_s'].xmlText(), MotaActionBlocks['showGif_1_s'].xmlText(), MotaActionBlocks['moveImage_0_s'].xmlText(), MotaActionBlocks['tip_s'].xmlText(), MotaActionBlocks['win_s'].xmlText(), MotaActionBlocks['lose_s'].xmlText(), MotaActionBlocks['choices_s'].xmlText([ '选择剑或者盾','流浪者','man',MotaActionBlocks['choicesContext'].xmlText([ '剑',MotaActionFunctions.actionParser.parseList([{"type": "openDoor", "loc": [3,3]}]), MotaActionBlocks['choicesContext'].xmlText([ '盾',MotaActionFunctions.actionParser.parseList([{"type": "openDoor", "loc": [9,3]}]), ]) ]) ]), ], '数据相关':[ MotaActionBlocks['setValue_s'].xmlText([ MotaActionBlocks['idString_1_e'].xmlText(['status','hp']) ]), MotaActionBlocks['setFloor_s'].xmlText(), MotaActionBlocks['input_s'].xmlText(), MotaActionBlocks['input2_s'].xmlText(), MotaActionBlocks['update_s'].xmlText(), MotaActionBlocks['updateEnemys_s'].xmlText(), MotaActionBlocks['moveHero_s'].xmlText(), MotaActionBlocks['jumpHero_s'].xmlText(), MotaActionBlocks['changeFloor_s'].xmlText(), MotaActionBlocks['changePos_0_s'].xmlText(), MotaActionBlocks['changePos_1_s'].xmlText(), MotaActionBlocks['battle_s'].xmlText(), MotaActionBlocks['openDoor_s'].xmlText(), MotaActionBlocks['openShop_s'].xmlText(), MotaActionBlocks['setBlock_s'].xmlText(), MotaActionBlocks['setHeroIcon_s'].xmlText(), MotaActionBlocks['follow_s'].xmlText(), MotaActionBlocks['unfollow_s'].xmlText(), ], '事件控制':[ MotaActionBlocks['if_s'].xmlText(), MotaActionFunctions.actionParser.parseList({"type": "switch", "condition": "判别值", "caseList": [ {"action": [{"type": "comment", "text": "当判别值是值的场合执行此事件"}]}, {"action": []}, {"case": "default", "action": [{"type": "comment", "text": "当没有符合的值的场合执行default事件"}]}, ]}), MotaActionBlocks['while_s'].xmlText(), MotaActionBlocks['break_s'].xmlText(), MotaActionBlocks['continue_s'].xmlText(), MotaActionBlocks['revisit_s'].xmlText(), MotaActionBlocks['exit_s'].xmlText(), MotaActionBlocks['show_s'].xmlText(), MotaActionBlocks['hide_s'].xmlText(), MotaActionBlocks['showFloorImg_s'].xmlText(), MotaActionBlocks['hideFloorImg_s'].xmlText(), MotaActionBlocks['showBgFgMap_s'].xmlText(), MotaActionBlocks['hideBgFgMap_s'].xmlText(), MotaActionBlocks['setBgFgBlock_s'].xmlText(), MotaActionBlocks['trigger_s'].xmlText(), MotaActionBlocks['insert_s'].xmlText(), MotaActionBlocks['move_s'].xmlText(), MotaActionBlocks['jump_s'].xmlText(), MotaActionBlocks['disableShop_s'].xmlText(), ], '特效/声音':[ MotaActionBlocks['sleep_s'].xmlText(), MotaActionBlocks['wait_s'].xmlText(), MotaActionBlocks['viberate_s'].xmlText(), MotaActionBlocks['animate_s'].xmlText(), MotaActionBlocks['setFg_0_s'].xmlText(), MotaActionBlocks['setFg_1_s'].xmlText(), MotaActionBlocks['setWeather_s'].xmlText(), MotaActionBlocks['playBgm_s'].xmlText(), MotaActionBlocks['pauseBgm_s'].xmlText(), MotaActionBlocks['resumeBgm_s'].xmlText(), MotaActionBlocks['playSound_s'].xmlText(), MotaActionBlocks['setVolume_s'].xmlText(), ], '原生脚本':[ MotaActionBlocks['function_s'].xmlText(), ], '值块':[ MotaActionBlocks['setValue_s'].xmlText([ MotaActionBlocks['idString_1_e'].xmlText(['status','hp']) ]), MotaActionBlocks['expression_arithmetic_0'].xmlText(), MotaActionBlocks['negate_e'].xmlText(), MotaActionBlocks['bool_e'].xmlText(), MotaActionBlocks['idString_e'].xmlText(), MotaActionBlocks['idString_1_e'].xmlText(), MotaActionBlocks['idString_2_e'].xmlText(), MotaActionBlocks['evalString_e'].xmlText(), ], '常见事件模板':[ '', MotaActionFunctions.actionParser.parseList({"type": "if", "condition": "!core.musicStatus.bgmStatus", "true": [ "\t[系统提示]你当前音乐处于关闭状态,本塔开音乐游戏效果更佳" ], "false": [] }), '', MotaActionFunctions.actionParser.parse([ {"type": "choices", "text": "\t[老人,man]少年,你需要钥匙吗?\n我这里有大把的!", "choices": [ {"text": "黄钥匙(\${9+flag:shop_times}金币)", "action": [ {"type": "if", "condition": "status:money>=9+flag:shop_times", "true": [ {"type": "setValue", "name": "status:money", "value": "status:money-(9+flag:shop_times)"}, {"type": "setValue", "name": "item:yellowKey", "value": "item:yellowKey+1"}, ], "false": [ "\t[老人,man]你的金钱不足!", {"type": "revisit"} ] } ]}, {"text": "蓝钥匙(\${18+2*flag:shop_times}金币)", "action": [ ]}, {"text": "离开", "action": [ {"type": "exit"} ]} ] }, {"type": "setValue", "name": "flag:shop_times", "value": "flag:shop_times+1"}, {"type": "revisit"} ], 'event'), '', MotaActionFunctions.actionParser.parse({ "trigger": "action", "displayDamage": true, "data": [ ' ... 战前剧情', {"type": "battle", "id": "greenSlime"}, ' ... 战后剧情;请注意上面的强制战斗不会使怪物消失', '需要下一句来调用{"type": "hide"}来隐藏事件', {"type": "hide"}, ] },'event'), '', MotaActionFunctions.actionParser.parse([ '怪物变成了黄钥匙(黄钥匙idnum是21)', '打怪变成可对话的NPC: https://ckcz123.github.io/mota-js/#/event?id=%e6%89%93%e6%80%aa%e5%8f%98%e6%88%90%e5%8f%af%e5%af%b9%e8%af%9d%e7%9a%84npc%ef%bc%88%e6%80%aa%e7%89%a9-gtnpc%ef%bc%89', {"type": "setBlock", "number": 21} ],'afterBattle'), '', MotaActionFunctions.actionParser.parse([ {"type": "setValue", "name": "flag:__door__", "value": "flag:__door__+1"}, {"type": "if", "condition": "flag:__door__==2", "true": [ {"type": "openDoor", "loc": [10,5]} ], "false": [] }, ],'afterBattle'), '', MotaActionFunctions.actionParser.parse([ {"type": "function", "function": "function(){var x=core.status.event.data.x,y=core.status.event.data.y;if(core.isset(x)&&core.isset(y)){core.insertAction([{type:'hide',loc:[[x-1,y-2],[x,y-2],[x+1,y-2],[x-1,y-1],[x,y-1],[x+1,y-1],[x-1,y],[x+1,y]]}]);}}"}, ],'afterBattle'), '', MotaActionFunctions.actionParser.parse({ "trigger": "action", "noPass": true, "data": [ {"type": "if", "condition": "flag:hasSuperPotion", "true": [], "false": [ {"type":"setValue", "name":"status:hp", "value":"status:hp*2"}, {"type":"setBlock", "number": 1}, {"type":"setValue", "name":"flag:hasSuperPotion", "value": "true"} ] } ] },'event'), ], } var toolboxgap = '' //xml_text = MotaActionFunctions.actionParser.parse(obj,type||'event') //MotaActionBlocks['idString_e'].xmlText() for (var name in toolboxObj){ getCategory(name).innerHTML = toolboxObj[name].join(toolboxgap); } var blocklyArea = document.getElementById('blocklyArea'); var blocklyDiv = document.getElementById('blocklyDiv'); var workspace = Blockly.inject(blocklyDiv,{ media: '_server/blockly/media/', toolbox: document.getElementById('toolbox'), zoom:{ controls: true, wheel: false,//滚轮改为上下(shift:左右)翻滚 startScale: 1.0, maxScale: 3, minScale: 0.3, scaleSpeed: 1.08 }, trashcan: false, }); var onresize = function(e) { blocklyDiv.style.width = blocklyArea.offsetWidth + 'px'; blocklyDiv.style.height = blocklyArea.offsetHeight + 'px'; Blockly.svgResize(workspace); }; if(typeof editor !== "undefined" && !editor.isMobile)window.addEventListener('resize', onresize, false); onresize(); //Blockly.svgResize(workspace); //Blockly.bindEventWithChecks_(workspace.svgGroup_,"wheel",workspace,function(e){}); document.getElementById('blocklyDiv').onmousewheel = function(e){ //console.log(e); e.preventDefault(); var hvScroll = e.shiftKey?'hScroll':'vScroll'; workspace.scrollbar[hvScroll].handlePosition_+=( ((e.deltaY||0)+(e.detail||0)) >0?20:-20); workspace.scrollbar[hvScroll].onScroll_(); workspace.setScale(workspace.scale); } var doubleClickCheck=[[0,'abc']]; function omitedcheckUpdateFunction(event) { if(event.type==='ui'){ var newClick = [new Date().getTime(),event.blockId]; var lastClick = doubleClickCheck.shift(); doubleClickCheck.push(newClick); if(newClick[0]-lastClick[0]<500){ if(newClick[1]===lastClick[1]){ editor_blockly.doubleClickBlock(newClick[1]); } } } if(editor_blockly.workspace.topBlocks_.length>=2){ codeAreaHL.setValue('入口方块只能有一个'); return; } var eventType = document.getElementById('entryType').value; if(editor_blockly.workspace.topBlocks_.length==1){ var blockType = editor_blockly.workspace.topBlocks_[0].type; if(blockType!==eventType+'_m'){ codeAreaHL.setValue('入口方块类型错误'); return; } } try { var code = Blockly.JavaScript.workspaceToCode(workspace); codeAreaHL.setValue(code); } catch (error) { codeAreaHL.setValue(String(error)); if (error instanceof OmitedError){ var blockName = error.blockName; var varName = error.varName; var block = error.block; } // console.log(error); } } workspace.addChangeListener(omitedcheckUpdateFunction); workspace.addChangeListener(Blockly.Events.disableOrphans); editor_blockly.workspace = workspace; MotaActionFunctions.workspace = function(){ return editor_blockly.workspace; } })(); `; var input_ = ''; editor_blockly.runOne = function () { //var printf = console.log; //var printf = function(){}; var grammerFile = input_; converter = new Converter().init(); converter.generBlocks(grammerFile); //printf(converter.blocks); converter.renderGrammerName(); //converter.generToolbox(); converter.generMainFile(); //printf(converter.mainFile.join('')); //console.log(converter); var script = document.createElement('script'); //var initscript = document.getElementById('initscript').innerText; script.innerHTML = converter.mainFile[5] + initscript; document.body.appendChild(script); } var xhr = new XMLHttpRequest(); xhr.onreadystatechange = function () { if (xhr.readyState != 4) return; if (xhr.status != 200) { alert("无法在file://下加载"); return; } input_ = xhr.responseText; editor_blockly.runOne(); } xhr.open('GET', '_server/blockly/MotaAction.g4', true); xhr.send(null); codeAreaHL = CodeMirror.fromTextArea(document.getElementById("codeArea"), { lineNumbers: true, matchBrackets: true, lineWrapping: true, continueComments: "Enter", extraKeys: {"Ctrl-Q": "toggleComment"} }); editor_blockly.showXML = function () { var xml = Blockly.Xml.workspaceToDom(editor_blockly.workspace); var xml_text = Blockly.Xml.domToPrettyText(xml); console.log(xml_text); var xml_text = Blockly.Xml.domToText(xml); console.log(xml_text); console.log(xml); } editor_blockly.runCode = function () { // Generate JavaScript code and run it. window.LoopTrap = 1000; Blockly.JavaScript.INFINITE_LOOP_TRAP = 'if (--window.LoopTrap == 0) throw "Infinite loop.";\n'; var code = Blockly.JavaScript.workspaceToCode(editor_blockly.workspace); Blockly.JavaScript.INFINITE_LOOP_TRAP = null; try { eval('obj=' + code); console.log(obj); } catch (e) { alert(e); } } editor_blockly.parse = function () { MotaActionFunctions.parse( eval('obj=' + codeAreaHL.getValue().replace(/[<>&]/g, function (c) { return {'<': '<', '>': '>', '&': '&'}[c]; })), document.getElementById('entryType').value ); } editor_blockly.id = ''; editor_blockly.import = function (id_, args) { var thisTr = document.getElementById(id_); if (!thisTr) return false; var input = thisTr.children[2].children[0].children[0]; var field = thisTr.children[0].getAttribute('title'); var type = args.type; if (!type) return false; editor_blockly.id = id_; codeAreaHL.setValue(input.value.replace(/\\r/g,'\\\\r')); document.getElementById('entryType').value = type; editor_blockly.parse(); editor_blockly.show(); return true; } var blocklyWidgetDiv = document.getElementsByClassName('blocklyWidgetDiv'); editor_blockly.show = function () { if (typeof(selectBox) !== typeof(undefined)) selectBox.isSelected = false; document.getElementById('left6').style = ''; for (var ii = 0, node; node = blocklyWidgetDiv[ii]; ii++) { node.style.zIndex = 201; node.style.opacity = ''; } } editor_blockly.hide = function () { document.getElementById('left6').style = 'z-index:-1;opacity: 0;'; for (var ii = 0, node; node = blocklyWidgetDiv[ii]; ii++) { node.style.zIndex = -1; node.style.opacity = 0; } } editor_blockly.cancel = function () { editor_blockly.id = ''; editor_blockly.hide(); } editor_blockly.confirm = function () { if (!editor_blockly.id) { editor_blockly.id = ''; return; } if(editor_blockly.workspace.topBlocks_.length>=2){ codeAreaHL.setValue('入口方块只能有一个'); return; } var eventType = document.getElementById('entryType').value; if(editor_blockly.workspace.topBlocks_.length==1){ var blockType = editor_blockly.workspace.topBlocks_[0].type; if(blockType!==eventType+'_m'){ codeAreaHL.setValue('入口方块类型错误'); return; } } var setvalue = function (value) { var thisTr = document.getElementById(editor_blockly.id); editor_blockly.id = ''; var input = thisTr.children[2].children[0].children[0]; input.value = value; editor_blockly.hide(); input.onchange(); } if (codeAreaHL.getValue() === '') { eventType==='shop'?setvalue('[]'):setvalue('null'); return; } var code = Blockly.JavaScript.workspaceToCode(editor_blockly.workspace); eval('var obj=' + code); setvalue(JSON.stringify(obj)); } editor_blockly.doubleClickBlock = function (blockId) { var b = editor_blockly.workspace.getBlockById(blockId); //console.log(b); var textStringDict = { 'text_0_s': 'EvalString_0', 'text_1_s': 'EvalString_2', 'autoText_s': 'EvalString_2', 'comment_s': 'EvalString_0', 'choices_s': 'EvalString_0', 'function_s': 'RawEvalString_0', 'shopsub': 'EvalString_3', } var f = b ? textStringDict[b.type] : null; if (f) { var value = b.getFieldValue(f); //多行编辑 editor_multi.multiLineEdit(value, b, f, {'lint': f === 'RawEvalString_0'}, function (newvalue, b, f) { if (textStringDict[b.type] !== 'RawEvalString_0') { } b.setFieldValue(newvalue.split('\n').join('\\n'), f); }); } } return editor_blockly; } //editor_blockly=editor_blockly();