diff --git a/_server/MotaAction.g4 b/_server/MotaAction.g4 index 22069f27..c316dfcc 100644 --- a/_server/MotaAction.g4 +++ b/_server/MotaAction.g4 @@ -595,6 +595,7 @@ return JSON.stringify(code); action : text_0_s | text_1_s + | text_2_s | comment_s | autoText_s | scrollText_s @@ -754,6 +755,85 @@ var code = '"'+title+EvalString_2+EvalString_3+'",\n'; return code; */; +text_2_s + : '标题' EvalString? '图像' EvalString? '对话框效果' EvalString? ':' EvalString BGNL? Newline textDrawingList* Newline + + +/* text_2_s +tooltip : text:显示一段文字(剧情),选项较多请右键点击帮助 +helpUrl : https://h5mota.com/games/template/_docs/#/event?id=text%EF%BC%9A%E6%98%BE%E7%A4%BA%E4%B8%80%E6%AE%B5%E6%96%87%E5%AD%97%EF%BC%88%E5%89%A7%E6%83%85%EF%BC%89 +doubleclicktext : EvalString_3 +allIds : ['EvalString_1'] +default : ["小妖精","fairy","","欢迎使用事件编辑器(双击方块进入多行编辑)",null] +var title=''; +if (EvalString_0==''){ + if (EvalString_1=='' )title=''; + else title='\\t['+EvalString_1+']'; +} else { + if (EvalString_1=='')title='\\t['+EvalString_0+']'; + else title='\\t['+EvalString_0+','+EvalString_1+']'; +} +if(EvalString_2 && !(/^(up|center|down|hero|this)(,(hero|null|\d+,\d+|\d+))?$/.test(EvalString_2))) { + throw new Error('对话框效果的用法请右键点击帮助'); +} +EvalString_2 = EvalString_2 && ('\\b['+EvalString_2+']'); +var code = '"'+title+EvalString_2+textDrawingList_0.replace(/\s/g, '')+EvalString_3+'",\n'; +return code; +*/; + +textDrawingList + : textDrawing + | textDrawingEmpty; + + +textDrawing + : '立绘' EvalString '翻转' Reverse_List '绘制坐标' 'x' IntString 'y' IntString '宽' IntString? '高' IntString? BGNL? Newline + '裁剪坐标' 'x' IntString? 'y' IntString? '宽' IntString? '高' IntString? '不透明度' EvalString? '旋转角度' IntString? + +/* textDrawing +tooltip : 立绘 +helpUrl : https://h5mota.com/games/template/_docs/#/event?id=drawImage%ef%bc%9a%e7%bb%98%e5%88%b6%e5%9b%be%e7%89%87 +default : ["fairy.png","null","0","0","","","","","","","",""] +colour : this.subColor +previewBlock : true +allImages : ['EvalString_0'] +if (Reverse_List_0 && Reverse_List_0 != 'null') EvalString_0 += Reverse_List_0; +var list = [EvalString_0, IntString_0, IntString_1]; +if (IntString_2 || IntString_3) { + if (list.length != 3 || !IntString_2 || !IntString_3) { + throw "绘制的宽和高需同时设置"; + } + list.push(IntString_2); + list.push(IntString_3); +} +if (IntString_4 || IntString_5 || IntString_6 || IntString_7) { + if (list.length != 5) throw "如设置裁剪区域,请先设置绘制区域的宽高"; + if (!IntString_4 || !IntString_5 || !IntString_6 || !IntString_7) { + throw "如设置裁剪区域,请同时设置全部的裁剪坐标和宽高"; + } + list.splice(1, 0, IntString_4, IntString_5, IntString_6, IntString_7); +} +if (EvalString_1) { + if (list.length != 9) throw "如设置不透明度,需填满所有坐标和宽高"; + var opacity = parseFloat(EvalString_1); + if (isNaN(opacity) || opacity < 0 || opacity > 1) throw "不合法的不透明度,必须是0到1之间" + list.push(opacity); +} +if (IntString_8) { + if (list.length != 10) throw "如设置旋转角度,需填满所有坐标和宽高,以及不透明度"; + list.push(IntString_8); +} +return "\\f[" + list.join(",")+"]"; +*/; + +textDrawingEmpty + : Newline + +/* textDrawingEmpty +var code = ''; +return code; +*/; + comment_s : '添加注释' ':' EvalString Newline @@ -1736,6 +1816,7 @@ helpUrl : https://h5mota.com/games/template/_docs/#/event?id=showImage%ef%bc%9a% default : [1,"bg.jpg","null","0","0",1,0,false] allImages : ['EvalString_0'] colour : this.printColor +previewBlock : true if(Int_0<=0 || Int_0>50) throw new Error('图片编号在1~50之间'); if (Reverse_List_0 && Reverse_List_0 != 'null') { Reverse_List_0 = ', "reverse": "' + Reverse_List_0 + '"'; @@ -1757,6 +1838,7 @@ helpUrl : https://h5mota.com/games/template/_docs/#/event?id=showImage%ef%bc%9a% default : [1,"bg.jpg","null","0","0","","",1,"0","0","","",0,false] allImages : ['EvalString_0'] colour : this.printColor +previewBlock : true if(Int_0<=0 || Int_0>50) throw new Error('图片编号在1~50之间'); if (Reverse_List_0 && Reverse_List_0 != 'null') { Reverse_List_0 = ', "reverse": "' + Reverse_List_0 + '"'; @@ -1814,6 +1896,7 @@ helpUrl : https://h5mota.com/games/template/_docs/#/event?id=showgif%EF%BC%9A%E6 default : ["","",""] allImages : ['EvalString_0'] colour : this.printColor +previewBlock : true EvalString_0 = EvalString_0 ? (', "name": "'+EvalString_0+'"') : ''; var loc = (PosString_0 && PosString_1) ? (', "loc": ['+PosString_0+','+PosString_1+']') : ''; var code = '{"type": "showGif"'+EvalString_0+loc+'},\n'; @@ -1849,6 +1932,7 @@ tooltip : setCurtain: 更改画面色调,动画时间可不填 helpUrl : https://h5mota.com/games/template/_docs/#/event?id=setcurtain%EF%BC%9A%E6%9B%B4%E6%94%B9%E7%94%BB%E9%9D%A2%E8%89%B2%E8%B0%83 default : ["255,255,255,1",'rgba(255,255,255,1)',500,true,false] colour : this.soundColor +previewBlock : true IntString_0 = IntString_0 ?(', "time": '+IntString_0):''; Bool_0 = Bool_0 ? ', "keep": true' : ''; var async = Bool_1?', "async": true':''; @@ -2006,6 +2090,7 @@ tooltip : playBgm: 播放背景音乐 helpUrl : https://h5mota.com/games/template/_docs/#/event?id=playbgm%EF%BC%9A%E6%92%AD%E6%94%BE%E8%83%8C%E6%99%AF%E9%9F%B3%E4%B9%90 default : ["bgm.mp3", 0, true] allBgms : ['EvalString_0'] +material : ["./project/bgms/", "EvalString_0"] colour : this.soundColor Int_0 = Int_0 ? (', "startTime": '+Int_0) : ''; Bool_0 = Bool_0 ? ', "keep": true' : ''; @@ -2047,6 +2132,7 @@ tooltip : loadBgm: 预加载某个背景音乐,之后可以直接播放 helpUrl : https://h5mota.com/games/template/_docs/#/event?id=loadBgm%ef%bc%9a%e9%a2%84%e5%8a%a0%e8%bd%bd%e4%b8%80%e4%b8%aa%e8%83%8c%e6%99%af%e9%9f%b3%e4%b9%90 default : ["bgm.mp3"] allBgms : ['EvalString_0'] +material : ["./project/bgms/", "EvalString_0"] colour : this.soundColor var code = '{"type": "loadBgm", "name": "'+EvalString_0+'"},\n'; return code; @@ -2076,6 +2162,7 @@ helpUrl : https://h5mota.com/games/template/_docs/#/event?id=playsound%EF%BC%9A% default : ["item.mp3",false] colour : this.soundColor allSounds : ['EvalString_0'] +material : ["./project/sounds/", "EvalString_0"] Bool_0 = Bool_0 ? ', "stop": true' : ''; var code = '{"type": "playSound", "name": "'+EvalString_0+'"'+Bool_0+'},\n'; return code; @@ -2943,7 +3030,7 @@ expression //todo 修改recieveOrder,根据Arithmetic_List_0不同的值设定不同的recieveOrder var code = expression_0 + Arithmetic_List_0 + expression_1; var ops = { - '^': 'Math.pow('+expression_0+','+expression_1+')' + '**': 'Math.pow('+expression_0+','+expression_1+')' } if (ops[Arithmetic_List_0])code = ops[Arithmetic_List_0]; var orders = { @@ -2951,6 +3038,7 @@ var orders = { '-': Blockly.JavaScript.ORDER_SUBTRACTION, '*': Blockly.JavaScript.ORDER_MULTIPLICATION, '/': Blockly.JavaScript.ORDER_DIVISION, + '%': Blockly.JavaScript.ORDER_MODULUS, '**': Blockly.JavaScript.ORDER_MEMBER, //recieveOrder : ORDER_COMMA '==': Blockly.JavaScript.ORDER_EQUALITY, '!=': Blockly.JavaScript.ORDER_EQUALITY, @@ -2961,7 +3049,8 @@ var orders = { '>=': Blockly.JavaScript.ORDER_RELATIONAL, '<=': Blockly.JavaScript.ORDER_RELATIONAL, '&&': Blockly.JavaScript.ORDER_LOGICAL_AND, - '||': Blockly.JavaScript.ORDER_LOGICAL_OR + '||': Blockly.JavaScript.ORDER_LOGICAL_OR, + '^': Blockly.JavaScript.ORDER_BITWISE_XOR } return [code, orders[Arithmetic_List_0]]; */; @@ -3158,12 +3247,12 @@ ShopUse_List /*ShopUse_List ['money','exp']*/; Arithmetic_List - : '加'|'减'|'乘'|'除'|'乘方'|'等于'|'不等于'|'大于'|'小于'|'大于等于'|'小于等于'|'且'|'或'|'弱等于'|'弱不等于' - /*Arithmetic_List ['+','-','*','/','**','===','!==','>','<','>=','<=','&&','||','==','!=']*/; + : '加'|'减'|'乘'|'除'|'取余'|'乘方'|'等于'|'不等于'|'大于'|'小于'|'大于等于'|'小于等于'|'且'|'或'|'异或'|'弱等于'|'弱不等于' + /*Arithmetic_List ['+','-','*','/','%','**','===','!==','>','<','>=','<=','&&','||','^','==','!=']*/; AssignOperator_List - : '='|'+='|'-='|'*='|'/='|'**='|'//='|'%=' - ; + : '设为'|'增加'|'减少'|'乘以'|'除以'|'乘方'|'除以并取商'|'除以并取余' + /*AssignOperator_List ['=','+=','-=','*=','/=','**=','//=','%=']*/; Weather_List : '无'|'雨'|'雪'|'雾' diff --git a/_server/MotaActionParser.js b/_server/MotaActionParser.js index ffa74fa7..7202bd61 100644 --- a/_server/MotaActionParser.js +++ b/_server/MotaActionParser.js @@ -210,7 +210,38 @@ ActionParser.prototype.parseAction = function() { return; case "text": // 文字/对话 var info = this.getTitleAndPosition(data.text); - if (info[0] || info[1] || info[2]) { + var textDrawing = []; + info[3] = (info[3] || "").replace(/(\f|\\f)\[(.*?)]/g, function (text, sympol, str) { + var ss = str.split(","); + if (ss.length == 3 || ss.length == 5 || ss.length >=9) { + var swap = function (i, j) { var x = ss[i]; ss[i] = ss[j]; ss[j] = x;} + if (ss.length >= 9) { + swap(1,5); swap(2,6); swap(3,7); swap(4,8); + } + textDrawing.push(ss); + } + return ''; + }); + if (textDrawing.length > 0) { + var buildTextDrawing = function (obj) { + if(!obj) obj=[]; + var text_choices = null; + for(var ii=obj.length-1,choice;choice=obj[ii];ii--) { + var reverse = 'null'; + if (choice[0].endsWith(':o') || choice[0].endsWith(':x') || choice[0].endsWith(':y')) { + reverse = choice[0].substring(choice[0].length - 2); + choice[0] = choice[0].substring(0, choice[0].length - 2); + } + text_choices=MotaActionBlocks['textDrawing'].xmlText([ + choice[0], reverse, choice[1], choice[2], choice[3], choice[4], choice[5], choice[6], + choice[7], choice[8], choice[9], choice[10], text_choices]); + } + return text_choices; + } + this.next = MotaActionBlocks['text_2_s'].xmlText([ + info[0], info[1], info[2], info[3], buildTextDrawing(textDrawing), this.next + ]); + } else if (info[0] || info[1] || info[2]) { this.next = MotaActionBlocks['text_1_s'].xmlText([ info[0], info[1], info[2], info[3], this.next]); } @@ -1154,7 +1185,7 @@ MotaActionFunctions.JsonEvalString_pre = function (JsonEvalString) { } MotaActionFunctions.IntString_pre = function (IntString) { - if (!/^\d*$/.test(IntString)) throw new Error('此项必须是整数或不填'); + if (!/^[+-]?\d*$/.test(IntString)) throw new Error('此项必须是整数或不填'); return IntString; } diff --git a/_server/editor_blockly.js b/_server/editor_blockly.js index 2924cb28..6f8e1843 100644 --- a/_server/editor_blockly.js +++ b/_server/editor_blockly.js @@ -234,18 +234,86 @@ editor_blockly = function () { if (b && MotaActionBlocks[b.type].previewBlock) { try { + // 特殊处理立绘 + if (b.type == 'textDrawing') { + var str = Blockly.JavaScript.blockToCode(b); + var list = str.substring(str.indexOf('[')+1, str.lastIndexOf(']')).split(","); + if (list.length == 3 || list.length == 5 || list.length >= 9) { + var arr = []; + var name = list[0]; + var obj = {"type": "drawImage"}; + if (name.endsWith(":o") || name.endsWith(":x") || name.endsWith(":y")) { + obj.reverse = name.substring(name.length-2); + name = name.substring(0, name.length - 2); + } + obj.image = name; + obj.x = parseFloat(list[1]); + obj.y = parseFloat(list[2]); + if (list.length >= 5) { + obj.w = parseFloat(list[3]); + obj.h = parseFloat(list[4]); + } + if (list.length >= 9) { + obj.x1 = parseFloat(list[5]); + obj.y1 = parseFloat(list[6]); + obj.w1 = parseFloat(list[7]); + obj.h1 = parseFloat(list[8]); + } + if (list.length >= 10) { + arr.push({"type": "setAttribute", "alpha": parseFloat(list[9])}); + } + if (list.length >= 11) { + obj.angle = parseFloat(list[10]); + } + arr.push(obj); + console.log(arr); + editor.uievent.previewUI(arr); + } + return true; + } + var code = "[" + Blockly.JavaScript.blockToCode(b).replace(/\\(i|c|d|e|z)/g, '\\\\$1') + "]"; eval("var obj="+code); - if (obj.length > 0 && b.type == 'waitContext_2') { - var dt = obj[0]; - editor.uievent.previewUI([{"type": "fillRect", "x": dt.px[0], "y": dt.py[0], - "width": "(" + dt.px[1] + ")-(" + dt.px[0] + ")", "height": "(" + dt.py[1] + ")-(" + dt.py[0] + ")", - "style": "rgba(255,0,0,0.5)"}]) - } - else if (obj.length > 0 && b.type.startsWith(obj[0].type)) { - if (b.type == 'previewUI_s') - editor.uievent.previewUI(obj[0].action); - else editor.uievent.previewUI([obj[0]]); + if (obj.length == 0) return true; + obj = obj[0]; + switch (b.type) { + case 'waitContext_2': // 等待用户操作坐标预览 + editor.uievent.previewUI([{"type": "fillRect", "x": obj.px[0], "y": obj.py[0], + "width": "(" + obj.px[1] + ")-(" + obj.px[0] + ")", "height": "(" + obj.py[1] + ")-(" + obj.py[0] + ")", + "style": "rgba(255,0,0,0.5)"}]); + break; + case 'showImage_s': // 显示图片 + case 'showImage_1_s': + if (obj.sloc) { + editor.uievent.previewUI([ + {type: "setAttribute", alpha: obj.opacity}, + {type: "drawImage", image: obj.image, x: obj.sloc[0], y: obj.sloc[1], w: obj.sloc[2], h: obj.sloc[3], + x1: obj.loc[0], y1: obj.loc[1], w1: obj.loc[2], h1: obj.loc[3], reverse: obj.reverse} + ]); + } else { + editor.uievent.previewUI([ + {type: "setAttribute", alpha: obj.opacity}, + {type: "drawImage", image: obj.image, x: obj.loc[0], y: obj.loc[1], w: obj.loc[2], h: obj.loc[3], reverse: obj.reverse} + ]); + } + break; + case 'showGif_s': // 显示动图 + if (obj.name && obj.loc) { + editor.uievent.previewUI([{type: "drawImage", image: obj.name, x: obj.loc[0], y: obj.loc[1]}]); + } + break; + case 'setCurtain_0_s': // 更改色调 + if (obj.color) { + editor.uievent.previewUI([{type: "fillRect", x: 0, y: 0, width: core.__PIXELS__, height: core.__PIXELS__, style: obj.color}]); + } + break; + case 'previewUI_s': // 预览 + editor.uievent.previewUI(obj.action); + break; + default: + if (b.type.startsWith(obj.type)) { + editor.uievent.previewUI([obj]); + } } } catch (e) {main.log(e);} return true; @@ -263,6 +331,19 @@ editor_blockly = function () { return; } + if (b && MotaActionBlocks[b.type].material) { + var material = JSON.parse(MotaActionBlocks[b.type].material); + console.log(material); + editor.uievent.selectMaterial([b.getFieldValue(material[1])], '请选择素材', material[0], function (one) { + return /^[-A-Za-z0-9_.]+$/.test(one) ? one : null; + }, function (value) { + if (value instanceof Array && value.length > 0) { + b.setFieldValue(value[0], material[1]); + } + }); + return; + } + var f = b ? MotaActionBlocks[b.type].doubleclicktext : null; if (f) { var value = b.getFieldValue(f); diff --git a/_server/editor_blocklyconfig.js b/_server/editor_blocklyconfig.js index 5961514a..179f0a56 100644 --- a/_server/editor_blocklyconfig.js +++ b/_server/editor_blocklyconfig.js @@ -87,6 +87,7 @@ editor_blocklyconfig=(function(){ '显示文字':[ MotaActionBlocks['text_0_s'].xmlText(), MotaActionBlocks['text_1_s'].xmlText(), + MotaActionFunctions.actionParser.parseList("\t[小妖精,fairy]\f[fairy.png,0,0]欢迎使用事件编辑器(双击方块进入多行编辑)"), MotaActionBlocks['comment_s'].xmlText(), MotaActionBlocks['autoText_s'].xmlText(), MotaActionBlocks['scrollText_s'].xmlText(), diff --git a/_server/editor_ui.js b/_server/editor_ui.js index 2412581f..49680762 100644 --- a/_server/editor_ui.js +++ b/_server/editor_ui.js @@ -568,7 +568,6 @@ editor_ui_wrapper = function (editor) { uievent.onKeyDown = function (e) { if (e.keyCode == 27) editor.uievent.close(); - else if (e.keyCode == 13) editor.uievent.confirm(); if (uievent.mode == 'selectPoint') { if (e.keyCode == 87) editor.uievent.move(0, -1) if (e.keyCode == 65) editor.uievent.move(-1, 0) diff --git a/libs/ui.js b/libs/ui.js index 4825563a..771708f8 100644 --- a/libs/ui.js +++ b/libs/ui.js @@ -1347,9 +1347,11 @@ ui.prototype._drawTextBox_drawImages = function (content) { core.drawImage('ui', ss[0], parseFloat(ss[1]), parseFloat(ss[2])); else if (ss.length==5) core.drawImage('ui', ss[0], parseFloat(ss[1]), parseFloat(ss[2]), parseFloat(ss[3]), parseFloat(ss[4])); - else if (ss.length==9 || ss.length==10) { - if (ss.length==10) core.setAlpha('ui', parseFloat(ss[9])); - core.drawImage('ui', ss[0], parseFloat(ss[1]), parseFloat(ss[2]), parseFloat(ss[3]), parseFloat(ss[4]), parseFloat(ss[5]), parseFloat(ss[6]), parseFloat(ss[7]), parseFloat(ss[8])); + else if (ss.length >= 9) { + if (ss.length >= 10) core.setAlpha('ui', parseFloat(ss[9])); + var angle = (parseFloat(ss[10]) || 0) * Math.PI / 180; + core.drawImage('ui', ss[0], parseFloat(ss[1]), parseFloat(ss[2]), parseFloat(ss[3]), parseFloat(ss[4]), + parseFloat(ss[5]), parseFloat(ss[6]), parseFloat(ss[7]), parseFloat(ss[8]), angle); core.setAlpha('ui', 1); } return ""; diff --git a/project/plugins.js b/project/plugins.js index e18ab765..44a805ee 100644 --- a/project/plugins.js +++ b/project/plugins.js @@ -350,6 +350,9 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = input.id = id; input.value = value; editor.dom[id] = input; + input.onchange = function () { + editor.uifunctions.setLayerMod(value); + } editor[value] = editor[value] || defaultMap; return input; }; @@ -391,37 +394,6 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = parent.insertBefore(input, parent.children[1]); parent.appendChild(input2); } - - var _isEditorInit = false; - - // 这里写编辑器复写的内容 有关游戏进程的函数复写请在下面复写 - var _afterEditorInit = function (callback) { - // 防止多次调用 - if (_isEditorInit) { - if (callback) callback(); - return; - } - _isEditorInit = true; - // 绑定onchange - editor.dom.layerMod4.onchange = function () { - editor.uifunctions.setLayerMod('bg2map'); - }; - editor.dom.layerMod5.onchange = function () { - editor.uifunctions.setLayerMod('fg2map'); - } - // 继续进行afterCoreReset - if (callback) callback(); - }; - // 将复写编辑器的内容插入changeFloor之后 afterCoreReset之前 - // 加载队列:int main => core => plugin(即plugin这个文件里的插件内容) => editor(此时才开始加载编辑器)=> afterMainInit - // => editor_file(此时才能开始复写编辑器内容) => changeFloor(在这里插入编辑器复写内容的加载) => afterCoreReset(此时才开始进行地图的绘制) - // 直接复写由于加载插件时 复写的editor函数还未加载 会导致出错 - var _changeFloor = core.events.changeFloor; - core.events.changeFloor = function (floorId, stair, heroLoc, time, callback) { - return _changeFloor.call(core.events, floorId, stair, heroLoc, time, function () { - _afterEditorInit(callback); - }); - }; } ////// 绘制背景层 ////// @@ -541,7 +513,7 @@ var plugins_bb40132b_638b_4a9f_b028_d3fe47acc8d1 = loc.forEach(function (t) { var x = t[0], y = t[1]; - var flag = [floorId, x, y, name+'_disable'].join('@'); + var flag = [floorId, x, y, name + '_disable'].join('@'); if (type == 'hide') core.setFlag(flag, true); else core.removeFlag(flag); });