From 6f75c878a06c2577cf18a875f3ee650c1cd2a871 Mon Sep 17 00:00:00 2001 From: oc Date: Wed, 19 Jun 2019 23:17:54 +0800 Subject: [PATCH 01/34] Fix uievent bugs & fillCircle --- _docs/event.md | 20 ++++++++++++++ _server/MotaAction.g4 | 53 ++++++++++++++++++++++++++++++++++++ _server/editor_blockly.js | 31 ++++++++++++++++----- _server/editor_unsorted_1.js | 2 ++ _server/editor_unsorted_3.js | 4 +++ libs/events.js | 10 +++++++ libs/ui.js | 38 +++++++++++++++++++++++++- 7 files changed, 150 insertions(+), 8 deletions(-) diff --git a/_docs/event.md b/_docs/event.md index 9c40d646..98fe65e9 100644 --- a/_docs/event.md +++ b/_docs/event.md @@ -2088,6 +2088,26 @@ UI绘制事件。此事件可以绘制一个多边形边框。 参数列表和`fillPolygon`基本相同,不过多了一个`lineWidth`表示的绘制线宽。 +### fillCircle:绘制圆 + +UI绘制事件。此项可以绘制一个圆。 + +```js +[ + {"type": "fillCircle", "x": 100, "y": 100, "r": 10, "style": [255,0,0,1]} +] +``` + +x, y, r必填,为要绘制的圆心和半径;也可以用`flag:xxx`。 + +color可选,表示绘制时的颜色,为三元组RGB或四元组RGBA。 + +### strokeCircle:绘制圆边框 + +UI绘制事件。此项可以绘制一个圆边框。 + +参数列表和`fillCircle`基本相同,不过多了一个`lineWidth`表示的绘制线宽。 + ### drawImage:绘制图片 UI绘制事件。此事件可以绘制一个图片。 diff --git a/_server/MotaAction.g4 b/_server/MotaAction.g4 index b6c5c19c..58007978 100644 --- a/_server/MotaAction.g4 +++ b/_server/MotaAction.g4 @@ -354,6 +354,8 @@ action | drawArrow_s | fillPolygon_s | strokePolygon_s + | fillCircle_s + | strokeCircle_s | drawImage_s | drawImage_1_s | drawIcon_s @@ -2168,6 +2170,45 @@ var code = '{"type": "strokePolygon", "nodes": ['+EvalString_0+']'+EvalString_2+ return code; */; +fillCircle_s + : '绘制圆' '圆心' 'x' PosString 'y' PosString '半径' PosString '颜色' EvalString? Colour Newline + +/* fillCircle_s +tooltip : fillCircle:绘制圆 +helpUrl : https://h5mota.com/games/template/_docs/#/event?id=fillCircle%ef%bc%9a%e7%bb%98%e5%88%b6%e5%9c%86 +colour : this.subColor +default : ["0","0","100","",null] +var colorRe = MotaActionFunctions.pattern.colorRe; +if (EvalString_0) { + if (!colorRe.test(EvalString_0))throw new Error('颜色格式错误,形如:0~255,0~255,0~255,0~1'); + EvalString_0 = ', "style": ['+EvalString_0+']'; +} +var code = '{"type": "fillCircle", "x": '+PosString_0+', "y": '+PosString_1+', "r": '+PosString_2+EvalString_0+'},\n'; +return code; +*/; + +strokeCircle_s + : '绘制圆边框' '圆心' 'x' PosString 'y' PosString '半径' PosString '颜色' EvalString? Colour '线宽' EvalString? Newline + +/* strokeCircle_s +tooltip : strokeCircle:绘制圆边框 +helpUrl : https://h5mota.com/games/template/_docs/#/event?id=strokeCircle%ef%bc%9a%e7%bb%98%e5%88%b6%e5%9c%86%e8%be%b9%e6%a1%86 +colour : this.subColor +default : ["0","0","100","",null,""] +var colorRe = MotaActionFunctions.pattern.colorRe; +if (EvalString_0) { + if (!colorRe.test(EvalString_0))throw new Error('颜色格式错误,形如:0~255,0~255,0~255,0~1'); + EvalString_0 = ', "style": ['+EvalString_0+']'; +} +if (EvalString_1) { + if (!/^\d+$/.test(EvalString_1))throw new Error('线宽必须是整数或不填'); + EvalString_1 = ', "lineWidth": '+EvalString_1; +} +var code = '{"type": "strokeCircle", "x": '+PosString_0+', "y": '+PosString_1+', "r": '+PosString_2+EvalString_0+EvalString_1+'},\n'; +return code; +*/; + + drawImage_s : '绘制图片' EvalString '起点像素' 'x' PosString 'y' PosString '宽' PosString? '高' PosString? Newline @@ -3314,6 +3355,18 @@ ActionParser.prototype.parseAction = function() { x_str.join(','), y_str.join(','), data.style, 'rgba('+data.style+')', data.lineWidth, this.next ]); break; + case "fillCircle": // 绘制圆 + data.style = this.Colour(data.style); + this.next = MotaActionBlocks['fillCircle_s'].xmlText([ + data.x, data.y, data.r, data.style, 'rgba('+data.style+')', this.next + ]); + break; + case "strokeCircle": // 绘制圆边框 + data.style = this.Colour(data.style); + this.next = MotaActionBlocks['strokeCircle_s'].xmlText([ + data.x, data.y, data.r, data.style, 'rgba('+data.style+')', data.lineWidth, this.next + ]); + break; case "drawImage": // 绘制图片 if (data.x1 != null && data.y1 != null && data.w1 != null && data.h1 != null) { this.next = MotaActionBlocks['drawImage_1_s'].xmlText([ diff --git a/_server/editor_blockly.js b/_server/editor_blockly.js index 83e56a95..f89f36bf 100644 --- a/_server/editor_blockly.js +++ b/_server/editor_blockly.js @@ -183,6 +183,8 @@ editor_blockly = function () { MotaActionBlocks['drawArrow_s'].xmlText(), MotaActionBlocks['fillPolygon_s'].xmlText(), MotaActionBlocks['strokePolygon_s'].xmlText(), + MotaActionBlocks['fillCircle_s'].xmlText(), + MotaActionBlocks['strokeCircle_s'].xmlText(), MotaActionBlocks['drawImage_s'].xmlText(), MotaActionBlocks['drawImage_1_s'].xmlText(), MotaActionBlocks['drawIcon_s'].xmlText(), @@ -610,20 +612,35 @@ function omitedcheckUpdateFunction(event) { setvalue(JSON.stringify(obj)); } - editor_blockly.doubleClickBlock = function (blockId) { - var b = editor_blockly.workspace.getBlockById(blockId); - // console.log(Blockly.JavaScript.blockToCode(b)); - if (b && b.type == 'previewUI_s') { // previewUI + var previewBlock = function (b) { + var types = [ + "previewUI_s", "clearMap_s", "clearMap_1_s", "setAttribute_s", "fillText_s", + "fillBoldText_s", "drawTextContent_s", "fillRect_s", "strokeRect_s", "drawLine_s", + "drawArrow_s", "fillPolygon_s", "strokePolygon_s", "fillCircle_s", "strokeCircle_s", + "drawImage_s", "drawImage_1_s", "drawIcon_s", "drawBackground_s", "drawSelector_s", "drawSelector_1_s" + ]; + if (b && types.indexOf(b.type)>=0) { try { var code = "[" + Blockly.JavaScript.blockToCode(b).replace(/\\i/g, '\\\\i') + "]"; eval("var obj="+code); // console.log(obj); - if (obj.length > 0 && obj[0].type == 'previewUI') { - uievent.previewUI(obj[0].action); + if (obj.length > 0 && b.type.startsWith(obj[0].type)) { + if (b.type == 'previewUI_s') + uievent.previewUI(obj[0].action); + else uievent.previewUI(obj); } } catch (e) {main.log(e);} - return; + return true; } + return false; + } + + editor_blockly.doubleClickBlock = function (blockId) { + var b = editor_blockly.workspace.getBlockById(blockId); + console.log(Blockly.JavaScript.blockToCode(b)); + + if (previewBlock(b)) return; + if (b && b.type in selectPointBlocks) { // selectPoint this.selectPoint(); return; diff --git a/_server/editor_unsorted_1.js b/_server/editor_unsorted_1.js index 91f754c7..73955ab2 100644 --- a/_server/editor_unsorted_1.js +++ b/_server/editor_unsorted_1.js @@ -362,6 +362,7 @@ editor.constructor.prototype.listen=function () { reDo = JSON.parse(JSON.stringify(currDrawData)); currDrawData = {pos: [], info: {}}; editor.preMapData = null; + return; } //Ctrl+y 重做一步redo if (e.keyCode == 89 && e.ctrlKey && reDo && reDo.pos.length && selectBox.isSelected()) { @@ -372,6 +373,7 @@ editor.constructor.prototype.listen=function () { editor.updateMap(); currDrawData = JSON.parse(JSON.stringify(reDo)); reDo = null; + return; } // PGUP和PGDOWN切换楼层 diff --git a/_server/editor_unsorted_3.js b/_server/editor_unsorted_3.js index b0adaa5c..c0b5ad82 100644 --- a/_server/editor_unsorted_3.js +++ b/_server/editor_unsorted_3.js @@ -508,6 +508,10 @@ uievent.elements.selectFloor.onchange = function () { uievent.setPoint(uievent.elements.selectFloor.value); } +uievent.elements.selectPointBox.onclick = function (e) { + e.stopPropagation(); +} + uievent.elements.body.onclick = function (e) { if (uievent.mode != 'selectPoint') return; uievent.values.x = uievent.values.left + Math.floor(e.offsetX / uievent.values.size); diff --git a/libs/events.js b/libs/events.js index 0461d567..8326714d 100644 --- a/libs/events.js +++ b/libs/events.js @@ -1660,6 +1660,16 @@ events.prototype._action_strokePolygon = function (data, x, y, prefix) { core.doAction(); } +events.prototype._action_fillCircle = function (data, x, y, prefix) { + core.ui._uievent_fillCircle(data); + core.doAction(); +} + +events.prototype._action_strokeCircle = function (data, x, y, prefix) { + core.ui._uievent_strokeCircle(data); + core.doAction(); +} + events.prototype._action_drawLine = function (data, x, y, prefix) { core.ui._uievent_drawLine(data); core.doAction(); diff --git a/libs/ui.js b/libs/ui.js index 25391dbe..47fbc876 100644 --- a/libs/ui.js +++ b/libs/ui.js @@ -189,6 +189,37 @@ ui.prototype._uievent_strokePolygon = function (data) { this.strokePolygon('uievent', data.nodes, data.style, data.lineWidth); } +////// 在某个canvas上绘制一个圆 ////// +ui.prototype.fillCircle = function (name, x, y, r, style) { + if (style) core.setFillStyle(name, style); + var ctx = this.getContextByName(name); + if (!ctx) return; + ctx.beginPath(); + ctx.arc(x, y, r, 0, 2*Math.PI); + ctx.fill(); +} + +ui.prototype._uievent_fillCircle = function (data) { + this._createUIEvent(); + this.fillCircle('uievent', core.calValue(data.x), core.calValue(data.y), core.calValue(data.r), data.style); +} + +////// 在某个canvas上绘制一个圆的边框 ////// +ui.prototype.strokeCircle = function (name, x, y, r, style, lineWidth) { + if (style) core.setStrokeStyle(name, style); + if (lineWidth) core.setLineWidth(name, lineWidth); + var ctx = this.getContextByName(name); + if (!ctx) return; + ctx.beginPath(); + ctx.arc(x, y, r, 0, 2*Math.PI); + ctx.stroke(); +} + +ui.prototype._uievent_strokeCircle = function (data) { + this._createUIEvent(); + this.strokeCircle('uievent', core.calValue(data.x), core.calValue(data.y), core.calValue(data.r), data.style, data.lineWidth); +} + ////// 在某个canvas上绘制一条线 ////// ui.prototype.drawLine = function (name, x1, y1, x2, y2, style, lineWidth) { if (style) core.setStrokeStyle(name, style); @@ -395,7 +426,12 @@ ui.prototype.drawIcon = function (name, id, x, y, w, h) { ui.prototype._uievent_drawIcon = function (data) { this._createUIEvent(); - this.drawIcon('uievent', data.id, core.calValue(data.x), core.calValue(data.y), core.calValue(data.width), core.calValue(data.height)); + var id; + try { + id = core.calValue(data.id); + if (typeof id !== 'string') id = data.id; + } catch (e) { id = data.id; } + this.drawIcon('uievent', id, core.calValue(data.x), core.calValue(data.y), core.calValue(data.width), core.calValue(data.height)); } ///////////////// UI绘制 From 4a960790c316885cfda0518eead67e52da1af989 Mon Sep 17 00:00:00 2001 From: oc Date: Fri, 28 Jun 2019 16:36:20 +0800 Subject: [PATCH 02/34] syntax error in editor & B in replay --- _server/editor_multi.js | 11 +++++++++++ libs/actions.js | 7 ++++--- libs/control.js | 1 + libs/ui.js | 17 ++++++++++++++--- 4 files changed, 30 insertions(+), 6 deletions(-) diff --git a/_server/editor_multi.js b/_server/editor_multi.js index 069855cc..ecfd6b7d 100644 --- a/_server/editor_multi.js +++ b/_server/editor_multi.js @@ -81,6 +81,12 @@ editor_multi = function () { _format(); } + editor_multi.hasError = function () { + if (!editor_multi.lintAutocomplete) return false; + return JSHINT.errors.filter(function (e) { + return e.code.startsWith("E") + }).length > 0; + } editor_multi.import = function (id_, args) { var thisTr = document.getElementById(id_); @@ -126,6 +132,11 @@ editor_multi = function () { } editor_multi.confirm = function () { + if (editor_multi.hasError()) { + alert("当前好像存在严重的语法错误,请处理后再保存。\n严重的语法错误可能会导致整个编辑器的崩溃。"); + return; + } + if (!editor_multi.id) { editor_multi.id = ''; return; diff --git a/libs/actions.js b/libs/actions.js index f6f80541..7fd5951f 100644 --- a/libs/actions.js +++ b/libs/actions.js @@ -112,9 +112,8 @@ actions.prototype.doRegisteredAction = function (action) { } actions.prototype._checkReplaying = function () { - if (core.isReplaying() && core.status.event.id != 'save' - && (core.status.event.id || "").indexOf('book') != 0 && core.status.event.id != 'viewMaps' - && core.status.event.id != 'toolbox' && core.status.event.id != 'equipbox') + if (core.isReplaying() && + ['save','book','book-detail','viewMaps','toolbox','equipbox','text'].indexOf(core.status.event.id)<0) return true; return false; } @@ -175,6 +174,8 @@ actions.prototype._sys_onkeyUp_replay = function (e) { core.toolboxReplay(); else if (e.keyCode == 81) // Q core.equipboxReplay(); + else if (e.keyCode == 66) // B + core.drawStatistics(); else if (e.keyCode >= 49 && e.keyCode <= 51) // 1-3 core.setReplaySpeed(e.keyCode - 48); else if (e.keyCode == 52) // 4 diff --git a/libs/control.js b/libs/control.js index 54201a90..7476d52c 100644 --- a/libs/control.js +++ b/libs/control.js @@ -1202,6 +1202,7 @@ control.prototype.bookReplay = function () { if (core.isMoving() || core.status.replay.animate || (core.status.event.id && core.status.event.id != 'viewMaps')) return core.drawTip("请等待当前事件的处理结束"); + if (!core.hasItem('book')) return core.drawTip('你没有怪物手册'); // 从“浏览地图”页面打开 if (core.status.event.id=='viewMaps') diff --git a/libs/ui.js b/libs/ui.js index 47fbc876..94c9bbdd 100644 --- a/libs/ui.js +++ b/libs/ui.js @@ -539,7 +539,8 @@ ui.prototype.drawText = function (contents, callback) { ui.prototype._drawText_setContent = function (contents, callback) { // 合并进 insertAction - if ((core.status.event && core.status.event.id=='action') || core.isReplaying()) { + if ((core.status.event && core.status.event.id=='action') + || (!core.hasFlag('__replayText__') && core.isReplaying())) { core.insertAction(contents,null,null,callback); return; } @@ -1866,11 +1867,19 @@ ui.prototype._drawBookDetail_turnAndCriticals = function (enemy, floorId, texts) var damageInfo = core.getDamageInfo(enemy, null, null, null, floorId); texts.push("战斗回合数:"+((damageInfo||{}).turn||0)); // 临界表 - var criticals = core.enemys.nextCriticals(enemy, 10, null, null, floorId).map(function (v) { + var criticals = core.enemys.nextCriticals(enemy, 8, null, null, floorId).map(function (v) { return core.formatBigNumber(v[0])+":"+core.formatBigNumber(v[1]); }); while (criticals[0]=='0:0') criticals.shift(); - texts.push("临界表:"+JSON.stringify(criticals)) + texts.push("临界表:"+JSON.stringify(criticals)); + var prevInfo = core.getDamageInfo(enemy, {atk: core.status.hero.atk-1}, null, null, floorId); + if (prevInfo != null && damageInfo != null) { + if (damageInfo.damage != null) damageInfo = damageInfo.damage; + if (prevInfo.damage != null) prevInfo = prevInfo.damage; + if (prevInfo > damageInfo) { + texts.push("(当前攻击力正位于临界点上)") + } + } } ui.prototype._drawBookDetail_drawContent = function (enemy, contents, pos) { @@ -2564,6 +2573,7 @@ ui.prototype.drawStatistics = function (floorIds) { core.ui._drawStatistics_floorId(floorId, obj); }); var statistics = core.status.hero.statistics; + core.setFlag("__replayText__", true); core.drawText([ this._drawStatistics_generateText(obj, "全塔", obj.total), this._drawStatistics_generateText(obj, "当前", obj.current), @@ -2581,6 +2591,7 @@ ui.prototype.drawStatistics = function (floorIds) { "4. 在自定义道具(例如其他宝石)后,需在脚本编辑的drawStatistics中注册,不然不会进行统计。\n"+ "5. 所有统计信息仅供参考,如有错误,概不负责。" ]) + core.removeFlag("__replayText__"); } ui.prototype._drawStatistics_buildObj = function () { From f36970a7853a62e4bab5c4c0a707abd84c18d4e6 Mon Sep 17 00:00:00 2001 From: oc Date: Fri, 28 Jun 2019 16:52:25 +0800 Subject: [PATCH 03/34] \f alpha & wait mousewheel --- libs/actions.js | 10 ++++++++++ libs/ui.js | 5 ++++- libs/utils.js | 2 ++ 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/libs/actions.js b/libs/actions.js index 7fd5951f..3814f333 100644 --- a/libs/actions.js +++ b/libs/actions.js @@ -718,6 +718,16 @@ actions.prototype._sys_onmousewheel = function (direct) { return; } + // wait事件 + if (core.status.lockControl && core.status.event.id == 'action' && core.status.event.data.type == 'wait') { + core.setFlag('type', 0); + var keycode = direct == 1 ? 33 : 34; + core.setFlag('keycode', keycode); + core.status.route.push("input:" + keycode); + core.doAction(); + return; + } + } ////// 长按Ctrl键时 ////// diff --git a/libs/ui.js b/libs/ui.js index 94c9bbdd..1961425e 100644 --- a/libs/ui.js +++ b/libs/ui.js @@ -1090,8 +1090,11 @@ ui.prototype._drawTextBox_drawImages = function (content) { core.drawImage('ui', img, parseFloat(ss[1]), parseFloat(ss[2])); else if (ss.length==5) core.drawImage('ui', img, 0, 0, img.width, img.height, parseFloat(ss[1]), parseFloat(ss[2]), parseFloat(ss[3]), parseFloat(ss[4])); - else if (ss.length==9) + else if (ss.length==9 || ss.length==10) { + if (ss.length==10) core.setAlpha('ui', parseFloat(ss[9])); core.drawImage('ui', img, parseFloat(ss[1]), parseFloat(ss[2]), parseFloat(ss[3]), parseFloat(ss[4]), parseFloat(ss[5]), parseFloat(ss[6]), parseFloat(ss[7]), parseFloat(ss[8])); + core.setAlpha('ui', 1); + } return ""; }); } diff --git a/libs/utils.js b/libs/utils.js index c3d9dd38..4378dca5 100644 --- a/libs/utils.js +++ b/libs/utils.js @@ -915,6 +915,7 @@ utils.prototype.myconfirm = function (hint, yesCallback, noCallback) { main.dom.inputMessage.innerHTML = hint.replace(/\n/g, '
'); main.dom.inputBox.style.display = 'none'; main.dom.inputYes.focus(); + core.status.holdingKeys = []; core.platform.successCallback = yesCallback; core.platform.errorCallback = noCallback; @@ -929,6 +930,7 @@ utils.prototype.myprompt = function (hint, value, callback) { setTimeout(function () { main.dom.inputBox.focus(); }); + core.status.holdingKeys = []; core.platform.successCallback = core.platform.errorCallback = callback; } From 43c12e55f1d80146592c2efbc9a9787bcb536882 Mon Sep 17 00:00:00 2001 From: oc Date: Fri, 28 Jun 2019 17:23:09 +0800 Subject: [PATCH 04/34] flyRecordPosition --- _docs/event.md | 5 ++++- _server/MotaAction.g4 | 4 ++-- _server/table/data.comment.js | 8 +++++++- libs/maps.js | 9 ++++++--- project/data.js | 1 + project/functions.js | 32 ++++++++++++++++++++++---------- 6 files changed, 42 insertions(+), 17 deletions(-) diff --git a/_docs/event.md b/_docs/event.md index 98fe65e9..51330cc4 100644 --- a/_docs/event.md +++ b/_docs/event.md @@ -258,6 +258,8 @@ 其基本写法是`\f[img,x,y]`,或者`\f[img,x,y,w,h]`,或者`\f[img,sx,sy,sw,sh,x,y,w,h]`。 +从V2.6.3开始,也可以在最后加上alpha值,即`\f[img,sx,sy,sw,sh,x,y,w,h,alpha]`。 + 需要注意的是,这个图片是绘制在UI层上的,下一个事件执行时即会擦除;同时如果使用了\t的图标动画效果,重叠的地方也会被图标动画给覆盖掉。 ``` js @@ -265,7 +267,8 @@ "\t[勇士]\b[up,hero]\f[1.png,100,100]以(100,100)为左上角绘制1.png图片", "\t[hero]\f[1.png,100,100]\f[2.png,300,300]同时绘制了两张图片", "\f[1.png,100,100,300,300]也可以填写宽高,这样会把图片强制进行放缩到指定的宽高值", - "\f[1.png,64,64,128,128,100,100,128,128]裁剪1.png上以(64,64)开始的128x128图片,并绘制到画布的(100,100)处" + "\f[1.png,64,64,128,128,100,100,128,128]裁剪1.png上以(64,64)开始的128x128图片,并绘制到画布的(100,100)处", + "\f[1.png,64,64,128,128,100,100,128,128,0.5]同上,不透明度0.5", ] ``` diff --git a/_server/MotaAction.g4 b/_server/MotaAction.g4 index 58007978..92a7a378 100644 --- a/_server/MotaAction.g4 +++ b/_server/MotaAction.g4 @@ -2536,8 +2536,8 @@ Global_Value_List Global_Flag_List - : '显示当前楼层'|'显示勇士图标'|'显示当前等级'|'启用生命上限'|'显示魔力值'|'显示魔防值'|'显示金币值'|'显示经验值'|'允许等级提升'|'升级扣除模式'|'显示钥匙数量'|'显示破炸飞'|'显示毒衰咒'|'显示当前技能'|'楼梯边才能楼传'|'破墙镐四方向'|'炸弹四方向'|'冰冻徽章四方向'|'铁门不需要钥匙'|'开启加点'|'开启负伤'|'仇恨怪战后扣减一半'|'夹击是否上整'|'夹击不超伤害值'|'循环计算临界'|'允许轻按'|'寻路算法不绕血瓶'|'允许走到将死领域'|'允许瞬间移动'|'允许查看禁用商店'|'阻激夹域后禁用快捷商店'|'检查控制台' - /*Global_Flag_List ['enableFloor','enableName','enableLv', 'enableHPMax', 'enableMana', 'enableMDef', 'enableMoney', 'enableExperience', 'enableLevelUp', 'levelUpLeftMode', 'enableKeys', 'enablePZF', 'enableDebuff', 'enableSkill', 'flyNearStair', 'pickaxeFourDirections', 'bombFourDirections', 'snowFourDirections', 'steelDoorWithoutKey', 'enableAddPoint', 'enableNegativeDamage', 'hatredDecrease', 'betweenAttackCeil', 'betweenAttackMax', 'useLoop', 'enableGentleClick', 'potionWhileRouting', 'canGoDeadZone', 'enableMoveDirectly', 'enableDisabledShop', 'disableShopOnDamage', 'checkConsole']*/; + : '显示当前楼层'|'显示勇士图标'|'显示当前等级'|'启用生命上限'|'显示魔力值'|'显示魔防值'|'显示金币值'|'显示经验值'|'允许等级提升'|'升级扣除模式'|'显示钥匙数量'|'显示破炸飞'|'显示毒衰咒'|'显示当前技能'|'楼梯边才能楼传'|'楼传平面塔模式'|'破墙镐四方向'|'炸弹四方向'|'冰冻徽章四方向'|'铁门不需要钥匙'|'开启加点'|'开启负伤'|'仇恨怪战后扣减一半'|'夹击是否上整'|'夹击不超伤害值'|'循环计算临界'|'允许轻按'|'寻路算法不绕血瓶'|'允许走到将死领域'|'允许瞬间移动'|'允许查看禁用商店'|'阻激夹域后禁用快捷商店'|'检查控制台' + /*Global_Flag_List ['enableFloor','enableName','enableLv', 'enableHPMax', 'enableMana', 'enableMDef', 'enableMoney', 'enableExperience', 'enableLevelUp', 'levelUpLeftMode', 'enableKeys', 'enablePZF', 'enableDebuff', 'enableSkill', 'flyNearStair', 'flyRecordPosition', 'pickaxeFourDirections', 'bombFourDirections', 'snowFourDirections', 'steelDoorWithoutKey', 'enableAddPoint', 'enableNegativeDamage', 'hatredDecrease', 'betweenAttackCeil', 'betweenAttackMax', 'useLoop', 'enableGentleClick', 'potionWhileRouting', 'canGoDeadZone', 'enableMoveDirectly', 'enableDisabledShop', 'disableShopOnDamage', 'checkConsole']*/; Colour : 'sdeirughvuiyasdeb'+ //为了被识别为复杂词法规则 diff --git a/_server/table/data.comment.js b/_server/table/data.comment.js index 2a2addfd..f6457473 100644 --- a/_server/table/data.comment.js +++ b/_server/table/data.comment.js @@ -515,7 +515,13 @@ var data_comment_c456ea59_6018_45ef_8bcc_211a24c627dc = { "_leaf": true, "_type": "checkbox", "_bool": "bool", - "_data": "是否需要在楼梯边使用传送器" + "_data": "传送器是否需要在楼梯边使用;如果flyRecordPosition开启,则此项对箭头也有效。" + }, + "flyRecordPosition": { + "_leaf": true, + "_type": "checkbox", + "_bool": "bool", + "_data": "传送器平面塔模式;此模式下楼层传送器将飞到上次离开该楼层的位置。" }, "pickaxeFourDirections": { "_leaf": true, diff --git a/libs/maps.js b/libs/maps.js index 81a70157..e1ad055f 100644 --- a/libs/maps.js +++ b/libs/maps.js @@ -1170,9 +1170,12 @@ maps.prototype.terrainExists = function (x, y, id, floorId) { ////// 某个点是否存在楼梯 ////// maps.prototype.stairExists = function (x, y, floorId) { - var block = this.getBlock(x, y, floorId); - if (block == null) return false; - return block.block.event.cls == 'terrains' && (block.block.event.id == 'upFloor' || block.block.event.id == 'downFloor'); + var blockId = this.getBlockId(x, y, floorId); + if (blockId == null) return false; + var ids = ['upFloor','downFloor']; + if (core.flags.flyRecordPosition) + ids = ids.concat(['leftPortal','rightPortal','upPortal','downPortal']); + return ids.indexOf(blockId)>=0; } ////// 当前位置是否在楼梯边 ////// diff --git a/project/data.js b/project/data.js index 654b14c6..dceadc87 100644 --- a/project/data.js +++ b/project/data.js @@ -389,6 +389,7 @@ var data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d = "enableDebuff": false, "enableSkill": false, "flyNearStair": true, + "flyRecordPosition": false, "pickaxeFourDirections": false, "bombFourDirections": false, "snowFourDirections": false, diff --git a/project/functions.js b/project/functions.js index 7723d333..79b2fa9d 100644 --- a/project/functions.js +++ b/project/functions.js @@ -112,16 +112,19 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = // ---------- 此时还没有进行切换,当前floorId还是原来的 ---------- // var currentId = core.status.floorId || null; // 获得当前的floorId,可能为null + if (!core.hasFlag("__leaveLoc__")) core.setFlag("__leaveLoc__", {}); + if (currentId != null) core.getFlag("__leaveLoc__")[currentId] = core.status.hero.loc; + // 可以对currentId进行判定,比如删除某些自定义图层等 // if (currentId == 'MT0') { // core.deleteAllCanvas(); // } - + // 重置画布尺寸 core.maps.resizeMap(floorId); // 检查重生怪并重置 if (!fromLoad) { - core.status.maps[floorId].blocks.forEach(function(block) { + core.status.maps[floorId].blocks.forEach(function (block) { if (block.disable && core.enemys.hasSpecial(block.event.id, 23)) { block.disable = false; } @@ -133,7 +136,7 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = // ---------- 重绘新地图;这一步将会设置core.status.floorId ---------- // core.drawMap(floorId); - + // 切换楼层BGM if (core.status.maps[floorId].bgm) { var bgm = core.status.maps[floorId].bgm; @@ -189,17 +192,26 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = return false; } - // 获得两个楼层的索引,以决定是上楼梯还是下楼梯 - var fromIndex = core.floorIds.indexOf(fromId), - toIndex = core.floorIds.indexOf(toId); - var stair = fromIndex <= toIndex ? "downFloor" : "upFloor"; - // 地下层:同层传送至上楼梯 - if (fromIndex == toIndex && core.status.maps[fromId].underGround) stair = "upFloor"; + // 平面塔模式 + var stair = null, + loc = null; + if (core.flags.flyRecordPosition) { + loc = core.getFlag("__leaveLoc__", {})[toId] || null; + } + if (loc == null) { + // 获得两个楼层的索引,以决定是上楼梯还是下楼梯 + var fromIndex = core.floorIds.indexOf(fromId), + toIndex = core.floorIds.indexOf(toId); + var stair = fromIndex <= toIndex ? "downFloor" : "upFloor"; + // 地下层:同层传送至上楼梯 + if (fromIndex == toIndex && core.status.maps[fromId].underGround) stair = "upFloor"; + } + // 记录录像 core.status.route.push("fly:" + toId); // 传送 core.ui.closePanel(); - core.changeFloor(toId, stair, null, null, callback); + core.changeFloor(toId, stair, loc, null, callback); return true; }, From 42d8a4df8fab4f079ed4b93ab7d3cfdede0cbb92 Mon Sep 17 00:00:00 2001 From: oc Date: Fri, 28 Jun 2019 23:41:24 +0800 Subject: [PATCH 05/34] optimize canMoveDirectly --- libs/control.js | 21 ++++++++++-------- libs/maps.js | 51 +++++++++++++++++++++++++++++++++++++------- libs/utils.js | 4 ++-- project/functions.js | 6 +++--- 4 files changed, 60 insertions(+), 22 deletions(-) diff --git a/libs/control.js b/libs/control.js index 7476d52c..67f930f1 100644 --- a/libs/control.js +++ b/libs/control.js @@ -751,25 +751,28 @@ control.prototype.turnHero = function(direction) { } ////// 瞬间移动 ////// -control.prototype.moveDirectly = function (destX, destY) { - return this.controldata.moveDirectly(destX, destY); +control.prototype.moveDirectly = function (destX, destY, ignoreSteps) { + return this.controldata.moveDirectly(destX, destY, ignoreSteps); } ////// 尝试瞬间移动 ////// control.prototype.tryMoveDirectly = function (destX, destY) { if (this.nearHero(destX, destY)) return false; var canMoveArray = core.maps.generateMovableArray(); - var testMove = function (dx, dy, dir) { - if (dx<0 || dx>=core.bigmap.width|| dy<0 || dy>=core.bigmap.height) return false; - if (dir && !core.inArray(canMoveArray[dx][dy],dir)) return false; - if (core.control.moveDirectly(dx, dy)) { + var dirs = [[destX,destY],[destX-1,destY,"right"],[destX,destY-1,"down"],[destX,destY+1,"up"],[destX+1,destY,"left"]]; + var canMoveDirectlyArray = core.canMoveDirectlyArray(dirs); + + for (var i = 0; i < dirs.length; ++i) { + var d = dirs[i], dx = d[0], dy = d[1], dir = d[2]; + if (dx<0 || dx>=core.bigmap.width|| dy<0 || dy>=core.bigmap.height) continue; + if (dir && !core.inArray(canMoveArray[dx][dy],dir)) continue; + if (canMoveDirectlyArray[i]<0) continue; + if (core.control.moveDirectly(dx, dy, canMoveDirectlyArray[i])) { if (dir) core.moveHero(dir, function() {}); return true; } - return false; } - return testMove(destX,destY) || testMove(destX-1, destY, "right") || testMove(destX,destY-1,"down") - || testMove(destX,destY+1,"up") || testMove(destX+1,destY,"left"); + return false; } ////// 绘制勇士 ////// diff --git a/libs/maps.js b/libs/maps.js index e1ad055f..9d4e2298 100644 --- a/libs/maps.js +++ b/libs/maps.js @@ -486,14 +486,39 @@ maps.prototype._canMoveHero_checkCannotInOut = function (number, name, direction ////// 能否瞬间移动 ////// maps.prototype.canMoveDirectly = function (destX, destY) { - if (!this._canMoveDirectly_checkGlobal()) return -1; + return this.canMoveDirectlyArray([[destX,destY]])[0]; +} + +maps.prototype.canMoveDirectlyArray = function (locs) { + var ans = [], number = locs.length; var fromX = core.getHeroLoc('x'), fromY = core.getHeroLoc('y'); - if (fromX == destX && fromY == destY) return 0; - // 检查起点事件 - if (!this._canMoveDirectly_checkStartPoint(fromX, fromY)) return -1; + if (!this._canMoveDirectly_checkGlobal()) { + for (var i = 0; i < number; ++i) ans.push(-1); + return ans; + } + for (var i = 0; i < number; ++i) { + if (locs[i][0] == fromX && locs[i][1] == fromY) { + ans.push(0); + number--; + } + else if (locs[i][0] < 0 || locs[i][0] >= core.bigmap.width || locs[i][1] < 0 || locs[i][1] >= core.bigmap.height) { + ans.push(-1); + number--; + } + else ans.push(null); + } + if (number == 0) return ans; - return this._canMoveDirectly_bfs(fromX, fromY, destX, destY); + // 检查起点事件 + if (!this._canMoveDirectly_checkStartPoint(fromX, fromY)) { + for (var i in ans) { + if (ans[i] == null) ans[i] = -1; + } + return ans; + } + + return this._canMoveDirectly_bfs(fromX, fromY, locs, number, ans); } maps.prototype._canMoveDirectly_checkGlobal = function () { @@ -519,7 +544,7 @@ maps.prototype._canMoveDirectly_checkStartPoint = function (sx, sy) { return true; } -maps.prototype._canMoveDirectly_bfs = function (sx, sy, ex, ey) { +maps.prototype._canMoveDirectly_bfs = function (sx, sy, locs, number, ans) { var canMoveArray = this.generateMovableArray(); var blocksObj = this.getMapBlocksObj(core.status.floorId); // 滑冰 @@ -538,12 +563,22 @@ maps.prototype._canMoveDirectly_bfs = function (sx, sy, ex, ey) { if (bgMap[ny][nx] == 167) continue; if (!this._canMoveDirectly_checkNextPoint(blocksObj, nx, ny)) continue; visited[nindex] = visited[now] + 1; - if (nx == ex && ny == ey) return visited[nindex]; + // if (nx == ex && ny == ey) return visited[nindex]; + for (var i in ans) { + if (locs[i][0] == nx && locs[i][1] == ny && ans[i] == null) { + ans[i] = visited[nindex]; + number--; + if (number == 0) return ans; + } + } queue.push(nindex); } } - return -1; + for (var i in ans) { + if (ans[i] == null) ans[i] = -1; + } + return ans; } maps.prototype._canMoveDirectly_checkNextPoint = function (blocksObj, x, y) { diff --git a/libs/utils.js b/libs/utils.js index 4378dca5..daea03ea 100644 --- a/libs/utils.js +++ b/libs/utils.js @@ -1086,7 +1086,7 @@ utils.prototype._export = function (floorIds) { // map var content = floorIds.length + "\n" + core.__SIZE__ + " " + core.__SIZE__ + "\n\n"; floorIds.forEach(function (floorId) { - var arr = core.maps._getMapArrayFromBlocks(core.status.maps[floorId].blocks); + var arr = core.maps._getMapArrayFromBlocks(core.status.maps[floorId].blocks, core.__SIZE__, core.__SIZE__); content += arr.map(function (x) { // check monster x.forEach(function (t) { @@ -1102,7 +1102,7 @@ utils.prototype._export = function (floorIds) { // values content += ["redJewel", "blueJewel", "greenJewel", "redPotion", "bluePotion", "yellowPotion", "greenPotion", "sword1", "shield1"].map(function (x) { - return core.values[x] + return core.values[x] || 0; }).join(" ") + "\n\n"; // monster diff --git a/project/functions.js b/project/functions.js index 79b2fa9d..65b5e6f0 100644 --- a/project/functions.js +++ b/project/functions.js @@ -1290,12 +1290,12 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = core.updateStatusBar(); }, - "moveDirectly": function (x, y) { - // 瞬间移动;x,y为要瞬间移动的点 + "moveDirectly": function (x, y, ignoreSteps) { + // 瞬间移动;x,y为要瞬间移动的点;ignoreSteps为减少的步数,可能之前已经被计算过 // 返回true代表成功瞬移,false代表没有成功瞬移 // 判定能否瞬移到该点 - var ignoreSteps = core.canMoveDirectly(x, y); + if (ignoreSteps == null) ignoreSteps = core.canMoveDirectly(x, y); if (ignoreSteps >= 0) { core.clearMap('hero'); // 获得勇士最后的朝向 From 90fc42fc31434934e4668e154590da8a6aa95efa Mon Sep 17 00:00:00 2001 From: oc Date: Sat, 29 Jun 2019 21:08:48 +0800 Subject: [PATCH 06/34] editor_blockly getAutoCompletions --- _server/editor_blockly.js | 51 +++++++++++++++++++++++++++++++++++++++ libs/ui.js | 7 ++---- 2 files changed, 53 insertions(+), 5 deletions(-) diff --git a/_server/editor_blockly.js b/_server/editor_blockly.js index f89f36bf..1a9b5e40 100644 --- a/_server/editor_blockly.js +++ b/_server/editor_blockly.js @@ -799,6 +799,57 @@ function omitedcheckUpdateFunction(event) { }); } + editor_blockly.getAutoCompletions = function (content) { + // --- content为当前框中输入内容;将返回一个列表,为后续所有可补全内容 + + // 检查 flag:xxx,item:xxx和flag:xxx + var index = content.lastIndexOf(":"); + if (index >= 0) { + var before = content.substring(0, index), token = content.substring(index+1); + if (/^\w*$/.test(token)) { + if (before.endsWith("status")) { + return Object.keys(core.status.hero).filter(function (one) { + return one != token && one.startsWith(token); + }).sort(); + } + else if (before.endsWith("item")) { + return Object.keys(core.material.items).filter(function (one) { + return one.startsWith(token); + }).sort(); + } + else if (before.endsWith("flag")) { + // TODO:提供 flag:xxx 的补全 + return []; + } + } + } + + // 提供 core.xxx 的补全 + index = content.lastIndexOf("core."); + if (index >= 0) { + var s = content.substring(index + 5); + if (/^[\w.]*$/.test(s)) { + var tokens = s.split("."); + var now = core, prefix = tokens[tokens.length - 1]; + for (var i = 0; i < tokens.length - 1; ++i) { + now = now[tokens[i]]; + if (now == null) break; + } + if (now != null) { + var candidates = []; + for (var i in now) { + candidates.push(i); + } + return candidates.filter(function (one) { + return one != prefix && one.startsWith(prefix); + }).sort(); + } + } + } + + return []; + } + return editor_blockly; } //editor_blockly=editor_blockly(); \ No newline at end of file diff --git a/libs/ui.js b/libs/ui.js index 1961425e..49943fe3 100644 --- a/libs/ui.js +++ b/libs/ui.js @@ -885,15 +885,12 @@ ui.prototype.drawTextContent = function (ctx, content, config) { config.blocks = []; // 创建一个新的临时画布 - var tempCtx = core.bigmap.tempCanvas; - tempCtx.canvas.height = ctx.canvas.height; - tempCtx.canvas.width = ctx.canvas.width; - var _textBaseLine = tempCtx.textBaseline; + var tempCtx = core.createCanvas('__temp__', 0, 0, ctx.canvas.width, ctx.canvas.height, -1); tempCtx.textBaseline = 'top'; tempCtx.font = this._buildFont(config.fontSize, config.bold); tempCtx.fillStyle = config.color; this._drawTextContent_draw(ctx, tempCtx, content, config); - tempCtx.textBaseline = _textBaseLine; + core.deleteCanvas('__temp__'); } ui.prototype._uievent_drawTextContent = function (data) { From b138d0a157e2baeb984a65a6e81bef6b5f5d53b8 Mon Sep 17 00:00:00 2001 From: oc Date: Sat, 29 Jun 2019 22:58:06 +0800 Subject: [PATCH 07/34] editor.used_flags --- _server/editor.js | 11 +++++++++++ _server/editor_blockly.js | 7 ++++--- _server/editor_file_unsorted.js | 1 + 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/_server/editor.js b/_server/editor.js index 3641c236..033187da 100644 --- a/_server/editor.js +++ b/_server/editor.js @@ -98,6 +98,12 @@ editor.prototype.init = function (callback) { editor_multi = editor_multi(); editor_blockly = editor_blockly(); + // --- 所有用到的flags + editor.used_flags = {}; + for (var floorId in editor.main.floors) { + editor.addUsedFlags(JSON.stringify(editor.main.floors[floorId])); + } + if (editor.useCompress == null) editor.useCompress = useCompress; if (Boolean(callback)) callback(); @@ -574,5 +580,10 @@ editor.prototype.clearPos = function (clearPos, pos, callback) { }); } +editor.prototype.addUsedFlags = function (s) { + s.replace(/flag:([a-zA-Z0-9_\u4E00-\u9FCC]+)/g, function (s0, s1) { + editor.used_flags[s1] = true; return s0; + }); +} editor = new editor(); \ No newline at end of file diff --git a/_server/editor_blockly.js b/_server/editor_blockly.js index 1a9b5e40..f6c09d49 100644 --- a/_server/editor_blockly.js +++ b/_server/editor_blockly.js @@ -814,12 +814,13 @@ function omitedcheckUpdateFunction(event) { } else if (before.endsWith("item")) { return Object.keys(core.material.items).filter(function (one) { - return one.startsWith(token); + return one != token && one.startsWith(token); }).sort(); } else if (before.endsWith("flag")) { - // TODO:提供 flag:xxx 的补全 - return []; + return Object.keys(editor.used_flags || {}).filter(function (one) { + return one != token && one.startsWith(token); + }).sort(); } } } diff --git a/_server/editor_file_unsorted.js b/_server/editor_file_unsorted.js index eec1667a..cbf79655 100644 --- a/_server/editor_file_unsorted.js +++ b/_server/editor_file_unsorted.js @@ -41,6 +41,7 @@ editor_file = function (editor, callback) { datastr = datastr.join(''); alertWhenCompress(); fs.writeFile(filename, encode(datastr), 'base64', function (err, data) { + editor.addUsedFlags(datastr); callback(err); }); } From a0487a3e5c5e2bc498dead431eb60d1f48fdd965 Mon Sep 17 00:00:00 2001 From: oc Date: Thu, 4 Jul 2019 12:01:55 +0800 Subject: [PATCH 08/34] blockly auto complete --- _server/colorPicker/LICENSE.md | 21 --- _server/editor_blockly.js | 149 ++++++++++++++++- _server/thirdparty/LICENSE.md | 60 +++++++ _server/thirdparty/awesomplete.css | 103 ++++++++++++ _server/thirdparty/awesomplete.min.js | 3 + _server/thirdparty/caret-position.js | 155 ++++++++++++++++++ .../color.all.min.js | 0 .../{colorPicker => thirdparty}/jsColor.js | 90 +--------- _server/vendor/polyfill.min.js | 1 - _server/vendor/vue.min.js | 6 - editor-mobile.html | 9 +- editor.html | 9 +- 12 files changed, 483 insertions(+), 123 deletions(-) delete mode 100644 _server/colorPicker/LICENSE.md create mode 100644 _server/thirdparty/LICENSE.md create mode 100644 _server/thirdparty/awesomplete.css create mode 100644 _server/thirdparty/awesomplete.min.js create mode 100644 _server/thirdparty/caret-position.js rename _server/{colorPicker => thirdparty}/color.all.min.js (100%) rename _server/{colorPicker => thirdparty}/jsColor.js (83%) delete mode 100644 _server/vendor/polyfill.min.js delete mode 100644 _server/vendor/vue.min.js diff --git a/_server/colorPicker/LICENSE.md b/_server/colorPicker/LICENSE.md deleted file mode 100644 index 8394aa4a..00000000 --- a/_server/colorPicker/LICENSE.md +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2014 Peter Dematté - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. \ No newline at end of file diff --git a/_server/editor_blockly.js b/_server/editor_blockly.js index f6c09d49..36a84fb3 100644 --- a/_server/editor_blockly.js +++ b/_server/editor_blockly.js @@ -627,7 +627,7 @@ function omitedcheckUpdateFunction(event) { if (obj.length > 0 && b.type.startsWith(obj[0].type)) { if (b.type == 'previewUI_s') uievent.previewUI(obj[0].action); - else uievent.previewUI(obj); + else uievent.previewUI([obj[0]]); } } catch (e) {main.log(e);} return true; @@ -637,7 +637,6 @@ function omitedcheckUpdateFunction(event) { editor_blockly.doubleClickBlock = function (blockId) { var b = editor_blockly.workspace.getBlockById(blockId); - console.log(Blockly.JavaScript.blockToCode(b)); if (previewBlock(b)) return; @@ -853,4 +852,148 @@ function omitedcheckUpdateFunction(event) { return editor_blockly; } -//editor_blockly=editor_blockly(); \ No newline at end of file + +// --- modify Blockly + +Blockly.FieldColour.prototype.createWidget_ = function() { + Blockly.WidgetDiv.hide(); + + // console.log('here') + var self=this; + var pb=self.sourceBlock_ + var args = MotaActionBlocks[pb.type].args + var targetf=args[args.indexOf(self.name)-1] + + var getValue=function(){ + // return self.getValue() // css颜色 + var f = pb.getFieldValue(targetf); + if (/^(25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d),(25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d),(25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(,0(\.\d+)?|,1)?$/.test(f)) { + return f; + } + return ""; + // 也可以用 pb.getFieldValue(targetf) 获得颜色块左边的域的内容 + } + + var setValue=function(newValue){ // css颜色 + self.setValue(newValue) + var c=new Colors(); + c.setColor(newValue) + var rgbatext = [c.colors.webSmart.r,c.colors.webSmart.g,c.colors.webSmart.b,c.colors.alpha].join(","); + pb.setFieldValue(rgbatext, targetf) // 放在颜色块左边的域中 + } + + setTimeout(function () { + document.getElementById("colorPicker").value = getValue(); + window.jsColorPicker.confirm = setValue; + // 设置位置 + triggerColorPicker(Blockly.WidgetDiv.DIV.style.left, Blockly.WidgetDiv.DIV.style.top); + }); + + return document.createElement('table'); +}; + +Blockly.FieldTextInput.prototype.showInlineEditor_ = function(quietInput) { + Blockly.WidgetDiv.show(this, this.sourceBlock_.RTL, this.widgetDispose_()); + var div = Blockly.WidgetDiv.DIV; + // Create the input. + var htmlInput = + goog.dom.createDom(goog.dom.TagName.INPUT, 'blocklyHtmlInput'); + htmlInput.setAttribute('spellcheck', this.spellcheck_); + var fontSize = + (Blockly.FieldTextInput.FONTSIZE * this.workspace_.scale) + 'pt'; + div.style.fontSize = fontSize; + htmlInput.style.fontSize = fontSize; + + Blockly.FieldTextInput.htmlInput_ = htmlInput; + div.appendChild(htmlInput); + + htmlInput.value = htmlInput.defaultValue = this.text_; + htmlInput.oldValue_ = null; + + // console.log('here') + var self=this; + var pb=self.sourceBlock_ + var args = MotaActionBlocks[pb.type].args + var targetf=args[args.indexOf(self.name)+1] + + // ------ colour + + if(targetf && targetf.slice(0,7)==='Colour_'){ + var inputDom = htmlInput; + // var getValue=function(){ // 获得自己的字符串 + // return pb.getFieldValue(self.name); + // } + var setValue = function(newValue){ // 设置右边颜色块的css颜色 + pb.setFieldValue(newValue, targetf) + } + // 给inputDom绑事件 + inputDom.oninput=function(){ + var value=inputDom.value + if(/[0-9 ]+,[0-9 ]+,[0-9 ]+(,[0-9. ]+)?/.test(value)){ + setValue('rgba('+value+')') + } + } + } + else { + // --- awesomplete + var awesomplete = new Awesomplete(htmlInput, { + minChars: 4, + maxItems: 12, + replace: function (text) { + var value = this.input.value, index = this.input.selectionEnd; + if (index == null) index = value.length; + var str = value.substring(0, index - awesomplete.prefix.length) + text + value.substring(index); + this.input.value = str; + pb.setFieldValue(str, self.name); + index += text.length - awesomplete.prefix.length; + this.input.setSelectionRange(index, index); + }, + filter: function () {return true;}, + item: function (text, input) { + var li = document.createElement("li"); + li.setAttribute("role", "option"); + li.setAttribute("aria-selected", "false"); + input = awesomplete.prefix.trim(); + if (input != "") text = text.replace(new RegExp("^"+input, "i"), "$&"); + li.innerHTML = text; + return li; + } + }); + + htmlInput.oninput = function () { + var value = htmlInput.value, index = htmlInput.selectionEnd; + if (index == null) index = value.length; + value = value.substring(0, index); + // cal prefix + awesomplete.prefix = ""; + for (var i = index - 1; i>=0; i--) { + var c = value.charAt(i); + if (!/^\w$/.test(c)) { + awesomplete.prefix = value.substring(i+1); + break; + } + } + + var list = editor_blockly.getAutoCompletions(value); + awesomplete.list = list; + var coordinates = getCaretCoordinates(htmlInput, htmlInput.selectionStart, {debug: true}); + // console.log(coordinates); + awesomplete.ul.style.marginLeft = coordinates.left - + htmlInput.scrollLeft - 20 + "px"; + awesomplete.evaluate(); + } + + awesomplete.container.style.width = "100%"; + + window.awesomplete = awesomplete; + } + + if (!quietInput) { + htmlInput.focus(); + htmlInput.select(); + } + this.validate_(); + this.resizeEditor_(); + + this.bindEvents_(htmlInput); +}; \ No newline at end of file diff --git a/_server/thirdparty/LICENSE.md b/_server/thirdparty/LICENSE.md new file mode 100644 index 00000000..8867f3df --- /dev/null +++ b/_server/thirdparty/LICENSE.md @@ -0,0 +1,60 @@ +/* jsColor */ + +The MIT License (MIT) + +Copyright (c) 2014 Peter Dematté + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +/* awesomplete */ + +The MIT License (MIT) + +Copyright (c) 2015 Lea Verou + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + +/* caret-position */ + +The MIT License (MIT) + +Copyright (c) 2015 Jonathan Ong me@jongleberry.com + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/_server/thirdparty/awesomplete.css b/_server/thirdparty/awesomplete.css new file mode 100644 index 00000000..91bc2bdd --- /dev/null +++ b/_server/thirdparty/awesomplete.css @@ -0,0 +1,103 @@ +.awesomplete [hidden] { + display: none; +} + +.awesomplete .visually-hidden { + position: absolute; + clip: rect(0, 0, 0, 0); +} + +.awesomplete { + display: inline-block; + position: relative; +} + +.awesomplete > input { + display: block; +} + +.awesomplete > ul { + position: absolute; + left: 0; + z-index: 1; + box-sizing: border-box; + list-style: none; + padding: 0; + margin: 0; + background: #fff; +} + +.awesomplete > ul:empty { + display: none; +} + +.awesomplete > ul { + border-radius: .3em; + margin: .8em 0 0; + background: hsla(0,0%,100%,.9); + background: linear-gradient(to bottom right, white, hsla(0,0%,100%,.8)); + border: 1px solid rgba(0,0,0,.3); + box-shadow: .05em .2em .6em rgba(0,0,0,.2); + text-shadow: none; +} + +@supports (transform: scale(0)) { + .awesomplete > ul { + transition: .3s cubic-bezier(.4,.2,.5,1.4); + transform-origin: 1.43em -.43em; + } + + .awesomplete > ul[hidden], + .awesomplete > ul:empty { + opacity: 0; + transform: scale(0); + display: block; + transition-timing-function: ease; + } +} + +/* Pointer */ +.awesomplete > ul:before { + content: ""; + position: absolute; + top: -.43em; + left: 1em; + width: 0; height: 0; + padding: .4em; + background: white; + border: inherit; + border-right: 0; + border-bottom: 0; + -webkit-transform: rotate(45deg); + transform: rotate(45deg); +} + +.awesomplete > ul > li { + position: relative; + padding: .2em .5em; + cursor: pointer; +} + +.awesomplete > ul > li:hover { + background: hsl(200, 40%, 80%); + color: black; +} + +.awesomplete > ul > li[aria-selected="true"] { + background: hsl(205, 40%, 40%); + color: white; +} + +.awesomplete mark { + background: hsl(65, 100%, 50%); +} + +.awesomplete li:hover mark { + background: hsl(68, 100%, 41%); +} + +.awesomplete li[aria-selected="true"] mark { + background: hsl(86, 100%, 21%); + color: inherit; +} +/*# sourceMappingURL=awesomplete.css.map */ \ No newline at end of file diff --git a/_server/thirdparty/awesomplete.min.js b/_server/thirdparty/awesomplete.min.js new file mode 100644 index 00000000..5328bd9b --- /dev/null +++ b/_server/thirdparty/awesomplete.min.js @@ -0,0 +1,3 @@ +// Awesomplete - Lea Verou - MIT license +!function(){function t(t){var e=Array.isArray(t)?{label:t[0],value:t[1]}:"object"==typeof t&&"label"in t&&"value"in t?t:{label:t,value:t};this.label=e.label||e.value,this.value=e.value}function e(t,e,i){for(var n in e){var s=e[n],r=t.input.getAttribute("data-"+n.toLowerCase());"number"==typeof s?t[n]=parseInt(r):!1===s?t[n]=null!==r:s instanceof Function?t[n]=null:t[n]=r,t[n]||0===t[n]||(t[n]=n in i?i[n]:s)}}function i(t,e){return"string"==typeof t?(e||document).querySelector(t):t||null}function n(t,e){return o.call((e||document).querySelectorAll(t))}function s(){n("input.awesomplete").forEach(function(t){new r(t)})}var r=function(t,n){var s=this;r.count=(r.count||0)+1,this.count=r.count,this.isOpened=!1,this.input=i(t),this.input.setAttribute("autocomplete","off"),this.input.setAttribute("aria-expanded","false"),this.input.setAttribute("aria-owns","awesomplete_list_"+this.count),this.input.setAttribute("role","combobox"),this.options=n=n||{},e(this,{minChars:2,maxItems:10,autoFirst:!1,data:r.DATA,filter:r.FILTER_CONTAINS,sort:!1!==n.sort&&r.SORT_BYLENGTH,container:r.CONTAINER,item:r.ITEM,replace:r.REPLACE,tabSelect:!1},n),this.index=-1,this.container=this.container(t),this.ul=i.create("ul",{hidden:"hidden",role:"listbox",id:"awesomplete_list_"+this.count,inside:this.container}),this.status=i.create("span",{className:"visually-hidden",role:"status","aria-live":"assertive","aria-atomic":!0,inside:this.container,textContent:0!=this.minChars?"Type "+this.minChars+" or more characters for results.":"Begin typing for results."}),this._events={input:{input:this.evaluate.bind(this),blur:this.close.bind(this,{reason:"blur"}),keydown:function(t){var e=t.keyCode;s.opened&&(13===e&&s.selected?(t.preventDefault(),s.select()):9===e&&s.selected&&s.tabSelect?s.select():27===e?s.close({reason:"esc"}):38!==e&&40!==e||(t.preventDefault(),s[38===e?"previous":"next"]()))}},form:{submit:this.close.bind(this,{reason:"submit"})},ul:{mousedown:function(t){t.preventDefault()},click:function(t){var e=t.target;if(e!==this){for(;e&&!/li/i.test(e.nodeName);)e=e.parentNode;e&&0===t.button&&(t.preventDefault(),s.select(e,t.target))}}}},i.bind(this.input,this._events.input),i.bind(this.input.form,this._events.form),i.bind(this.ul,this._events.ul),this.input.hasAttribute("list")?(this.list="#"+this.input.getAttribute("list"),this.input.removeAttribute("list")):this.list=this.input.getAttribute("data-list")||n.list||[],r.all.push(this)};r.prototype={set list(t){if(Array.isArray(t))this._list=t;else if("string"==typeof t&&t.indexOf(",")>-1)this._list=t.split(/\s*,\s*/);else if((t=i(t))&&t.children){var e=[];o.apply(t.children).forEach(function(t){if(!t.disabled){var i=t.textContent.trim(),n=t.value||i,s=t.label||i;""!==n&&e.push({label:s,value:n})}}),this._list=e}document.activeElement===this.input&&this.evaluate()},get selected(){return this.index>-1},get opened(){return this.isOpened},close:function(t){this.opened&&(this.input.setAttribute("aria-expanded","false"),this.ul.setAttribute("hidden",""),this.isOpened=!1,this.index=-1,this.status.setAttribute("hidden",""),i.fire(this.input,"awesomplete-close",t||{}))},open:function(){this.input.setAttribute("aria-expanded","true"),this.ul.removeAttribute("hidden"),this.isOpened=!0,this.status.removeAttribute("hidden"),this.autoFirst&&-1===this.index&&this.goto(0),i.fire(this.input,"awesomplete-open")},destroy:function(){if(i.unbind(this.input,this._events.input),i.unbind(this.input.form,this._events.form),!this.options.container){var t=this.container.parentNode;t.insertBefore(this.input,this.container),t.removeChild(this.container)}this.input.removeAttribute("autocomplete"),this.input.removeAttribute("aria-autocomplete");var e=r.all.indexOf(this);-1!==e&&r.all.splice(e,1)},next:function(){var t=this.ul.children.length;this.goto(this.index-1&&e.length>0&&(e[t].setAttribute("aria-selected","true"),this.status.textContent=e[t].textContent+", list item "+(t+1)+" of "+e.length,this.input.setAttribute("aria-activedescendant",this.ul.id+"_item_"+this.index),this.ul.scrollTop=e[t].offsetTop-this.ul.clientHeight+e[t].clientHeight,i.fire(this.input,"awesomplete-highlight",{text:this.suggestions[this.index]}))},select:function(t,e){if(t?this.index=i.siblingIndex(t):t=this.ul.children[this.index],t){var n=this.suggestions[this.index];i.fire(this.input,"awesomplete-select",{text:n,origin:e||t})&&(this.replace(n),this.close({reason:"select"}),i.fire(this.input,"awesomplete-selectcomplete",{text:n}))}},evaluate:function(){var e=this,i=this.input.value;i.length>=this.minChars&&this._list&&this._list.length>0?(this.index=-1,this.ul.innerHTML="",this.suggestions=this._list.map(function(n){return new t(e.data(n,i))}).filter(function(t){return e.filter(t,i)}),!1!==this.sort&&(this.suggestions=this.suggestions.sort(this.sort)),this.suggestions=this.suggestions.slice(0,this.maxItems),this.suggestions.forEach(function(t,n){e.ul.appendChild(e.item(t,i,n))}),0===this.ul.children.length?(this.status.textContent="No results found",this.close({reason:"nomatches"})):(this.open(),this.status.textContent=this.ul.children.length+" results found")):(this.close({reason:"nomatches"}),this.status.textContent="No results found")}},r.all=[],r.FILTER_CONTAINS=function(t,e){return RegExp(i.regExpEscape(e.trim()),"i").test(t)},r.FILTER_STARTSWITH=function(t,e){return RegExp("^"+i.regExpEscape(e.trim()),"i").test(t)},r.SORT_BYLENGTH=function(t,e){return t.length!==e.length?t.length-e.length:t$&"),role:"option","aria-selected":"false",id:"awesomplete_list_"+this.count+"_item_"+n})},r.REPLACE=function(t){this.input.value=t.value},r.DATA=function(t){return t},Object.defineProperty(t.prototype=Object.create(String.prototype),"length",{get:function(){return this.label.length}}),t.prototype.toString=t.prototype.valueOf=function(){return""+this.label};var o=Array.prototype.slice;i.create=function(t,e){var n=document.createElement(t);for(var s in e){var r=e[s];if("inside"===s)i(r).appendChild(n);else if("around"===s){var o=i(r);o.parentNode.insertBefore(n,o),n.appendChild(o),null!=o.getAttribute("autofocus")&&o.focus()}else s in n?n[s]=r:n.setAttribute(s,r)}return n},i.bind=function(t,e){if(t)for(var i in e){var n=e[i];i.split(/\s+/).forEach(function(e){t.addEventListener(e,n)})}},i.unbind=function(t,e){if(t)for(var i in e){var n=e[i];i.split(/\s+/).forEach(function(e){t.removeEventListener(e,n)})}},i.fire=function(t,e,i){var n=document.createEvent("HTMLEvents");n.initEvent(e,!0,!0);for(var s in i)n[s]=i[s];return t.dispatchEvent(n)},i.regExpEscape=function(t){return t.replace(/[-\\^$*+?.()|[\]{}]/g,"\\$&")},i.siblingIndex=function(t){for(var e=0;t=t.previousElementSibling;e++);return e},"undefined"!=typeof self&&(self.Awesomplete=r),"undefined"!=typeof Document&&("loading"!==document.readyState?s():document.addEventListener("DOMContentLoaded",s)),r.$=i,r.$$=n,"object"==typeof module&&module.exports&&(module.exports=r)}(); +//# sourceMappingURL=awesomplete.min.js.map \ No newline at end of file diff --git a/_server/thirdparty/caret-position.js b/_server/thirdparty/caret-position.js new file mode 100644 index 00000000..a46ddb78 --- /dev/null +++ b/_server/thirdparty/caret-position.js @@ -0,0 +1,155 @@ +/* jshint browser: true */ + +(function () { + +// We'll copy the properties below into the mirror div. +// Note that some browsers, such as Firefox, do not concatenate properties +// into their shorthand (e.g. padding-top, padding-bottom etc. -> padding), +// so we have to list every single property explicitly. + var properties = [ + 'direction', // RTL support + 'boxSizing', + 'width', // on Chrome and IE, exclude the scrollbar, so the mirror div wraps exactly as the textarea does + 'height', + 'overflowX', + 'overflowY', // copy the scrollbar for IE + + 'borderTopWidth', + 'borderRightWidth', + 'borderBottomWidth', + 'borderLeftWidth', + 'borderStyle', + + 'paddingTop', + 'paddingRight', + 'paddingBottom', + 'paddingLeft', + + // https://developer.mozilla.org/en-US/docs/Web/CSS/font + 'fontStyle', + 'fontVariant', + 'fontWeight', + 'fontStretch', + 'fontSize', + 'fontSizeAdjust', + 'lineHeight', + 'fontFamily', + + 'textAlign', + 'textTransform', + 'textIndent', + 'textDecoration', // might not make a difference, but better be safe + + 'letterSpacing', + 'wordSpacing', + + 'tabSize', + 'MozTabSize' + + ]; + + var isBrowser = (typeof window !== 'undefined'); + var isFirefox = (isBrowser && window.mozInnerScreenX != null); + + function getCaretCoordinates(element, position, options) { + if (!isBrowser) { + throw new Error('textarea-caret-position#getCaretCoordinates should only be called in a browser'); + } + + var debug = options && options.debug || false; + if (debug) { + var el = document.querySelector('#input-textarea-caret-position-mirror-div'); + if (el) el.parentNode.removeChild(el); + } + + // The mirror div will replicate the textarea's style + var div = document.createElement('div'); + div.id = 'input-textarea-caret-position-mirror-div'; + document.body.appendChild(div); + + var style = div.style; + var computed = window.getComputedStyle ? window.getComputedStyle(element) : element.currentStyle; // currentStyle for IE < 9 + var isInput = element.nodeName === 'INPUT'; + + // Default textarea styles + style.whiteSpace = 'nowrap'; + if (!isInput) + style.wordWrap = 'break-word'; // only for textarea-s + + // Position off-screen + style.position = 'absolute'; // required to return coordinates properly + if (!debug) + style.visibility = 'hidden'; // not 'display: none' because we want rendering + + // Transfer the element's properties to the div + properties.forEach(function (prop) { + if (isInput && prop === 'lineHeight') { + // Special case for s because text is rendered centered and line height may be != height + if (computed.boxSizing === "border-box") { + var height = parseInt(computed.height); + var outerHeight = + parseInt(computed.paddingTop) + + parseInt(computed.paddingBottom) + + parseInt(computed.borderTopWidth) + + parseInt(computed.borderBottomWidth); + var targetHeight = outerHeight + parseInt(computed.lineHeight); + if (height > targetHeight) { + style.lineHeight = height - outerHeight + "px"; + } else if (height === targetHeight) { + style.lineHeight = computed.lineHeight; + } else { + style.lineHeight = 0; + } + } else { + style.lineHeight = computed.height; + } + } else { + style[prop] = computed[prop]; + } + }); + + if (isFirefox) { + // Firefox lies about the overflow property for textareas: https://bugzilla.mozilla.org/show_bug.cgi?id=984275 + if (element.scrollHeight > parseInt(computed.height)) + style.overflowY = 'scroll'; + } else { + style.overflow = 'hidden'; // for Chrome to not render a scrollbar; IE keeps overflowY = 'scroll' + } + + div.textContent = element.value.substring(0, position); + // The second special handling for input type="text" vs textarea: + // spaces need to be replaced with non-breaking spaces - http://stackoverflow.com/a/13402035/1269037 + if (isInput) + div.textContent = div.textContent.replace(/\s/g, '\u00a0'); + + var span = document.createElement('span'); + // Wrapping must be replicated *exactly*, including when a long word gets + // onto the next line, with whitespace at the end of the line before (#7). + // The *only* reliable way to do that is to copy the *entire* rest of the + // textarea's content into the created at the caret position. + // For inputs, just '.' would be enough, but no need to bother. + span.textContent = element.value.substring(position) || '.'; // || because a completely empty faux span doesn't render at all + div.appendChild(span); + + var coordinates = { + top: span.offsetTop + parseInt(computed['borderTopWidth']), + left: span.offsetLeft + parseInt(computed['borderLeftWidth']), + height: parseInt(computed['lineHeight']) + }; + + if (debug) { + span.style.backgroundColor = '#aaa'; + } else { + document.body.removeChild(div); + } + + return coordinates; + } + + if (typeof module != 'undefined' && typeof module.exports != 'undefined') { + module.exports = getCaretCoordinates; + } else if(isBrowser) { + window.getCaretCoordinates = getCaretCoordinates; + } + +}()); \ No newline at end of file diff --git a/_server/colorPicker/color.all.min.js b/_server/thirdparty/color.all.min.js similarity index 100% rename from _server/colorPicker/color.all.min.js rename to _server/thirdparty/color.all.min.js diff --git a/_server/colorPicker/jsColor.js b/_server/thirdparty/jsColor.js similarity index 83% rename from _server/colorPicker/jsColor.js rename to _server/thirdparty/jsColor.js index 45dcaf1d..cbd9dee6 100644 --- a/_server/colorPicker/jsColor.js +++ b/_server/thirdparty/jsColor.js @@ -1,3 +1,5 @@ +// ------ ColorPicker ------ // + (function (window) { window.jsColorPicker = function(selectors, config) { var renderCallback = function(colors, mode) { @@ -254,7 +256,7 @@ })(this); // Added -var colors = jsColorPicker('input.color', { +jsColorPicker('input.color', { customBG: '#222', readOnly: false, // patch: false, @@ -303,89 +305,5 @@ function triggerColorPicker(left, top) { } } -Blockly.FieldColour.prototype.createWidget_ = function() { - Blockly.WidgetDiv.hide(); +// ------ AutoCompletion ------ - // console.log('here') - var self=this; - var pb=self.sourceBlock_ - var args = MotaActionBlocks[pb.type].args - var targetf=args[args.indexOf(self.name)-1] - - var getValue=function(){ - // return self.getValue() // css颜色 - var f = pb.getFieldValue(targetf); - if (/^(25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d),(25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d),(25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(,0(\.\d+)?|,1)?$/.test(f)) { - return f; - } - return ""; - // 也可以用 pb.getFieldValue(targetf) 获得颜色块左边的域的内容 - } - - var setValue=function(newValue){ // css颜色 - self.setValue(newValue) - var c=new Colors(); - c.setColor(newValue) - var rgbatext = [c.colors.webSmart.r,c.colors.webSmart.g,c.colors.webSmart.b,c.colors.alpha].join(","); - pb.setFieldValue(rgbatext, targetf) // 放在颜色块左边的域中 - } - - setTimeout(function () { - document.getElementById("colorPicker").value = getValue(); - window.jsColorPicker.confirm = setValue; - // 设置位置 - triggerColorPicker(Blockly.WidgetDiv.DIV.style.left, Blockly.WidgetDiv.DIV.style.top); - }); - - return document.createElement('table'); -}; - -Blockly.FieldTextInput.prototype.showInlineEditor_ = function(quietInput) { - Blockly.WidgetDiv.show(this, this.sourceBlock_.RTL, this.widgetDispose_()); - var div = Blockly.WidgetDiv.DIV; - // Create the input. - var htmlInput = - goog.dom.createDom(goog.dom.TagName.INPUT, 'blocklyHtmlInput'); - htmlInput.setAttribute('spellcheck', this.spellcheck_); - var fontSize = - (Blockly.FieldTextInput.FONTSIZE * this.workspace_.scale) + 'pt'; - div.style.fontSize = fontSize; - htmlInput.style.fontSize = fontSize; - - Blockly.FieldTextInput.htmlInput_ = htmlInput; - div.appendChild(htmlInput); - - htmlInput.value = htmlInput.defaultValue = this.text_; - htmlInput.oldValue_ = null; - this.validate_(); - this.resizeEditor_(); - if (!quietInput) { - htmlInput.focus(); - htmlInput.select(); - } - - // console.log('here') - var self=this; - var pb=self.sourceBlock_ - var args = MotaActionBlocks[pb.type].args - var targetf=args[args.indexOf(self.name)+1] - - if(targetf && targetf.slice(0,7)==='Colour_'){ - var inputDom = htmlInput; - // var getValue=function(){ // 获得自己的字符串 - // return pb.getFieldValue(self.name); - // } - var setValue = function(newValue){ // 设置右边颜色块的css颜色 - pb.setFieldValue(newValue, targetf) - } - // 给inputDom绑事件 - inputDom.oninput=function(){ - var value=inputDom.value - if(/[0-9 ]+,[0-9 ]+,[0-9 ]+(,[0-9. ]+)?/.test(value)){ - setValue('rgba('+value+')') - } - } - } - - this.bindEvents_(htmlInput); -}; \ No newline at end of file diff --git a/_server/vendor/polyfill.min.js b/_server/vendor/polyfill.min.js deleted file mode 100644 index 80fe8dc8..00000000 --- a/_server/vendor/polyfill.min.js +++ /dev/null @@ -1 +0,0 @@ -!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?n():"function"==typeof define&&define.amd?define(n):n()}(0,function(){"use strict";function e(){}function n(e,n){for(;3===e._state;)e=e._value;0!==e._state?(e._handled=!0,f._immediateFn(function(){var i=1===e._state?n.onFulfilled:n.onRejected;if(null!==i){var r;try{r=i(e._value)}catch(e){return void o(n.promise,e)}t(n.promise,r)}else(1===e._state?t:o)(n.promise,e._value)})):e._deferreds.push(n)}function t(e,n){try{if(n===e)throw new TypeError("A promise cannot be resolved with itself.");if(n&&("object"==typeof n||"function"==typeof n)){var t=n.then;if(n instanceof f)return e._state=3,e._value=n,void i(e);if("function"==typeof t)return void r(function(e,n){return function(){e.apply(n,arguments)}}(t,n),e)}e._state=1,e._value=n,i(e)}catch(n){o(e,n)}}function o(e,n){e._state=2,e._value=n,i(e)}function i(e){2===e._state&&0===e._deferreds.length&&f._immediateFn(function(){e._handled||f._unhandledRejectionFn(e._value)});for(var t=0,o=e._deferreds.length;o>t;t++)n(e,e._deferreds[t]);e._deferreds=null}function r(e,n){var i=!1;try{e(function(e){i||(i=!0,t(n,e))},function(e){i||(i=!0,o(n,e))})}catch(e){if(i)return;i=!0,o(n,e)}}function f(e){if(!(this instanceof f))throw new TypeError("Promises must be constructed via new");if("function"!=typeof e)throw new TypeError("not a function");this._state=0,this._handled=!1,this._value=void 0,this._deferreds=[],r(e,this)}var u=setTimeout,c=f.prototype;c.catch=function(e){return this.then(null,e)},c.then=function(t,o){var i=new this.constructor(e);return n(this,new function(e,n,t){this.onFulfilled="function"==typeof e?e:null,this.onRejected="function"==typeof n?n:null,this.promise=t}(t,o,i)),i},f.all=function(e){return new f(function(n,t){function o(e,f){try{if(f&&("object"==typeof f||"function"==typeof f)){var u=f.then;if("function"==typeof u)return void u.call(f,function(n){o(e,n)},t)}i[e]=f,0==--r&&n(i)}catch(e){t(e)}}if(!e||void 0===e.length)throw new TypeError("Promise.all accepts an array");var i=Array.prototype.slice.call(e);if(0===i.length)return n([]);for(var r=i.length,f=0;i.length>f;f++)o(f,i[f])})},f.resolve=function(e){return e&&"object"==typeof e&&e.constructor===f?e:new f(function(n){n(e)})},f.reject=function(e){return new f(function(n,t){t(e)})},f.race=function(e){return new f(function(n,t){for(var o=0,i=e.length;i>o;o++)e[o].then(n,t)})},f._immediateFn="function"==typeof setImmediate&&function(e){setImmediate(e)}||function(e){u(e,0)},f._unhandledRejectionFn=function(e){void 0!==console&&console&&console.warn("Possible Unhandled Promise Rejection:",e)};var a=function(){if("undefined"!=typeof self)return self;if("undefined"!=typeof window)return window;if(void 0!==a)return a;throw Error("unable to locate global object")}();a.Promise||(a.Promise=f)}); diff --git a/_server/vendor/vue.min.js b/_server/vendor/vue.min.js deleted file mode 100644 index 4eb55b79..00000000 --- a/_server/vendor/vue.min.js +++ /dev/null @@ -1,6 +0,0 @@ -/*! - * Vue.js v2.5.11 - * (c) 2014-2017 Evan You - * Released under the MIT License. - */ -!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):t.Vue=e()}(this,function(){"use strict";function t(t){return void 0===t||null===t}function e(t){return void 0!==t&&null!==t}function n(t){return!0===t}function r(t){return"string"==typeof t||"number"==typeof t||"boolean"==typeof t}function i(t){return null!==t&&"object"==typeof t}function o(t){return"[object Object]"===Nn.call(t)}function a(t){var e=parseFloat(String(t));return e>=0&&Math.floor(e)===e&&isFinite(t)}function s(t){return null==t?"":"object"==typeof t?JSON.stringify(t,null,2):String(t)}function c(t){var e=parseFloat(t);return isNaN(e)?t:e}function u(t,e){for(var n=Object.create(null),r=t.split(","),i=0;i-1)return t.splice(n,1)}}function f(t,e){return Mn.call(t,e)}function d(t){var e=Object.create(null);return function(n){return e[n]||(e[n]=t(n))}}function p(t,e){function n(n){var r=arguments.length;return r?r>1?t.apply(e,arguments):t.call(e,n):t.call(e)}return n._length=t.length,n}function v(t,e){e=e||0;for(var n=t.length-e,r=new Array(n);n--;)r[n]=t[n+e];return r}function h(t,e){for(var n in e)t[n]=e[n];return t}function m(t){for(var e={},n=0;n0&&(tt((s=et(s,(o||"")+"_"+a))[0])&&tt(u)&&(l[c]=x(u.text+s[0].text),s.shift()),l.push.apply(l,s)):r(s)?tt(u)?l[c]=x(u.text+s):""!==s&&l.push(x(s)):tt(s)&&tt(u)?l[c]=x(u.text+s.text):(n(i._isVList)&&e(s.tag)&&t(s.key)&&e(o)&&(s.key="__vlist"+o+"_"+a+"__"),l.push(s)));return l}function nt(t,e){return(t.__esModule||fr&&"Module"===t[Symbol.toStringTag])&&(t=t.default),i(t)?e.extend(t):t}function rt(t){return t.isComment&&t.asyncFactory}function it(t){if(Array.isArray(t))for(var n=0;n=0||n.indexOf(t[i])<0)&&r.push(t[i]);return r}return t}}(n[o],r[o],i[o]));return e}(t);r&&h(t.extendOptions,r),(e=t.options=F(n,t.extendOptions)).name&&(e.components[e.name]=t)}}return e}function Rt(t){this._init(t)}function Ht(t){t.cid=0;var e=1;t.extend=function(t){t=t||{};var n=this,r=n.cid,i=t._Ctor||(t._Ctor={});if(i[r])return i[r];var o=t.name||n.options.name,a=function(t){this._init(t)};return a.prototype=Object.create(n.prototype),a.prototype.constructor=a,a.cid=e++,a.options=F(n.options,t),a.super=n,a.options.props&&function(t){var e=t.options.props;for(var n in e)mt(t.prototype,"_props",n)}(a),a.options.computed&&function(t){var e=t.options.computed;for(var n in e)gt(t.prototype,n,e[n])}(a),a.extend=n.extend,a.mixin=n.mixin,a.use=n.use,zn.forEach(function(t){a[t]=n[t]}),o&&(a.options.components[o]=a),a.superOptions=n.options,a.extendOptions=t,a.sealedOptions=h({},a.options),i[r]=a,a}}function Bt(t){return t&&(t.Ctor.options.name||t.tag)}function Ut(t,e){return Array.isArray(t)?t.indexOf(e)>-1:"string"==typeof t?t.split(",").indexOf(e)>-1:!!function(t){return"[object RegExp]"===Nn.call(t)}(t)&&t.test(e)}function Vt(t,e){var n=t.cache,r=t.keys,i=t._vnode;for(var o in n){var a=n[o];if(a){var s=Bt(a.componentOptions);s&&!e(s)&&zt(n,o,r,i)}}}function zt(t,e,n,r){var i=t[e];!i||r&&i.tag===r.tag||i.componentInstance.$destroy(),t[e]=null,l(n,e)}function Kt(t){for(var n=t.data,r=t,i=t;e(i.componentInstance);)(i=i.componentInstance._vnode)&&i.data&&(n=Jt(i.data,n));for(;e(r=r.parent);)r&&r.data&&(n=Jt(n,r.data));return function(t,n){if(e(t)||e(n))return qt(t,Wt(n));return""}(n.staticClass,n.class)}function Jt(t,n){return{staticClass:qt(t.staticClass,n.staticClass),class:e(t.class)?[t.class,n.class]:n.class}}function qt(t,e){return t?e?t+" "+e:t:e||""}function Wt(t){return Array.isArray(t)?function(t){for(var n,r="",i=0,o=t.length;i=0&&" "===(m=t.charAt(h));h--);m&&Ii.test(m)||(l=!0)}}else void 0===o?(v=i+1,o=t.slice(0,i).trim()):e();if(void 0===o?o=t.slice(0,i).trim():0!==v&&e(),a)for(i=0;i-1?{exp:t.slice(0,ii),key:'"'+t.slice(ii+1)+'"'}:{exp:t,key:null};ni=t,ii=oi=ai=0;for(;!ge();)_e(ri=ye())?be(ri):91===ri&&function(t){var e=1;oi=ii;for(;!ge();)if(t=ye(),_e(t))be(t);else if(91===t&&e++,93===t&&e--,0===e){ai=ii;break}}(ri);return{exp:t.slice(0,oi),key:t.slice(oi+1,ai)}}(t);return null===n.key?t+"="+e:"$set("+n.exp+", "+n.key+", "+e+")"}function ye(){return ni.charCodeAt(++ii)}function ge(){return ii>=ei}function _e(t){return 34===t||39===t}function be(t){for(var e=t;!ge()&&(t=ye())!==e;);}function $e(t,e,n,r,i){e=function(t){return t._withTask||(t._withTask=function(){Er=!0;var e=t.apply(null,arguments);return Er=!1,e})}(e),n&&(e=function(t,e,n){var r=si;return function i(){null!==t.apply(null,arguments)&&Ce(e,i,n,r)}}(e,t,r)),si.addEventListener(t,e,or?{capture:r,passive:i}:r)}function Ce(t,e,n,r){(r||si).removeEventListener(t,e._withTask||e,n)}function we(n,r){if(!t(n.data.on)||!t(r.data.on)){var i=r.data.on||{},o=n.data.on||{};si=r.elm,function(t){if(e(t[Li])){var n=Qn?"change":"input";t[n]=[].concat(t[Li],t[n]||[]),delete t[Li]}e(t[Mi])&&(t.change=[].concat(t[Mi],t.change||[]),delete t[Mi])}(i),X(i,o,$e,Ce,r.context),si=void 0}}function xe(n,r){if(!t(n.data.domProps)||!t(r.data.domProps)){var i,o,a=r.elm,s=n.data.domProps||{},u=r.data.domProps||{};e(u.__ob__)&&(u=r.data.domProps=h({},u));for(i in s)t(u[i])&&(a[i]="");for(i in u){if(o=u[i],"textContent"===i||"innerHTML"===i){if(r.children&&(r.children.length=0),o===s[i])continue;1===a.childNodes.length&&a.removeChild(a.childNodes[0])}if("value"===i){a._value=o;var l=t(o)?"":String(o);(function(t,n){return!t.composing&&("OPTION"===t.tagName||function(t,e){var n=!0;try{n=document.activeElement!==t}catch(t){}return n&&t.value!==e}(t,n)||function(t,n){var r=t.value,i=t._vModifiers;if(e(i)){if(i.lazy)return!1;if(i.number)return c(r)!==c(n);if(i.trim)return r.trim()!==n.trim()}return r!==n}(t,n))})(a,l)&&(a.value=l)}else a[i]=o}}}function ke(t){var e=Ae(t.style);return t.staticStyle?h(t.staticStyle,e):e}function Ae(t){return Array.isArray(t)?m(t):"string"==typeof t?Fi(t):t}function Oe(n,r){var i=r.data,o=n.data;if(!(t(i.staticStyle)&&t(i.style)&&t(o.staticStyle)&&t(o.style))){var a,s,c=r.elm,u=o.staticStyle,l=o.normalizedStyle||o.style||{},f=u||l,d=Ae(r.data.style)||{};r.data.normalizedStyle=e(d.__ob__)?h({},d):d;var p=function(t,e){var n,r={};if(e)for(var i=t;i.componentInstance;)(i=i.componentInstance._vnode)&&i.data&&(n=ke(i.data))&&h(r,n);(n=ke(t.data))&&h(r,n);for(var o=t;o=o.parent;)o.data&&(n=ke(o.data))&&h(r,n);return r}(r,!0);for(s in f)t(p[s])&&Bi(c,s,"");for(s in p)(a=p[s])!==f[s]&&Bi(c,s,null==a?"":a)}}function Se(t,e){if(e&&(e=e.trim()))if(t.classList)e.indexOf(" ")>-1?e.split(/\s+/).forEach(function(e){return t.classList.add(e)}):t.classList.add(e);else{var n=" "+(t.getAttribute("class")||"")+" ";n.indexOf(" "+e+" ")<0&&t.setAttribute("class",(n+e).trim())}}function Te(t,e){if(e&&(e=e.trim()))if(t.classList)e.indexOf(" ")>-1?e.split(/\s+/).forEach(function(e){return t.classList.remove(e)}):t.classList.remove(e),t.classList.length||t.removeAttribute("class");else{for(var n=" "+(t.getAttribute("class")||"")+" ",r=" "+e+" ";n.indexOf(r)>=0;)n=n.replace(r," ");(n=n.trim())?t.setAttribute("class",n):t.removeAttribute("class")}}function Ee(t){if(t){if("object"==typeof t){var e={};return!1!==t.css&&h(e,Ki(t.name||"v")),h(e,t),e}return"string"==typeof t?Ki(t):void 0}}function je(t){Qi(function(){Qi(t)})}function Ne(t,e){var n=t._transitionClasses||(t._transitionClasses=[]);n.indexOf(e)<0&&(n.push(e),Se(t,e))}function Ie(t,e){t._transitionClasses&&l(t._transitionClasses,e),Te(t,e)}function Le(t,e,n){var r=Me(t,e),i=r.type,o=r.timeout,a=r.propCount;if(!i)return n();var s=i===qi?Zi:Yi,c=0,u=function(){t.removeEventListener(s,l),n()},l=function(e){e.target===t&&++c>=a&&u()};setTimeout(function(){c0&&(n=qi,l=a,f=o.length):e===Wi?u>0&&(n=Wi,l=u,f=c.length):f=(n=(l=Math.max(a,u))>0?a>u?qi:Wi:null)?n===qi?o.length:c.length:0;return{type:n,timeout:l,propCount:f,hasTransform:n===qi&&to.test(r[Gi+"Property"])}}function De(t,e){for(;t.length1}function Ue(t,e){!0!==e.data.show&&Fe(e)}function Ve(t,e,n){ze(t,e,n),(Qn||er)&&setTimeout(function(){ze(t,e,n)},0)}function ze(t,e,n){var r=e.value,i=t.multiple;if(!i||Array.isArray(r)){for(var o,a,s=0,c=t.options.length;s-1,a.selected!==o&&(a.selected=o);else if(g(Je(a),r))return void(t.selectedIndex!==s&&(t.selectedIndex=s));i||(t.selectedIndex=-1)}}function Ke(t,e){return e.every(function(e){return!g(e,t)})}function Je(t){return"_value"in t?t._value:t.value}function qe(t){t.target.composing=!0}function We(t){t.target.composing&&(t.target.composing=!1,Ge(t.target,"input"))}function Ge(t,e){var n=document.createEvent("HTMLEvents");n.initEvent(e,!0,!0),t.dispatchEvent(n)}function Ze(t){return!t.componentInstance||t.data&&t.data.transition?t:Ze(t.componentInstance._vnode)}function Xe(t){var e=t&&t.componentOptions;return e&&e.Ctor.options.abstract?Xe(it(e.children)):t}function Ye(t){var e={},n=t.$options;for(var r in n.propsData)e[r]=t[r];var i=n._parentListeners;for(var o in i)e[Pn(o)]=i[o];return e}function Qe(t,e){if(/\d-keep-alive$/.test(e.tag))return t("keep-alive",{props:e.componentOptions.propsData})}function tn(t){t.elm._moveCb&&t.elm._moveCb(),t.elm._enterCb&&t.elm._enterCb()}function en(t){t.data.newPos=t.elm.getBoundingClientRect()}function nn(t){var e=t.data.pos,n=t.data.newPos,r=e.left-n.left,i=e.top-n.top;if(r||i){t.data.moved=!0;var o=t.elm.style;o.transform=o.WebkitTransform="translate("+r+"px,"+i+"px)",o.transitionDuration="0s"}}function rn(t,e){var n=e?zo:Vo;return t.replace(n,function(t){return Uo[t]})}function on(t,e,n){return{type:1,tag:t,attrsList:e,attrsMap:function(t){for(var e={},n=0,r=t.length;n=0&&a[i].lowerCasedTag!==s;i--);else i=0;if(i>=0){for(var c=a.length-1;c>=i;c--)e.end&&e.end(a[c].tag,n,r);a.length=i,o=i&&a[i-1].tag}else"br"===s?e.start&&e.start(t,[],!0,n,r):"p"===s&&(e.start&&e.start(t,[],!1,n,r),e.end&&e.end(t,n,r))}for(var i,o,a=[],s=e.expectHTML,c=e.isUnaryTag||Bn,u=e.canBeLeftOpenTag||Bn,l=0;t;){if(i=t,o&&Ho(o)){var f=0,d=o.toLowerCase(),p=Bo[d]||(Bo[d]=new RegExp("([\\s\\S]*?)(]*>)","i")),v=t.replace(p,function(t,n,r){return f=r.length,Ho(d)||"noscript"===d||(n=n.replace(//g,"$1").replace(//g,"$1")),Jo(d,n)&&(n=n.slice(1)),e.chars&&e.chars(n),""});l+=t.length-v.length,t=v,r(d,l-f,l)}else{var h=t.indexOf("<");if(0===h){if(Ao.test(t)){var m=t.indexOf("--\x3e");if(m>=0){e.shouldKeepComment&&e.comment(t.substring(4,m)),n(m+3);continue}}if(Oo.test(t)){var y=t.indexOf("]>");if(y>=0){n(y+2);continue}}var g=t.match(ko);if(g){n(g[0].length);continue}var _=t.match(xo);if(_){var b=l;n(_[0].length),r(_[1],b,l);continue}var $=function(){var e=t.match(Co);if(e){var r={tagName:e[1],attrs:[],start:l};n(e[0].length);for(var i,o;!(i=t.match(wo))&&(o=t.match(_o));)n(o[0].length),r.attrs.push(o);if(i)return r.unarySlash=i[1],n(i[0].length),r.end=l,r}}();if($){!function(t){var n=t.tagName,i=t.unarySlash;s&&("p"===o&&go(n)&&r(o),u(n)&&o===n&&r(n));for(var l=c(n)||!!i,f=t.attrs.length,d=new Array(f),p=0;p=0){for(w=t.slice(h);!(xo.test(w)||Co.test(w)||Ao.test(w)||Oo.test(w)||(x=w.indexOf("<",1))<0);)h+=x,w=t.slice(h);C=t.substring(0,h),n(h)}h<0&&(C=t,t=""),e.chars&&C&&e.chars(C)}if(t===i){e.chars&&e.chars(t);break}}r()}(t,{warn:To,expectHTML:e.expectHTML,isUnaryTag:e.isUnaryTag,canBeLeftOpenTag:e.canBeLeftOpenTag,shouldDecodeNewlines:e.shouldDecodeNewlines,shouldDecodeNewlinesForHref:e.shouldDecodeNewlinesForHref,shouldKeepComment:e.comments,start:function(t,a,u){var l=i&&i.ns||Do(t);Qn&&"svg"===l&&(a=function(t){for(var e=[],n=0;na&&o.push(JSON.stringify(t.slice(a,i)));var s=ae(r[1].trim());o.push("_s("+s+")"),a=i+r[0].length}return a':'
',Ro.innerHTML.indexOf(" ")>0}var jn=Object.freeze({}),Nn=Object.prototype.toString,In=u("slot,component",!0),Ln=u("key,ref,slot,slot-scope,is"),Mn=Object.prototype.hasOwnProperty,Dn=/-(\w)/g,Pn=d(function(t){return t.replace(Dn,function(t,e){return e?e.toUpperCase():""})}),Fn=d(function(t){return t.charAt(0).toUpperCase()+t.slice(1)}),Rn=/\B([A-Z])/g,Hn=d(function(t){return t.replace(Rn,"-$1").toLowerCase()}),Bn=function(t,e,n){return!1},Un=function(t){return t},Vn="data-server-rendered",zn=["component","directive","filter"],Kn=["beforeCreate","created","beforeMount","mounted","beforeUpdate","updated","beforeDestroy","destroyed","activated","deactivated","errorCaptured"],Jn={optionMergeStrategies:Object.create(null),silent:!1,productionTip:!1,devtools:!1,performance:!1,errorHandler:null,warnHandler:null,ignoredElements:[],keyCodes:Object.create(null),isReservedTag:Bn,isReservedAttr:Bn,isUnknownElement:Bn,getTagNamespace:y,parsePlatformTagName:Un,mustUseProp:Bn,_lifecycleHooks:Kn},qn=/[^\w.$]/,Wn="__proto__"in{},Gn="undefined"!=typeof window,Zn="undefined"!=typeof WXEnvironment&&!!WXEnvironment.platform,Xn=Zn&&WXEnvironment.platform.toLowerCase(),Yn=Gn&&window.navigator.userAgent.toLowerCase(),Qn=Yn&&/msie|trident/.test(Yn),tr=Yn&&Yn.indexOf("msie 9.0")>0,er=Yn&&Yn.indexOf("edge/")>0,nr=Yn&&Yn.indexOf("android")>0||"android"===Xn,rr=Yn&&/iphone|ipad|ipod|ios/.test(Yn)||"ios"===Xn,ir=(Yn&&/chrome\/\d+/.test(Yn),{}.watch),or=!1;if(Gn)try{var ar={};Object.defineProperty(ar,"passive",{get:function(){or=!0}}),window.addEventListener("test-passive",null,ar)}catch(t){}var sr,cr,ur=function(){return void 0===sr&&(sr=!Gn&&"undefined"!=typeof global&&"server"===global.process.env.VUE_ENV),sr},lr=Gn&&window.__VUE_DEVTOOLS_GLOBAL_HOOK__,fr="undefined"!=typeof Symbol&&w(Symbol)&&"undefined"!=typeof Reflect&&w(Reflect.ownKeys);cr="undefined"!=typeof Set&&w(Set)?Set:function(){function t(){this.set=Object.create(null)}return t.prototype.has=function(t){return!0===this.set[t]},t.prototype.add=function(t){this.set[t]=!0},t.prototype.clear=function(){this.set=Object.create(null)},t}();var dr=y,pr=0,vr=function(){this.id=pr++,this.subs=[]};vr.prototype.addSub=function(t){this.subs.push(t)},vr.prototype.removeSub=function(t){l(this.subs,t)},vr.prototype.depend=function(){vr.target&&vr.target.addDep(this)},vr.prototype.notify=function(){for(var t=this.subs.slice(),e=0,n=t.length;eVr&&Fr[n].id>t.id;)n--;Fr.splice(n+1,0,t)}else Fr.push(t);Br||(Br=!0,q(ht))}}(this)},Kr.prototype.run=function(){if(this.active){var t=this.get();if(t!==this.value||i(t)||this.deep){var e=this.value;if(this.value=t,this.user)try{this.cb.call(this.vm,t,e)}catch(t){V(t,this.vm,'callback for watcher "'+this.expression+'"')}else this.cb.call(this.vm,t,e)}}},Kr.prototype.evaluate=function(){this.value=this.get(),this.dirty=!1},Kr.prototype.depend=function(){for(var t=this.deps.length;t--;)this.deps[t].depend()},Kr.prototype.teardown=function(){if(this.active){this.vm._isBeingDestroyed||l(this.vm._watchers,this);for(var t=this.deps.length;t--;)this.deps[t].removeSub(this);this.active=!1}};var Jr={enumerable:!0,configurable:!0,get:y,set:y},qr={lazy:!0};Nt(It.prototype);var Wr={init:function(t,n,r,i){if(!t.componentInstance||t.componentInstance._isDestroyed){(t.componentInstance=function(t,n,r,i){var o={_isComponent:!0,parent:n,_parentVnode:t,_parentElm:r||null,_refElm:i||null},a=t.data.inlineTemplate;return e(a)&&(o.render=a.render,o.staticRenderFns=a.staticRenderFns),new t.componentOptions.Ctor(o)}(t,Pr,r,i)).$mount(n?t.elm:void 0,n)}else if(t.data.keepAlive){var o=t;Wr.prepatch(o,o)}},prepatch:function(t,e){var n=e.componentOptions;!function(t,e,n,r,i){var o=!!(i||t.$options._renderChildren||r.data.scopedSlots||t.$scopedSlots!==jn);if(t.$options._parentVnode=r,t.$vnode=r,t._vnode&&(t._vnode.parent=r),t.$options._renderChildren=i,t.$attrs=r.data&&r.data.attrs||jn,t.$listeners=n||jn,e&&t.$options.props){Cr.shouldConvert=!1;for(var a=t._props,s=t.$options._propKeys||[],c=0;c1?v(n):n;for(var r=v(arguments,1),i=0,o=n.length;iparseInt(this.max)&&zt(a,s[0],s,this._vnode)),e.data.keepAlive=!0}return e||t&&t[0]}}};!function(t){var e={};e.get=function(){return Jn},Object.defineProperty(t,"config",e),t.util={warn:dr,extend:h,mergeOptions:F,defineReactive:E},t.set=j,t.delete=N,t.nextTick=q,t.options=Object.create(null),zn.forEach(function(e){t.options[e+"s"]=Object.create(null)}),t.options._base=t,h(t.options.components,ti),function(t){t.use=function(t){var e=this._installedPlugins||(this._installedPlugins=[]);if(e.indexOf(t)>-1)return this;var n=v(arguments,1);return n.unshift(this),"function"==typeof t.install?t.install.apply(t,n):"function"==typeof t&&t.apply(null,n),e.push(t),this}}(t),function(t){t.mixin=function(t){return this.options=F(this.options,t),this}}(t),Ht(t),function(t){zn.forEach(function(e){t[e]=function(t,n){return n?("component"===e&&o(n)&&(n.name=n.name||t,n=this.options._base.extend(n)),"directive"===e&&"function"==typeof n&&(n={bind:n,update:n}),this.options[e+"s"][t]=n,n):this.options[e+"s"][t]}})}(t)}(Rt),Object.defineProperty(Rt.prototype,"$isServer",{get:ur}),Object.defineProperty(Rt.prototype,"$ssrContext",{get:function(){return this.$vnode&&this.$vnode.ssrContext}}),Rt.version="2.5.11";var ei,ni,ri,ii,oi,ai,si,ci,ui=u("style,class"),li=u("input,textarea,option,select,progress"),fi=function(t,e,n){return"value"===n&&li(t)&&"button"!==e||"selected"===n&&"option"===t||"checked"===n&&"input"===t||"muted"===n&&"video"===t},di=u("contenteditable,draggable,spellcheck"),pi=u("allowfullscreen,async,autofocus,autoplay,checked,compact,controls,declare,default,defaultchecked,defaultmuted,defaultselected,defer,disabled,enabled,formnovalidate,hidden,indeterminate,inert,ismap,itemscope,loop,multiple,muted,nohref,noresize,noshade,novalidate,nowrap,open,pauseonexit,readonly,required,reversed,scoped,seamless,selected,sortable,translate,truespeed,typemustmatch,visible"),vi="http://www.w3.org/1999/xlink",hi=function(t){return":"===t.charAt(5)&&"xlink"===t.slice(0,5)},mi=function(t){return hi(t)?t.slice(6,t.length):""},yi=function(t){return null==t||!1===t},gi={svg:"http://www.w3.org/2000/svg",math:"http://www.w3.org/1998/Math/MathML"},_i=u("html,body,base,head,link,meta,style,title,address,article,aside,footer,header,h1,h2,h3,h4,h5,h6,hgroup,nav,section,div,dd,dl,dt,figcaption,figure,picture,hr,img,li,main,ol,p,pre,ul,a,b,abbr,bdi,bdo,br,cite,code,data,dfn,em,i,kbd,mark,q,rp,rt,rtc,ruby,s,samp,small,span,strong,sub,sup,time,u,var,wbr,area,audio,map,track,video,embed,object,param,source,canvas,script,noscript,del,ins,caption,col,colgroup,table,thead,tbody,td,th,tr,button,datalist,fieldset,form,input,label,legend,meter,optgroup,option,output,progress,select,textarea,details,dialog,menu,menuitem,summary,content,element,shadow,template,blockquote,iframe,tfoot"),bi=u("svg,animate,circle,clippath,cursor,defs,desc,ellipse,filter,font-face,foreignObject,g,glyph,image,line,marker,mask,missing-glyph,path,pattern,polygon,polyline,rect,switch,symbol,text,textpath,tspan,use,view",!0),$i=function(t){return _i(t)||bi(t)},Ci=Object.create(null),wi=u("text,number,password,search,email,tel,url"),xi=Object.freeze({createElement:function(t,e){var n=document.createElement(t);return"select"!==t?n:(e.data&&e.data.attrs&&void 0!==e.data.attrs.multiple&&n.setAttribute("multiple","multiple"),n)},createElementNS:function(t,e){return document.createElementNS(gi[t],e)},createTextNode:function(t){return document.createTextNode(t)},createComment:function(t){return document.createComment(t)},insertBefore:function(t,e,n){t.insertBefore(e,n)},removeChild:function(t,e){t.removeChild(e)},appendChild:function(t,e){t.appendChild(e)},parentNode:function(t){return t.parentNode},nextSibling:function(t){return t.nextSibling},tagName:function(t){return t.tagName},setTextContent:function(t,e){t.textContent=e},setAttribute:function(t,e,n){t.setAttribute(e,n)}}),ki={create:function(t,e){Xt(e)},update:function(t,e){t.data.ref!==e.data.ref&&(Xt(t,!0),Xt(e))},destroy:function(t){Xt(t,!0)}},Ai=new mr("",{},[]),Oi=["create","activate","update","remove","destroy"],Si={create:te,update:te,destroy:function(t){te(t,Ai)}},Ti=Object.create(null),Ei=[ki,Si],ji={create:re,update:re},Ni={create:oe,update:oe},Ii=/[\w).+\-_$\]]/,Li="__r",Mi="__c",Di={create:we,update:we},Pi={create:xe,update:xe},Fi=d(function(t){var e={},n=/:(.+)/;return t.split(/;(?![^(]*\))/g).forEach(function(t){if(t){var r=t.split(n);r.length>1&&(e[r[0].trim()]=r[1].trim())}}),e}),Ri=/^--/,Hi=/\s*!important$/,Bi=function(t,e,n){if(Ri.test(e))t.style.setProperty(e,n);else if(Hi.test(n))t.style.setProperty(e,n.replace(Hi,""),"important");else{var r=Vi(e);if(Array.isArray(n))for(var i=0,o=n.length;ip?v(n,t(i[g+1])?null:i[g+1].elm,i,d,g,o):d>g&&m(0,r,f,p)}function _(r,i,o,a){if(r!==i){var s=i.elm=r.elm;if(n(r.isAsyncPlaceholder))e(i.asyncFactory.resolved)?$(r.elm,i,o):i.isAsyncPlaceholder=!0;else if(n(i.isStatic)&&n(r.isStatic)&&i.key===r.key&&(n(i.isCloned)||n(i.isOnce)))i.componentInstance=r.componentInstance;else{var c,u=i.data;e(u)&&e(c=u.hook)&&e(c=c.prepatch)&&c(r,i);var l=r.children,d=i.children;if(e(u)&&f(i)){for(c=0;c-1?Ci[t]=e.constructor===window.HTMLUnknownElement||e.constructor===window.HTMLElement:Ci[t]=/HTMLUnknownElement/.test(e.toString())},h(Rt.options.directives,ro),h(Rt.options.components,so),Rt.prototype.__patch__=Gn?eo:y,Rt.prototype.$mount=function(t,e){return t=t&&Gn?Zt(t):void 0,function(t,e,n){t.$el=e,t.$options.render||(t.$options.render=gr),vt(t,"beforeMount");var r;return r=function(){t._update(t._render(),n)},new Kr(t,r,y,null,!0),n=!1,null==t.$vnode&&(t._isMounted=!0,vt(t,"mounted")),t}(this,t,e)},Rt.nextTick(function(){Jn.devtools&&lr&&lr.emit("init",Rt)},0);var co,uo=/\{\{((?:.|\n)+?)\}\}/g,lo=/[-.*+?^${}()|[\]\/\\]/g,fo=d(function(t){var e=t[0].replace(lo,"\\$&"),n=t[1].replace(lo,"\\$&");return new RegExp(e+"((?:.|\\n)+?)"+n,"g")}),po={staticKeys:["staticClass"],transformNode:function(t,e){e.warn;var n=ve(t,"class");n&&(t.staticClass=JSON.stringify(n));var r=pe(t,"class",!1);r&&(t.classBinding=r)},genData:function(t){var e="";return t.staticClass&&(e+="staticClass:"+t.staticClass+","),t.classBinding&&(e+="class:"+t.classBinding+","),e}},vo={staticKeys:["staticStyle"],transformNode:function(t,e){e.warn;var n=ve(t,"style");n&&(t.staticStyle=JSON.stringify(Fi(n)));var r=pe(t,"style",!1);r&&(t.styleBinding=r)},genData:function(t){var e="";return t.staticStyle&&(e+="staticStyle:"+t.staticStyle+","),t.styleBinding&&(e+="style:("+t.styleBinding+"),"),e}},ho=function(t){return co=co||document.createElement("div"),co.innerHTML=t,co.textContent},mo=u("area,base,br,col,embed,frame,hr,img,input,isindex,keygen,link,meta,param,source,track,wbr"),yo=u("colgroup,dd,dt,li,options,p,td,tfoot,th,thead,tr,source"),go=u("address,article,aside,base,blockquote,body,caption,col,colgroup,dd,details,dialog,div,dl,dt,fieldset,figcaption,figure,footer,form,h1,h2,h3,h4,h5,h6,head,header,hgroup,hr,html,legend,li,menuitem,meta,optgroup,option,param,rp,rt,source,style,summary,tbody,td,tfoot,th,thead,title,tr,track"),_o=/^\s*([^\s"'<>\/=]+)(?:\s*(=)\s*(?:"([^"]*)"+|'([^']*)'+|([^\s"'=<>`]+)))?/,bo="[a-zA-Z_][\\w\\-\\.]*",$o="((?:"+bo+"\\:)?"+bo+")",Co=new RegExp("^<"+$o),wo=/^\s*(\/?)>/,xo=new RegExp("^<\\/"+$o+"[^>]*>"),ko=/^]+>/i,Ao=/^ - - + + + + + diff --git a/editor.html b/editor.html index 43200cfe..90aafb87 100644 --- a/editor.html +++ b/editor.html @@ -4,6 +4,7 @@ + @@ -582,9 +583,11 @@ - - - + + + + + From 3b3195b9d40d0db7522b76abd6fce0be20a49eb8 Mon Sep 17 00:00:00 2001 From: oc Date: Thu, 4 Jul 2019 12:02:38 +0800 Subject: [PATCH 09/34] blockly auto complete --- _server/editor_blockly.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/_server/editor_blockly.js b/_server/editor_blockly.js index 36a84fb3..9ac2d906 100644 --- a/_server/editor_blockly.js +++ b/_server/editor_blockly.js @@ -976,9 +976,7 @@ Blockly.FieldTextInput.prototype.showInlineEditor_ = function(quietInput) { var list = editor_blockly.getAutoCompletions(value); awesomplete.list = list; - var coordinates = getCaretCoordinates(htmlInput, htmlInput.selectionStart, {debug: true}); - // console.log(coordinates); - awesomplete.ul.style.marginLeft = coordinates.left - + awesomplete.ul.style.marginLeft = getCaretCoordinates(htmlInput, htmlInput.selectionStart).left - htmlInput.scrollLeft - 20 + "px"; awesomplete.evaluate(); } From 224f7031cccd193b83c4a331a8ff402f4e27f42f Mon Sep 17 00:00:00 2001 From: oc Date: Thu, 4 Jul 2019 14:08:53 +0800 Subject: [PATCH 10/34] blockly auto complete --- _server/editor_blockly.js | 22 ++++++++++++++++++++-- _server/thirdparty/awesomplete.css | 1 + index.html | 2 +- 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/_server/editor_blockly.js b/_server/editor_blockly.js index 9ac2d906..83b155b6 100644 --- a/_server/editor_blockly.js +++ b/_server/editor_blockly.js @@ -805,7 +805,7 @@ function omitedcheckUpdateFunction(event) { var index = content.lastIndexOf(":"); if (index >= 0) { var before = content.substring(0, index), token = content.substring(index+1); - if (/^\w*$/.test(token)) { + if (/^[a-zA-Z0-9_\u4E00-\u9FCC]*$/.test(token)) { if (before.endsWith("status")) { return Object.keys(core.status.hero).filter(function (one) { return one != token && one.startsWith(token); @@ -850,6 +850,7 @@ function omitedcheckUpdateFunction(event) { return []; } + editor_blockly.completeItems = []; return editor_blockly; } @@ -939,14 +940,22 @@ Blockly.FieldTextInput.prototype.showInlineEditor_ = function(quietInput) { var awesomplete = new Awesomplete(htmlInput, { minChars: 4, maxItems: 12, + autoFirst: true, replace: function (text) { + text = text.toString(); var value = this.input.value, index = this.input.selectionEnd; if (index == null) index = value.length; + if (index < awesomplete.prefix.length) index = awesomplete.prefix.length; var str = value.substring(0, index - awesomplete.prefix.length) + text + value.substring(index); this.input.value = str; pb.setFieldValue(str, self.name); index += text.length - awesomplete.prefix.length; this.input.setSelectionRange(index, index); + + editor_blockly.completeItems = editor_blockly.completeItems.filter(function (x) { + return x != text; + }); + editor_blockly.completeItems.unshift(text); }, filter: function () {return true;}, item: function (text, input) { @@ -957,6 +966,15 @@ Blockly.FieldTextInput.prototype.showInlineEditor_ = function(quietInput) { if (input != "") text = text.replace(new RegExp("^"+input, "i"), "$&"); li.innerHTML = text; return li; + }, + sort: function (a, b) { + a = a.toString(); b = b.toString(); + var ia = editor_blockly.completeItems.indexOf(a), ib = editor_blockly.completeItems.indexOf(b); + if (ia < 0) ia = editor_blockly.completeItems.length; + if (ib < 0) ib = editor_blockly.completeItems.length; + if (ia != ib) return ia - ib; + if (a.length != b.length) return a.length - b.length; + return a < b ? -1 : 1; } }); @@ -968,7 +986,7 @@ Blockly.FieldTextInput.prototype.showInlineEditor_ = function(quietInput) { awesomplete.prefix = ""; for (var i = index - 1; i>=0; i--) { var c = value.charAt(i); - if (!/^\w$/.test(c)) { + if (!/^[a-zA-Z0-9_\u4E00-\u9FCC]$/.test(c)) { awesomplete.prefix = value.substring(i+1); break; } diff --git a/_server/thirdparty/awesomplete.css b/_server/thirdparty/awesomplete.css index 91bc2bdd..b36a7035 100644 --- a/_server/thirdparty/awesomplete.css +++ b/_server/thirdparty/awesomplete.css @@ -76,6 +76,7 @@ position: relative; padding: .2em .5em; cursor: pointer; + word-break: keep-all; } .awesomplete > ul > li:hover { diff --git a/index.html b/index.html index 06398202..a723dfba 100644 --- a/index.html +++ b/index.html @@ -152,7 +152,7 @@

请输入文字...

- +
From d9b905c9efa228fcbb96fe768c4a375fde7c7dc0 Mon Sep 17 00:00:00 2001 From: oc Date: Fri, 5 Jul 2019 00:01:54 +0800 Subject: [PATCH 11/34] changeFont --- libs/maps.js | 7 +++- libs/ui.js | 105 +++++++++++++++++++++++++++++++++++++-------------- 2 files changed, 82 insertions(+), 30 deletions(-) diff --git a/libs/maps.js b/libs/maps.js index 9d4e2298..3cda4b57 100644 --- a/libs/maps.js +++ b/libs/maps.js @@ -774,6 +774,7 @@ maps.prototype.drawBg = function (floorId, ctx) { if (onMap) { ctx = core.canvas.bg; core.clearMap(ctx); + core.status.floorAnimateObjs = this._getFloorImages(floorId); } core.maps._drawBg_drawBackground(floorId, ctx); // ------ 调整这两行的顺序来控制是先绘制贴图还是先绘制背景图块;后绘制的覆盖先绘制的。 @@ -813,7 +814,10 @@ maps.prototype.drawEvents = function (floorId, blocks, ctx) { maps.prototype.drawFg = function (floorId, ctx) { floorId = floorId || core.status.floorId; var onMap = ctx == null; - if (onMap) ctx = core.canvas.fg; + if (onMap) { + ctx = core.canvas.fg; + core.status.floorAnimateObjs = this._getFloorImages(floorId); + } // ------ 调整这两行的顺序来控制是先绘制贴图还是先绘制背景图块;后绘制的覆盖先绘制的。 this._drawFloorImages(floorId, ctx, 'fg'); this._drawBgFgMap(floorId, ctx, 'fg', onMap); @@ -861,7 +865,6 @@ maps.prototype._drawFloorImages = function (floorId, ctx, name, images, currStat floorId = floorId || core.status.floorId; if (!images) images = this._getFloorImages(floorId); var redraw = currStatus != null; - if (!redraw) core.status.floorAnimateObjs = core.clone(images); images.forEach(function (t) { if (typeof t == 'string') t = [0, 0, t]; var dx = parseInt(t[0]), dy = parseInt(t[1]), imageName = t[2], frame = core.clamp(parseInt(t[4]), 1, 8); diff --git a/libs/ui.js b/libs/ui.js index 49943fe3..a54595c3 100644 --- a/libs/ui.js +++ b/libs/ui.js @@ -847,11 +847,11 @@ ui.prototype._getDrawableIconInfo = function (id) { return [image,icon]; } -ui.prototype._buildFont = function (fontSize, bold) { +ui.prototype._buildFont = function (fontSize, bold, italic) { var textAttribute = core.status.textAttribute || core.initStatus.textAttribute, globalAttribute = core.status.globalAttribute || core.initStatus.globalAttribute; if (bold == null) bold = textAttribute.bold; - return (bold?"bold ":"") + (fontSize || textAttribute.textfont) + "px " + globalAttribute.font; + return (bold?"bold ":"") + (italic?"italic ":"") + (fontSize || textAttribute.textfont) + "px " + globalAttribute.font; } ////// 绘制一段文字到某个画布上面 @@ -862,16 +862,16 @@ ui.prototype._buildFont = function (fontSize, bold) { // fontSize:字体大小;lineHeight:行高;time:打字机间隔 ui.prototype.drawTextContent = function (ctx, content, config) { ctx = core.getContextByName(ctx); - if (!ctx) return; // 设置默认配置项 var textAttribute = core.status.textAttribute || core.initStatus.textAttribute; config = core.clone(config || {}); config.left = config.left || 0; - config.right = config.left + (config.maxWidth == null ? ctx.canvas.width : config.maxWidth); + config.right = config.left + (config.maxWidth == null ? (ctx != null ? ctx.canvas.width : core.__PIXELS__) : config.maxWidth) config.top = config.top || 0; config.color = config.color || textAttribute.text; if (config.color instanceof Array) config.color = core.arrayToRGBA(config.color); if (config.bold == null) config.bold = textAttribute.bold; + config.italic = false; config.align = config.align || textAttribute.align || "left"; config.fontSize = config.fontSize || textAttribute.textfont; config.lineHeight = config.lineHeight || (config.fontSize * 1.3); @@ -879,18 +879,23 @@ ui.prototype.drawTextContent = function (ctx, content, config) { config.index = 0; config.currcolor = config.color; + config.currfont = config.fontSize; + config.lineMargin = Math.max(0, config.lineHeight - config.fontSize); + config.topMargin = parseInt(config.lineMargin / 2); + config.lineMaxHeight = config.lineMargin + config.fontSize; config.offsetX = 0; config.offsetY = 0; config.line = 0; config.blocks = []; // 创建一个新的临时画布 - var tempCtx = core.createCanvas('__temp__', 0, 0, ctx.canvas.width, ctx.canvas.height, -1); + var tempCtx = core.createCanvas('__temp__', 0, 0, ctx==null?1:ctx.canvas.width, ctx==null?1:ctx.canvas.height, -1); tempCtx.textBaseline = 'top'; - tempCtx.font = this._buildFont(config.fontSize, config.bold); + tempCtx.font = this._buildFont(config.fontSize, config.bold, config.italic); tempCtx.fillStyle = config.color; - this._drawTextContent_draw(ctx, tempCtx, content, config); + config = this._drawTextContent_draw(ctx, tempCtx, content, config); core.deleteCanvas('__temp__'); + return config; } ui.prototype._uievent_drawTextContent = function (data) { @@ -908,13 +913,16 @@ ui.prototype._drawTextContent_draw = function (ctx, tempCtx, content, config) { // Step 1: 绘制到tempCtx上,并记录下图块信息 while (this._drawTextContent_next(tempCtx, content, config)); + if (ctx == null) return config; + // Step 2: 从tempCtx绘制到画布上 config.index = 0; var _drawNext = function () { if (config.index >= config.blocks.length) return false; var block = config.blocks[config.index++]; ctx.drawImage(tempCtx.canvas, block.left, block.top, block.width, block.height, - config.left + block.left + block.marginLeft, config.top + block.top, block.width, block.height); + config.left + block.left + block.marginLeft, config.top + block.top + block.marginTop, + block.width, block.height); return true; } if (config.time == 0) { @@ -928,6 +936,8 @@ ui.prototype._drawTextContent_draw = function (ctx, tempCtx, content, config) { } }, config.time); } + + return config; } ui.prototype._drawTextContent_next = function (tempCtx, content, config) { @@ -953,9 +963,22 @@ ui.prototype._drawTextContent_drawChar = function (tempCtx, content, config, ch) if (ch == '\\') config.index++; return this._drawTextContent_changeColor(tempCtx, content, config); } - // \\i 绘制图标 - if (ch == '\\' && content.charAt(config.index)=='i') { - return this._drawTextContent_drawIcon(tempCtx, content, config); + if (ch == '\\') { + var c = content.charAt(config.index); + if (c == 'i') return this._drawTextContent_drawIcon(tempCtx, content, config); + if (c == 'c') return this._drawTextContent_changeFont(tempCtx, content, config); + if (c == 'd' || c == 'e') { + config.index++; + if (c == 'd') config.bold = !config.bold; + if (c == 'e') config.italic = !config.italic; + tempCtx.font = this._buildFont(config.currfont, config.bold, config.italic); + return true; + } + } + // \\e 斜体切换 + if (ch == '\\' && content.charAt(config.index)=='e') { + config.italic = !config.italic; + tempCtx.font = this._buildFont(config.fontSize, config.bold, config.italic); } // 检查是不是自动换行 var charwidth = core.calWidth(tempCtx, ch); @@ -965,10 +988,11 @@ ui.prototype._drawTextContent_drawChar = function (tempCtx, content, config, ch) return this._drawTextContent_next(tempCtx, content, config); } // 输出 - var left = config.offsetX, top = config.offsetY + (config.lineHeight - config.fontSize) / 2; + var left = config.offsetX, top = config.offsetY + config.topMargin; core.fillText(tempCtx, ch, left, top); config.blocks.push({left: config.offsetX, top: config.offsetY, - width: charwidth, height: config.lineHeight, line: config.line, marginLeft: 0}); + width: charwidth, height: config.currfont + config.lineMargin, + line: config.line, marginLeft: 0}); config.offsetX += charwidth; return true; } @@ -983,12 +1007,17 @@ ui.prototype._drawTextContent_newLine = function (tempCtx, config) { marginLeft = totalWidth - width; config.blocks.forEach(function (b) { - if (b.line == config.line) + if (b.line == config.line) { b.marginLeft = marginLeft; + // b.marginTop = 0; // 上对齐 + b.marginTop = (config.lineMaxHeight - b.height) / 2; // 居中对齐 + // b.marginTop = config.lineMaxHeight - b.height; // 下对齐 + } }); config.offsetX = 0; - config.offsetY += config.lineHeight; + config.offsetY += config.lineMaxHeight; + config.lineMaxHeight = config.currfont + config.lineMargin; config.line++; } @@ -1006,6 +1035,22 @@ ui.prototype._drawTextContent_changeColor = function (tempCtx, content, config) return this._drawTextContent_next(tempCtx, content, config); } +ui.prototype._drawTextContent_changeFont = function (tempCtx, content, config) { + config.index++; + // 检查是不是 [] + var index = config.index, index2; + if (content.charAt(index) == '[' && ((index2=content.indexOf(']', index))>=0)) { + var str = content.substring(index+1, index2); + if (!/^\d+$/.test(str)) config.currfont = config.fontSize; + else config.currfont = parseInt(str); + config.index = index2 + 1; + } + else config.currfont = config.fontSize; + config.lineMaxHeight = Math.max(config.lineMaxHeight, config.currfont + config.lineMargin); + tempCtx.font = this._buildFont(config.currfont, config.bold, config.italic); + return this._drawTextContent_next(tempCtx, content, config); +} + ui.prototype._drawTextContent_drawIcon = function (tempCtx, content, config) { // 绘制一个 \i 效果 var index = config.index, index2; @@ -1015,17 +1060,18 @@ ui.prototype._drawTextContent_drawIcon = function (tempCtx, content, config) { var iconInfo = core.ui._getDrawableIconInfo(str), image = iconInfo[0], icon = iconInfo[1]; if (image == null) return this._drawTextContent_next(tempCtx, content, config); // 检查自动换行 - var width = config.fontSize + 2, left = config.offsetX + 2, top = config.offsetY + (config.lineHeight - width) / 2 - 1; + var width = config.currfont + 2, left = config.offsetX + 2, top = config.offsetY + config.topMargin - 1; if (config.maxWidth != null && left + width > config.maxWidth) { this._drawTextContent_newLine(tempCtx, config); config.index--; - this._drawTextContent_next(tempCtx, content, config); + return this._drawTextContent_next(tempCtx, content, config); } // 绘制到画布上 core.drawImage(tempCtx, image, 0, 32*icon, 32, 32, left, top, width, width); config.blocks.push({left: left, top: config.offsetY, - width: config.lineHeight, height: config.lineHeight, line: config.line, marginLeft: 0}); + width: width, height: width + config.lineMargin, + line: config.line, marginLeft: 0}); config.offsetX += width + 6; config.index = index2 + 1; @@ -1034,8 +1080,12 @@ ui.prototype._drawTextContent_drawIcon = function (tempCtx, content, config) { return this._drawTextContent_next(tempCtx, content, config); } +ui.prototype.getTextContentHeight = function (content, config) { + return this.drawTextContent(null, content, config).offsetY; +} + ui.prototype._getRealContent = function (content) { - return content.replace(/(\r|\\r)(\[.*?])?/g, "").replace(/(\\i)(\[.*?])?/g, "占1"); + return content.replace(/(\r|\\(r|c|d|e))(\[.*?])?/g, "").replace(/(\\i)(\[.*?])?/g, "占1"); } ////// 绘制一个对话框 ////// @@ -1069,7 +1119,7 @@ ui.prototype.drawTextBox = function(content, showAll) { var content_top = this._drawTextBox_drawTitleAndIcon(titleInfo, hPos, vPos, alpha); // Step 5: 绘制正文 - this.drawTextContent('ui', content, { + return this.drawTextContent('ui', content, { left: hPos.content_left, top: content_top, maxWidth: hPos.validWidth, lineHeight: vPos.lineHeight, time: (showAll || textAttribute.time<=0 || core.status.event.id!='action')?0:textAttribute.time }); @@ -1120,8 +1170,9 @@ ui.prototype._drawTextBox_getHorizontalPosition = function (content, titleInfo, ui.prototype._drawTextBox_getVerticalPosition = function (content, titleInfo, posInfo, validWidth) { var textAttribute = core.status.textAttribute || core.initStatus.textAttribute; var lineHeight = textAttribute.textfont + 6; - var realContent = this._getRealContent(content); - var height = 30 + lineHeight * core.splitLines("ui", realContent, validWidth, this._buildFont()).length; + var height = 30 + this.getTextContentHeight(content, { + lineHeight: lineHeight, maxWidth: validWidth + }); if (titleInfo.title) height += textAttribute.titlefont + 5; if (titleInfo.icon != null) { if (titleInfo.title) height = Math.max(height, titleInfo.height+50); @@ -1202,9 +1253,7 @@ ui.prototype._drawTextBox_drawTitleAndIcon = function (titleInfo, hPos, vPos, al } ui.prototype._createTextCanvas = function (content, lineHeight) { - var realContent = this._getRealContent(content); - var lines = core.splitLines('ui', realContent, null, this._buildFont()); - var width = this.PIXEL, height = lines.length * lineHeight; + var width = this.PIXEL, height = 30 + this.getTextContentHeight(content, {lineHeight: lineHeight}); var ctx = document.createElement('canvas').getContext('2d'); ctx.canvas.width = width; ctx.canvas.height = height; @@ -1304,10 +1353,10 @@ ui.prototype._drawChoices_getVerticalPosition = function (titleInfo, choices, hP var choice_top = bottom - height + 56; if (titleInfo.content) { var headHeight = 0; - var realContent = this._getRealContent(titleInfo.content); - var lines = core.splitLines('ui', realContent, hPos.validWidth, this._buildFont(15, true)); if (titleInfo.title) headHeight += 25; - headHeight += lines.length * 20; + headHeight += this.getTextContentHeight(titleInfo.content, { + lineHeight: 20, maxWidth: hPos.validWidth, fontSize: 15, bold: true + }); height += headHeight; if (bottom - height <= 32) { offset = Math.floor(headHeight / 64); From 3ba1ff07cfc04349490a9bcea4a431f6d06aa89f Mon Sep 17 00:00:00 2001 From: oc Date: Fri, 5 Jul 2019 00:23:42 +0800 Subject: [PATCH 12/34] changeFont --- API列表.txt | 10 +++++----- _docs/api.md | 11 ++++++----- _docs/element.md | 5 ++++- _docs/event.md | 14 +++++++++++++- _server/editor_blockly.js | 9 ++++----- libs/ui.js | 2 +- 6 files changed, 33 insertions(+), 18 deletions(-) diff --git a/API列表.txt b/API列表.txt index 8233a735..dd1f5990 100644 --- a/API列表.txt +++ b/API列表.txt @@ -1742,7 +1742,7 @@ id可选,为同时绘制的图标ID,如果不为null则会同时绘制该图 core.drawText(content, callback) 绘制一段文字。contents为一个字符串或一个字符串数组,callback为全部绘制完毕的回调。 -支持所有的文字效果(如\n,${},\r,\\i等),也支持\t和\b的语法。 +支持所有的文字效果(如\n,${},\r,\\i,\\c,\\d,\\e等),也支持\t和\b的语法。 如果当前在事件处理中或录像回放中,则会自动转成core.insertAction处理。 不建议使用该函数,如有绘制文字的需求请尽量使用core.insertAction()插入剧情文本事件。 @@ -1767,7 +1767,7 @@ posInfo如果不为null则是一个含position, px和py的对象,表示一个 core.drawTextContent(ctx, content, config) 根据配置在某个画布上绘制一段文字。此函数会被core.drawTextBox()所调用。 ctx为画布名或画布本身,如果不设置则会忽略该函数。 -content为要绘制的文字内容,支持所有的文字效果(如\n,${},\r,\\i等),但不支持支持\t和\b的语法。 +content为要绘制的文字内容,支持所有的文字效果(如\n,${},\r,\\i,\\c,\\d,\\e等),但不支持支持\t和\b的语法。 config为绘制的配置项,目前可以包括如下几项: - left, top:在该画布上绘制的左上角像素位置,不设置默认为(0,0)。 > 该函数绘制时会将textBaseline设置为'top',因此只需要考虑第一个字的左上角位置。 @@ -1782,7 +1782,7 @@ config为绘制的配置项,目前可以包括如下几项: core.drawTextBox(content, showAll) 绘制一个对话框。content为一个字符串或一个字符串数组。 -支持所有的文字效果(如\n,${},\r,\\i等),也支持\t和\b的语法。 +支持所有的文字效果(如\n,${},\r,\\i,\\c,\\d,\\e等),也支持\t和\b的语法。 该函数将使用用户在剧情文本设置中的配置项进行绘制。 实际执行时,会计算文本框宽度并绘制背景,绘制标题和头像,再调用core.drawTextContent()绘制正文内容。 showAll可选,如果为true则不会使用打字机效果而全部显示,主要用于打字机效果的点击显示全部。 @@ -1790,7 +1790,7 @@ showAll可选,如果为true则不会使用打字机效果而全部显示,主 core.drawScrollText(content, time, lineHeight, callback) 绘制一个滚动字幕。content为绘制内容,time为总时间(默认为5000),lineHeight为行距比例(默认为1.4)。 -滚动字幕将绘制在UI上,支持所有的文字效果(如\n,${},\r,\\i等),但不支持\t和\b效果。 +滚动字幕将绘制在UI上,支持所有的文字效果(如\n,${},\r,\\i,\\c,\\d,\\e等),但不支持\t和\b效果。 可以通过剧情文本设置中的align控制是否居中绘制,offset控制其距离左边的偏移量。 @@ -1802,7 +1802,7 @@ core.textImage(content, lineHeight) core.drawChoices(content, choices) 绘制一个选项框。 -content可选,为选项上方的提示文字,支持所有的文字效果(如\n,${},\r,\\i等),也支持\t效果。 +content可选,为选项上方的提示文字,支持所有的文字效果(如\n,${},\r,\\i,\\c,\\d,\\e等),也支持\t效果。 choices必选,为要绘制的选项内容,是一个列表。其中的每一项: - 可以是一个字符串,表示选项文字,将使用剧情文本设置中的正文颜色来绘制,仅支持${}表达式计算。 - 或者是一个包含text, color和icon的对象。 diff --git a/_docs/api.md b/_docs/api.md index c74a7267..8c5ddaa2 100644 --- a/_docs/api.md +++ b/_docs/api.md @@ -1721,7 +1721,7 @@ id可选,为同时绘制的图标ID,如果不为null则会同时绘制该图 core.drawText(content, callback) 绘制一段文字。contents为一个字符串或一个字符串数组,callback为全部绘制完毕的回调。 -支持所有的文字效果(如\n,${},\r,\\i等),也支持\t和\b的语法。 +支持所有的文字效果(如\n,${},\r,\\i,\\c,\\d,\\e等),也支持\t和\b的语法。 如果当前在事件处理中或录像回放中,则会自动转成core.insertAction处理。 不建议使用该函数,如有绘制文字的需求请尽量使用core.insertAction()插入剧情文本事件。 @@ -1746,7 +1746,8 @@ posInfo如果不为null则是一个含position, px和py的对象,表示一个 core.drawTextContent(ctx, content, config) 根据配置在某个画布上绘制一段文字。此函数会被core.drawTextBox()所调用。 ctx为画布名或画布本身,如果不设置则会忽略该函数。 -content为要绘制的文字内容,支持所有的文字效果(如\n,${},\r,\\i等),但不支持支持\t和\b的语法。 +content为要绘制的文字内容,支持所有的文字效果(如\n,${},\r,\\i,\\c,\\d,\\e等) + ,但不支持支持\t和\b的语法。 config为绘制的配置项,目前可以包括如下几项: - left, top:在该画布上绘制的左上角像素位置,不设置默认为(0,0)。 > 该函数绘制时会将textBaseline设置为'top',因此只需要考虑第一个字的左上角位置。 @@ -1761,7 +1762,7 @@ config为绘制的配置项,目前可以包括如下几项: core.drawTextBox(content, showAll) 绘制一个对话框。content为一个字符串或一个字符串数组。 -支持所有的文字效果(如\n,${},\r,\\i等),也支持\t和\b的语法。 +支持所有的文字效果(如\n,${},\r,\\i,\\c,\\d,\\e等),也支持\t和\b的语法。 该函数将使用用户在剧情文本设置中的配置项进行绘制。 实际执行时,会计算文本框宽度并绘制背景,绘制标题和头像,再调用core.drawTextContent()绘制正文内容。 showAll可选,如果为true则不会使用打字机效果而全部显示,主要用于打字机效果的点击显示全部。 @@ -1769,7 +1770,7 @@ showAll可选,如果为true则不会使用打字机效果而全部显示,主 core.drawScrollText(content, time, lineHeight, callback) 绘制一个滚动字幕。content为绘制内容,time为总时间(默认为5000),lineHeight为行距比例(默认为1.4)。 -滚动字幕将绘制在UI上,支持所有的文字效果(如\n,${},\r,\\i等),但不支持\t和\b效果。 +滚动字幕将绘制在UI上,支持所有的文字效果(如\n,${},\r,\\i,\\c,\\d,\\e等),但不支持\t和\b效果。 可以通过剧情文本设置中的align控制是否居中绘制,offset控制其距离左边的偏移量。 @@ -1781,7 +1782,7 @@ core.textImage(content, lineHeight) core.drawChoices(content, choices) 绘制一个选项框。 -content可选,为选项上方的提示文字,支持所有的文字效果(如\n,${},\r,\\i等),也支持\t效果。 +content可选,为选项上方的提示文字,支持所有的文字效果(如\n,${},\r,\\i,\\c,\\d,\\e等),也支持\t。 choices必选,为要绘制的选项内容,是一个列表。其中的每一项: - 可以是一个字符串,表示选项文字,将使用剧情文本设置中的正文颜色来绘制,仅支持${}表达式计算。 - 或者是一个包含text, color和icon的对象。 diff --git a/_docs/element.md b/_docs/element.md index bd2966de..32aa2b24 100644 --- a/_docs/element.md +++ b/_docs/element.md @@ -282,10 +282,13 @@ floorId指定的是目标楼层的唯一标识符(ID)。 - 使用`${}`来计算一个表达式的值,如`${status:atk+status:def}`。 - 使用`\f[...]`来同时插入一张立绘图,如`\f[1.png,100,200]`。 - 使用`\\i[...]`来在对话框中绘制一个图标,如`\\i[fly]`。 +- 使用`\\c[...]`来修改字体大小,如`\\b[16]`。 +- 使用`\\d`来加粗或者取消粗体。 +- 使用`\\e`来加斜体或取消斜体。 从V2.5.2开始,也允许绘制一张头像图在对话框中,只要通过`\t[1.png]`或`\t[标题,1.png]`的写法。 -**使用`\\i[...]`绘制图标请注意:在事件块中,允许只写一个反斜杠`\i`,系统会自动转义成`\\i`;但是在脚本中必须两个反斜杠都写上!** +**使用`\\i,\\c,\\d,\\e`时请注意:在事件块中,允许只写一个反斜杠`\`,系统会自动转义成`\\`;但是在脚本中必须两个反斜杠都写上!** 详细信息请参见[剧情文本控制](event#text:显示一段文字(剧情))中的说明。 diff --git a/_docs/event.md b/_docs/event.md index 51330cc4..f5120480 100644 --- a/_docs/event.md +++ b/_docs/event.md @@ -291,6 +291,18 @@ !> 注意,在事件块中,允许只写一个反斜杠`\i`,系统会自动转义成`\\i`;但是在脚本中必须两个反斜杠都写上! +从V2.6.3开始,也可以使用`\\c[...]`来切换当前字体,`\\d`来加粗或取消粗体,`\\e`来加斜体或取消斜体。 + +``` js +[ + "这是原始字体,\\c[20]使用20号字体,\\c[10]使用10号字体", + "\\c如果不加中括号则切换回原始字体。", + "\\d这是粗体\\d取消粗体,\\e加斜体\\e取消斜体" +] +``` + +!> 注意,在事件块中,允许只写一个反斜杠`\c`,系统会自动转义成`\\c`;但是在脚本中必须两个反斜杠都写上!`\d`和`\e`同理。 + 另外值得一提的是,我们是可以在文字中计算一个表达式的值的。只需要将表达式用 `${ }`整个括起来就可以。 ``` js @@ -2001,7 +2013,7 @@ UI绘制事件。 ] ``` -text必填,为要绘制的文本,支持所有的文字效果(如\n,${},\r,\\i等),但不支持支持\t和\b的语法。 +text必填,为要绘制的文本,支持所有的文字效果(如\n,${},\r,\\i,\\c,\\d,\\e等),但不支持支持\t和\b的语法。 left和top必填,为要绘制的起始像素坐标。实际绘制时会将textBaseline设置为'top',因此只需要考虑第一个字的左上角位置。 diff --git a/_server/editor_blockly.js b/_server/editor_blockly.js index 83b155b6..afe04fe2 100644 --- a/_server/editor_blockly.js +++ b/_server/editor_blockly.js @@ -389,7 +389,7 @@ function omitedcheckUpdateFunction(event) { } } try { - var code = Blockly.JavaScript.workspaceToCode(workspace).replace(/\\\\i/g, '\\\\\\\\i'); + var code = Blockly.JavaScript.workspaceToCode(workspace).replace(/\\\\(i|c|d|e)/g, '\\\\\\\\$1'); codeAreaHL.setValue(code); } catch (error) { codeAreaHL.setValue(String(error)); @@ -532,8 +532,7 @@ function omitedcheckUpdateFunction(event) { MotaActionFunctions.parse( eval('obj=' + codeAreaHL.getValue().replace(/[<>&]/g, function (c) { return {'<': '<', '>': '>', '&': '&'}[c]; - }).replace(/\\r/g, '\\\\r').replace(/\\f/g, '\\\\f') - .replace(/\\i/,'\\\\i')), + }).replace(/\\(r|f|i|c|d|e)/g,'\\\\$1')), document.getElementById('entryType').value ); } @@ -607,7 +606,7 @@ function omitedcheckUpdateFunction(event) { return; } var code = Blockly.JavaScript.workspaceToCode(editor_blockly.workspace); - code = code.replace(/\\i/g, '\\\\i'); + code = code.replace(/\\(i|c|d|e)/g, '\\\\$1'); eval('var obj=' + code); setvalue(JSON.stringify(obj)); } @@ -621,7 +620,7 @@ function omitedcheckUpdateFunction(event) { ]; if (b && types.indexOf(b.type)>=0) { try { - var code = "[" + Blockly.JavaScript.blockToCode(b).replace(/\\i/g, '\\\\i') + "]"; + var code = "[" + Blockly.JavaScript.blockToCode(b).replace(/\\(i|c|d|e)/g, '\\\\$1') + "]"; eval("var obj="+code); // console.log(obj); if (obj.length > 0 && b.type.startsWith(obj[0].type)) { diff --git a/libs/ui.js b/libs/ui.js index a54595c3..2050669b 100644 --- a/libs/ui.js +++ b/libs/ui.js @@ -856,7 +856,7 @@ ui.prototype._buildFont = function (fontSize, bold, italic) { ////// 绘制一段文字到某个画布上面 // ctx:要绘制到的画布 -// content:要绘制的内容;转义字符目前只允许留 \n, \r[...] 和 \i[...] +// content:要绘制的内容;转义字符目前只允许留 \n, \r[...], \i[...], \c[...], \d, \e // config:绘制配置项,目前暂时包含如下内容(均为可选) // left, top:起始点位置;maxWidth:单行最大宽度;color:默认颜色;align:左中右 // fontSize:字体大小;lineHeight:行高;time:打字机间隔 From 44b12e5c22e5d376bdf70842e683b560eb37a13c Mon Sep 17 00:00:00 2001 From: oc Date: Fri, 5 Jul 2019 00:29:43 +0800 Subject: [PATCH 13/34] 2.6.3 --- _docs/V2.0.md | 2 +- _docs/api.md | 2 +- _docs/element.md | 2 +- _docs/event.md | 2 +- _docs/index.md | 2 +- _docs/personalization.md | 2 +- _docs/script.md | 2 +- _docs/start.md | 2 +- main.js | 6 +++--- project/data.js | 2 +- 10 files changed, 12 insertions(+), 12 deletions(-) diff --git a/_docs/V2.0.md b/_docs/V2.0.md index 076c827c..30a38017 100644 --- a/_docs/V2.0.md +++ b/_docs/V2.0.md @@ -1,6 +1,6 @@ # V2.0版本介绍 -?> 目前版本**v2.6.2**,上次更新时间:* {docsify-updated} * +?> 目前版本**v2.6.3*,上次更新时间:* {docsify-updated} * 目前样板已经更新到V2.0版本以上,本章将对V2.0的一些内容进行介绍。 diff --git a/_docs/api.md b/_docs/api.md index 8c5ddaa2..5bcbe0ed 100644 --- a/_docs/api.md +++ b/_docs/api.md @@ -1,6 +1,6 @@ # 附录:API列表 -?> 目前版本**v2.6.2**,上次更新时间:* {docsify-updated} * +?> 目前版本**v2.6.3**,上次更新时间:* {docsify-updated} * 这里将列出所有被转发到core的API,没有被转发的函数此处不会列出,请自行在代码中查看。 diff --git a/_docs/element.md b/_docs/element.md index 32aa2b24..b7dca11d 100644 --- a/_docs/element.md +++ b/_docs/element.md @@ -1,6 +1,6 @@ # 元件说明 -?> 目前版本**v2.6.2**,上次更新时间:* {docsify-updated} * +?> 目前版本**v2.6.3**,上次更新时间:* {docsify-updated} * 在本章中,将对样板里的各个元件进行说明。各个元件主要包括道具、门、怪物、楼梯等等。 diff --git a/_docs/event.md b/_docs/event.md index f5120480..080108e4 100644 --- a/_docs/event.md +++ b/_docs/event.md @@ -1,6 +1,6 @@ # 事件 -?> 目前版本**v2.6.2**,上次更新时间:* {docsify-updated} * +?> 目前版本**v2.6.3**,上次更新时间:* {docsify-updated} * 本章内将对样板所支持的事件进行介绍。 diff --git a/_docs/index.md b/_docs/index.md index 131b9acd..74d241d7 100644 --- a/_docs/index.md +++ b/_docs/index.md @@ -1,6 +1,6 @@ # HTML5 魔塔样板说明文档 -?> 目前版本**v2.6.2**,上次更新时间:* {docsify-updated} * +?> 目前版本**v2.6.3**,上次更新时间:* {docsify-updated} * 众所周知,魔塔的趋势是向移动端发展,贴吧中也常常能见到“求手机魔塔”的帖子。然而现有的工具中,NekoRPG有着比较大的局限性,游戏感较差,更是完全没法在iOS上运行。而一些APP的魔塔虽然可用,但是必须要下载安装,对于Android和iOS还必须开发不同的版本,非常麻烦。 diff --git a/_docs/personalization.md b/_docs/personalization.md index f4bfb1ac..e6573e80 100644 --- a/_docs/personalization.md +++ b/_docs/personalization.md @@ -1,6 +1,6 @@ # 个性化 -?> 目前版本**v2.6.2**,上次更新时间:* {docsify-updated} * +?> 目前版本**v2.6.3**,上次更新时间:* {docsify-updated} * 有时候只靠样板本身可能是不够的。我们需要一些个性化、自定义的素材,道具效果,怪物属性,等等。 diff --git a/_docs/script.md b/_docs/script.md index cf277eed..44e31e2d 100644 --- a/_docs/script.md +++ b/_docs/script.md @@ -1,6 +1,6 @@ # 脚本 -?> 目前版本**v2.6.2**,上次更新时间:* {docsify-updated} * +?> 目前版本**v2.6.3**,上次更新时间:* {docsify-updated} * 在V2.6版本中,基本对整个项目代码进行了重写,更加方便造塔者的使用和复写函数。 diff --git a/_docs/start.md b/_docs/start.md index 61cf9ed8..ced7faa1 100644 --- a/_docs/start.md +++ b/_docs/start.md @@ -1,6 +1,6 @@ # 快速上手 -?> 目前版本**v2.6.2**,上次更新时间:* {docsify-updated} * +?> 目前版本**v2.6.3**,上次更新时间:* {docsify-updated} * 在这一节中,将详细介绍做一部塔的流程。现在,让我们来做一部单层塔! diff --git a/main.js b/main.js index 15673ecd..18a16b97 100644 --- a/main.js +++ b/main.js @@ -2,7 +2,7 @@ function main() { //------------------------ 用户修改内容 ------------------------// - this.version = "2.6.2"; // 游戏版本号;如果更改了游戏内容建议修改此version以免造成缓存问题。 + this.version = "2.6.3"; // 游戏版本号;如果更改了游戏内容建议修改此version以免造成缓存问题。 this.useCompress = false; // 是否使用压缩文件 // 当你即将发布你的塔时,请使用“JS代码压缩工具”将所有js代码进行压缩,然后将这里的useCompress改为true。 @@ -188,8 +188,8 @@ function main() { this.floors = {} this.canvas = {}; - this.__VERSION__ = "2.6.2"; - this.__VERSION_CODE__ = 54; + this.__VERSION__ = "2.6.3"; + this.__VERSION_CODE__ = 63; } main.prototype.init = function (mode, callback) { diff --git a/project/data.js b/project/data.js index dceadc87..9469147f 100644 --- a/project/data.js +++ b/project/data.js @@ -77,7 +77,7 @@ var data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d = "firstData": { "title": "魔塔样板", "name": "template", - "version": "Ver 2.6.2", + "version": "Ver 2.6.3", "floorId": "sample0", "hero": { "name": "阳光", From 0e877bd1b963454b73bce4b09901dc143df50361 Mon Sep 17 00:00:00 2001 From: oc Date: Fri, 5 Jul 2019 00:38:09 +0800 Subject: [PATCH 14/34] 2.6.3 --- README.md | 13 +++++++++++++ 更新说明.txt | 17 ++++++++++++++++- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index b95dbf49..290b38b3 100644 --- a/README.md +++ b/README.md @@ -55,6 +55,19 @@ HTML5 canvas制作的魔塔样板,支持全平台游戏! ## 更新说明 +### 2019.7.5 V2.6.3 + +* [x] 事件编辑器支持自动补全,能对flag和API列表等进行补全 +* [x] 剧情文本中\\c修改字体大小,\\d和\\e切换粗体和斜体 +* [x] 楼层传送器的平面传送模式(哪里离开飞回到哪里) +* [x] UI绘制事件增添绘制圆和绘制圆边框 +* [x] 所有的UI绘制事件均可以双击预览 +* [x] \f立绘支持alpha值 +* [x] 等待用户操作支持滚轮,视为PgUp和PgDn +* [x] 脚本编辑器语法错误将禁止保存 +* [x] 录像播放时B键查看数据统计 +* [x] 所有已知bug的修复,大量细节优化 + ### 2019.6.7 V2.6.2 * [x] 可以拖动地图上的图块和事件,复制剪切和跨楼层粘贴 diff --git a/更新说明.txt b/更新说明.txt index f973f575..1ad4ea48 100644 --- a/更新说明.txt +++ b/更新说明.txt @@ -1,4 +1,19 @@ -HTML5魔塔样板V2.6.2 +HTML5魔塔样板V2.6.3 + +事件编辑器支持自动补全,能对flag和API列表等进行补全 +剧情文本中\\c修改字体大小,\\d和\\e切换粗体和斜体 +楼层传送器的平面传送模式(哪里离开飞回到哪里) +UI绘制事件增添绘制圆和绘制圆边框 +所有的UI绘制事件均可以双击预览 +\f立绘支持alpha值 +等待用户操作支持滚轮,视为PgUp和PgDn +脚本编辑器语法错误将禁止保存 +录像播放时B键查看数据统计 +所有已知bug的修复,大量细节优化 + +----------------------------------------------------------------------- + +HTML5魔塔样板V2.6.2 可以拖动地图上的图块和事件,复制剪切和跨楼层粘贴 新增事件的地图选点功能,可以在地图上选择落点 From 5d279e375d80e602f726785776e0d224148ee5cc Mon Sep 17 00:00:00 2001 From: oc Date: Fri, 5 Jul 2019 23:20:25 +0800 Subject: [PATCH 15/34] dynamic choices & startReaply save & global flag --- API列表.txt | 2 +- _server/MotaAction.g4 | 9 +++++---- _server/editor_blockly.js | 4 ++-- libs/control.js | 2 +- libs/events.js | 23 +++++++++++++++++++++++ project/functions.js | 1 + project/items.js | 9 ++++++--- 7 files changed, 39 insertions(+), 11 deletions(-) diff --git a/API列表.txt b/API列表.txt index dd1f5990..9c8b2129 100644 --- a/API列表.txt +++ b/API列表.txt @@ -1,4 +1,4 @@ -附录:API列表(V2.6版) +附录:API列表(V2.6.3版) 这里将列出所有被转发到core的API,没有被转发的函数此处不会列出,请自行在代码中查看。 diff --git a/_server/MotaAction.g4 b/_server/MotaAction.g4 index 92a7a378..8d62eba8 100644 --- a/_server/MotaAction.g4 +++ b/_server/MotaAction.g4 @@ -1716,13 +1716,13 @@ return code; */; choicesContext - : '子选项' EvalString '图标' IdString? '颜色' EvalString? Colour BGNL? Newline action+ + : '子选项' EvalString '图标' IdString? '颜色' EvalString? Colour '出现条件' EvalString? BGNL? Newline action+ /* choicesContext tooltip : 选项的选择 helpUrl : https://h5mota.com/games/template/_docs/#/event?id=choices%EF%BC%9A%E7%BB%99%E7%94%A8%E6%88%B7%E6%8F%90%E4%BE%9B%E9%80%89%E9%A1%B9 -default : ["提示文字:红钥匙","",""] +default : ["提示文字:红钥匙","","",""] colour : this.subColor if (EvalString_1) { var colorRe = MotaActionFunctions.pattern.colorRe; @@ -1731,8 +1731,9 @@ if (EvalString_1) { else EvalString_1 = ', "color": "'+EvalString_1+'"'; } +EvalString_2 = EvalString_2 && (', "condition": "'+EvalString_2+'"') IdString_0 = IdString_0?(', "icon": "'+IdString_0+'"'):''; -var code = '{"text": "'+EvalString_0+'"'+IdString_0+EvalString_1+', "action": [\n'+action_0+']},\n'; +var code = '{"text": "'+EvalString_0+'"'+IdString_0+EvalString_1+EvalString_2+', "action": [\n'+action_0+']},\n'; return code; */; @@ -3169,7 +3170,7 @@ ActionParser.prototype.parseAction = function() { for(var ii=data.choices.length-1,choice;choice=data.choices[ii];ii--) { choice.color = this.Colour(choice.color); text_choices=MotaActionBlocks['choicesContext'].xmlText([ - choice.text,choice.icon,choice.color,'rgba('+choice.color+')',this.insertActionList(choice.action),text_choices]); + choice.text,choice.icon,choice.color,'rgba('+choice.color+')',choice.condition||'',this.insertActionList(choice.action),text_choices]); } if (!this.isset(data.text)) data.text = ''; var info = this.getTitleAndPosition(data.text); diff --git a/_server/editor_blockly.js b/_server/editor_blockly.js index afe04fe2..ebd20df0 100644 --- a/_server/editor_blockly.js +++ b/_server/editor_blockly.js @@ -76,9 +76,9 @@ editor_blockly = function () { MotaActionBlocks['confirm_s'].xmlText(), MotaActionBlocks['choices_s'].xmlText([ '选择剑或者盾','流浪者','man',MotaActionBlocks['choicesContext'].xmlText([ - '剑','','',null,MotaActionFunctions.actionParser.parseList([{"type": "openDoor", "loc": [3,3]}]), + '剑','','',null,'',MotaActionFunctions.actionParser.parseList([{"type": "openDoor", "loc": [3,3]}]), MotaActionBlocks['choicesContext'].xmlText([ - '盾','','',null,MotaActionFunctions.actionParser.parseList([{"type": "openDoor", "loc": [9,3]}]), + '盾','','',null,'',MotaActionFunctions.actionParser.parseList([{"type": "openDoor", "loc": [9,3]}]), ]) ]) ]), diff --git a/libs/control.js b/libs/control.js index 67f930f1..ba8247f5 100644 --- a/libs/control.js +++ b/libs/control.js @@ -1317,7 +1317,7 @@ control.prototype._replay_finished = function () { control.prototype._replay_save = function () { core.status.replay.steps++; - if (core.status.replay.steps%50==0) { + if (core.status.replay.steps%40==1) { if (core.status.replay.save.length == 30) core.status.replay.save.shift(); core.status.replay.save.push({"data": core.saveData(), "replay": { diff --git a/libs/events.js b/libs/events.js index 8326714d..db925b61 100644 --- a/libs/events.js +++ b/libs/events.js @@ -458,6 +458,24 @@ events.prototype.getItem = function (id, num, x, y, callback) { if (num > 1) text += "x" + num; if (itemCls === 'items') text += core.items.getItemEffectTip(id); core.drawTip(text, id); + + // --- 首次获得道具的提示 + if (!core.hasFlag("__itemHint__")) core.setFlag("__itemHint__", []); + var itemHint = core.getFlag("__itemHint__"); + if (itemHint.indexOf(id) < 0 && itemCls != 'items') { + var hint = core.material.items[id].text || "该道具暂无描述"; + try { + hint = core.replaceText(hint); + } catch (e) {} + core.insertAction("\t["+core.material.items[id].name+","+id+"]" + hint + "\n" + + (itemCls == 'keys' || id == 'greenKey' || id == 'steelKey' ? "(钥匙类道具,遇到对应的门时自动打开)" + : itemCls == 'tools' ? "(消耗类道具,请按T在道具栏使用)" + : itemCls == 'constants' ? "(永久类道具,请按T在道具栏使用)" + : itemCls == 'equips' ? "(装备类道具,请按Q在装备栏进行装备)" : "")) + itemHint.push(id); + } + + core.updateStatusBar(); this.afterGetItem(id, x, y, callback); @@ -1385,6 +1403,11 @@ events.prototype._action_switch = function (data, x, y, prefix) { } events.prototype._action_choices = function (data, x, y, prefix) { + data.choices = data.choices.filter(function (x) { + if (x.condition == null || x.condition == '') return true; + try { return core.calValue(x.condition, prefix); } catch (e) { return true; } + }) + if (data.choices.length == 0) return this.doAction(); if (core.isReplaying()) { var action = core.status.replay.toReplay.shift(), index; // --- 忽略可能的turn事件 diff --git a/project/functions.js b/project/functions.js index 65b5e6f0..9b9bdc5f 100644 --- a/project/functions.js +++ b/project/functions.js @@ -15,6 +15,7 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = core.status.played = true; // 初始化人物,图标,统计信息 core.status.hero = core.clone(hero); + window.flags = core.status.hero.flags; core.events.setHeroIcon(core.getFlag('heroIcon', 'hero.png'), true); core.control._initStatistics(core.animateFrame.totalTime); core.status.hero.statistics.totalTime = core.animateFrame.totalTime = diff --git a/project/items.js b/project/items.js index bc656898..1c5b4c7f 100644 --- a/project/items.js +++ b/project/items.js @@ -3,15 +3,18 @@ var items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a = "items": { "yellowKey": { "cls": "keys", - "name": "黄钥匙" + "name": "黄钥匙", + "text": "可以打开一扇黄门" }, "blueKey": { "cls": "keys", - "name": "蓝钥匙" + "name": "蓝钥匙", + "text": "可以打开一扇蓝门" }, "redKey": { "cls": "keys", - "name": "红钥匙" + "name": "红钥匙", + "text": "可以打开一扇红门" }, "redJewel": { "cls": "items", From c6c8cd91ec0b9c870a9b4fa4e2c923b83e5867c4 Mon Sep 17 00:00:00 2001 From: oc Date: Sat, 6 Jul 2019 00:54:16 +0800 Subject: [PATCH 16/34] startButtons css --- _server/table/data.comment.js | 6 ++++++ libs/actions.js | 2 ++ libs/control.js | 2 ++ main.js | 36 +++++++++++++++++++++++++++++++++++ project/data.js | 3 ++- styles.css | 29 ++++++++++++++++++---------- 6 files changed, 67 insertions(+), 11 deletions(-) diff --git a/_server/table/data.comment.js b/_server/table/data.comment.js index f6457473..3e1bacf1 100644 --- a/_server/table/data.comment.js +++ b/_server/table/data.comment.js @@ -63,6 +63,12 @@ var data_comment_c456ea59_6018_45ef_8bcc_211a24c627dc = { "_string": true, "_data": "标题样式:可以改变颜色,也可以写\"display: none\"来隐藏标题" }, + "startButtonsStyle": { + "_leaf": true, + "_type": "textarea", + "_string": true, + "_data": "标题界面按钮的样式;caret-color指的是当前选中项的边框颜色" + }, "levelChoose": { "_leaf": true, "_type": "textarea", diff --git a/libs/actions.js b/libs/actions.js index 3814f333..51eefbab 100644 --- a/libs/actions.js +++ b/libs/actions.js @@ -137,6 +137,7 @@ actions.prototype._sys_onkeyDown = function (e) { return; } } + e.preventDefault(); core.status.holdingKeys.push(e.keyCode); this.pressKey(e.keyCode); } else { @@ -198,6 +199,7 @@ actions.prototype._sys_onkeyUp = function (e) { break; } } + e.preventDefault(); this.keyUp(e.keyCode, e.altKey); } else { if (e.keyCode == 17) core.status.ctrlDown = false; diff --git a/libs/control.js b/libs/control.js index ba8247f5..50d25713 100644 --- a/libs/control.js +++ b/libs/control.js @@ -337,6 +337,8 @@ control.prototype._showStartAnimate_resetDom = function () { control.prototype._showStartAnimate_finished = function (start, callback) { core.dom.startTop.style.display = 'none'; core.dom.startButtonGroup.style.display = 'block'; + main.selectedButton = null; + main.selectButton(0); if (start) core.startGame(); if (callback) callback(); } diff --git a/main.js b/main.js index 18a16b97..e4cf16c4 100644 --- a/main.js +++ b/main.js @@ -204,6 +204,7 @@ main.prototype.init = function (mode, callback) { main.dom.startBackground.src="project/images/"+main.startBackground; main.dom.startLogo.style=main.startLogoStyle; + main.dom.startButtonGroup.style = main.startButtonsStyle; main.levelChoose.forEach(function(value){ var span = document.createElement('span'); span.setAttribute('class','startButton'); @@ -327,6 +328,29 @@ main.prototype.log = function (e) { } } +////// 选项 ////// +main.prototype.selectButton = function (index) { + var select = function (children) { + index = (index + children.length) % children.length; + for (var i = 0;i < children.length; ++i) { + children[i].style.borderColor = 'transparent'; + } + children[index].style.borderColor = main.dom.startButtonGroup.style.caretColor || '#FFD700'; + if (main.selectedButton == index) { + children[index].click(); + } + else { + main.selectedButton = index; + } + } + + if (main.dom.startButtons.style.display == 'block') { + select(main.dom.startButtons.children); + } + else if (main.dom.levelChooseButtons.style.display == 'block') { + select(main.dom.levelChooseButtons.children); + } +} main.prototype.listen = function () { @@ -348,6 +372,16 @@ main.dom.body.onkeydown = function(e) { ////// 在界面上放开某按键时 ////// main.dom.body.onkeyup = function(e) { + if (main.dom.startButtons.style.display == 'block' || main.dom.levelChooseButtons.style.display == 'block') { + if (e.keyCode == 38 || e.keyCode == 33) // up/pgup + main.selectButton((main.selectedButton||0) - 1); + else if (e.keyCode == 40 || e.keyCode == 34) // down/pgdn + main.selectButton((main.selectedButton||0) + 1); + else if (e.keyCode == 67 || e.keyCode == 13 || e.keyCode == 32) // C/Enter/Space + main.selectButton(main.selectedButton); + return; + } + try { if (main.dom.inputDiv.style.display == 'block') return; if (main.core && (main.core.isPlaying() || main.core.status.lockControl)) @@ -649,6 +683,8 @@ main.dom.playGame.onclick = function () { } else { main.dom.levelChooseButtons.style.display='block'; + main.selectedButton = null; + main.selectButton(0); } } diff --git a/project/data.js b/project/data.js index 9469147f..29c59b80 100644 --- a/project/data.js +++ b/project/data.js @@ -72,7 +72,8 @@ var data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d = "hardLabelColor": "red", "floorChangingBackground": "black", "floorChangingTextColor": "white", - "font": "Verdana" + "font": "Verdana", + "startButtonsStyle": "background-color: #32369F; opacity: 0.85; color: #FFFFFF; border: #FFFFFF 2px solid; caret-color: #FFD700;" }, "firstData": { "title": "魔塔样板", diff --git a/styles.css b/styles.css index a1d6649e..ccdb83cb 100644 --- a/styles.css +++ b/styles.css @@ -117,16 +117,25 @@ } #startButtonGroup { - width: 100%; + width: auto; position: absolute; text-align: center; font-size: 1.4rem; - background-color: #000; - opacity: 0.85; display: none; z-index: 310; bottom: 0; - margin-bottom: 7%; + margin-bottom: 5%; + left: 50%; + transform: translateX(-50%); + padding: 15px 25px; + min-width: 20%; + /* default value */ + background-color: #32369F; + opacity: 0.85; + color: #FFFFFF; + border: #FFFFFF 2px solid; + caret-color: #FFD700; + border-radius: 10px; } #startButtons { @@ -139,15 +148,15 @@ .startButton { width: 100%; - margin: 20px 0; - color: #fff; + margin: 0; font-weight: bold; display: block; cursor: pointer; -} - -.startButton:hover { - color: #ff0000; + padding: 4px 0; + border-color: transparent; + border-width: 2px; + border-style: solid; + border-radius: 6px; } #floorMsgGroup { From 931e24e1dac62252ff7c9be5c532e9654d880cad Mon Sep 17 00:00:00 2001 From: oc Date: Sat, 6 Jul 2019 01:07:05 +0800 Subject: [PATCH 17/34] open single shop directly --- libs/events.js | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/libs/events.js b/libs/events.js index db925b61..8e9a9046 100644 --- a/libs/events.js +++ b/libs/events.js @@ -1819,6 +1819,21 @@ events.prototype.openToolbox = function (fromUserAction) { ////// 点击快捷商店按钮时的打开操作 ////// events.prototype.openQuickShop = function (fromUserAction) { if (core.isReplaying()) return; + + // --- 如果只有一个商店,则直接打开之 + if (Object.keys(core.status.shops).length == 1) { + var shopId = Object.keys(core.status.shops)[0]; + if (core.status.event.id != null) return; + if (!this._checkStatus('shop', false)) return; + var reason = core.events.canUseQuickShop(shopId); + if (!core.flags.enableDisabledShop && reason) { + core.drawText(reason); + return; + } + core.events.openShop(shopId, true); + return; + } + if (!this._checkStatus('selectShop', fromUserAction)) return; core.ui.drawQuickShop(); } From 9619325d128fd6883e30b7c73c16c51d2a05991f Mon Sep 17 00:00:00 2001 From: oc Date: Sat, 6 Jul 2019 01:20:31 +0800 Subject: [PATCH 18/34] playBgm keep --- _docs/event.md | 2 ++ _server/MotaAction.g4 | 9 +++++---- libs/events.js | 9 +++++++-- project/functions.js | 6 ++++-- 4 files changed, 18 insertions(+), 8 deletions(-) diff --git a/_docs/event.md b/_docs/event.md index 080108e4..eef54da8 100644 --- a/_docs/event.md +++ b/_docs/event.md @@ -1433,6 +1433,8 @@ async可选,如果为true则会异步执行(即不等待当前事件执行 目前支持mp3/ogg/wav等多种格式的音乐播放。 +从V2.6.3开始,还提供了keep项。如果此项为真,则会记录该bgm,并且持续到下次调用本事件位置(楼层切换不改变bgm,读档也有效)。 + 有关BGM播放的详细说明参见[背景音乐](element#背景音乐) ### pauseBgm:暂停背景音乐 diff --git a/_server/MotaAction.g4 b/_server/MotaAction.g4 index 8d62eba8..27bacb0f 100644 --- a/_server/MotaAction.g4 +++ b/_server/MotaAction.g4 @@ -1468,15 +1468,16 @@ return code; */; playBgm_s - : '播放背景音乐' EvalString Newline + : '播放背景音乐' EvalString '持续到下个本事件' Bool Newline /* playBgm_s 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"] +default : ["bgm.mp3", true] colour : this.soundColor -var code = '{"type": "playBgm", "name": "'+EvalString_0+'"},\n'; +Bool_0 = Bool_0 ? ', "keep": true' : ''; +var code = '{"type": "playBgm", "name": "'+EvalString_0+'"'+Bool_0+'},\n'; return code; */; @@ -3069,7 +3070,7 @@ ActionParser.prototype.parseAction = function() { break; case "playBgm": this.next = MotaActionBlocks['playBgm_s'].xmlText([ - data.name,this.next]); + data.name,data.keep||false,this.next]); break case "pauseBgm": this.next = MotaActionBlocks['pauseBgm_s'].xmlText([ diff --git a/libs/events.js b/libs/events.js index 8e9a9046..0c30dfb0 100644 --- a/libs/events.js +++ b/libs/events.js @@ -1261,6 +1261,7 @@ events.prototype._action_insert = function (data, x, y, prefix) { events.prototype._action_playBgm = function (data, x, y, prefix) { core.playBgm(data.name); + core.setFlag("__bgm__", data.keep ? data.name : null); core.doAction(); } @@ -1820,11 +1821,15 @@ events.prototype.openToolbox = function (fromUserAction) { events.prototype.openQuickShop = function (fromUserAction) { if (core.isReplaying()) return; + if (Object.keys(core.status.shops).length == 0) { + core.drawTip("本塔没有快捷商店!"); + return; + } + // --- 如果只有一个商店,则直接打开之 if (Object.keys(core.status.shops).length == 1) { var shopId = Object.keys(core.status.shops)[0]; - if (core.status.event.id != null) return; - if (!this._checkStatus('shop', false)) return; + if (core.status.event.id != null || !this._checkStatus('shop', false)) return; var reason = core.events.canUseQuickShop(shopId); if (!core.flags.enableDisabledShop && reason) { core.drawText(reason); diff --git a/project/functions.js b/project/functions.js index 9b9bdc5f..774e6b9e 100644 --- a/project/functions.js +++ b/project/functions.js @@ -142,7 +142,7 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = if (core.status.maps[floorId].bgm) { var bgm = core.status.maps[floorId].bgm; if (bgm instanceof Array) bgm = bgm[0]; - core.playBgm(bgm); + if (!core.hasFlag("__bgm__")) core.playBgm(bgm); } // 更改画面色调 var color = core.getFlag('__color__', null); @@ -1004,7 +1004,9 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = // 切换到对应的楼层 core.changeFloor(data.floorId, null, data.hero.loc, 0, function () { // TODO:可以在这里设置读档后播放BGM - // if (core.getFlag("bgm", 0)==1) core.playBgm("bgm.mp3"); + if (core.hasFlag("__bgm__")) { // 持续播放 + core.playBgm(core.getFlag("__bgm__")); + } if (callback) callback(); }, true); From ddfc725856a6ef93b4ea730251ddb6fe54c8e707 Mon Sep 17 00:00:00 2001 From: oc Date: Sat, 6 Jul 2019 01:29:25 +0800 Subject: [PATCH 19/34] v2.6.3 --- README.md | 9 +++++++-- 更新说明.txt | 5 +++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 290b38b3..4d83c518 100644 --- a/README.md +++ b/README.md @@ -57,12 +57,17 @@ HTML5 canvas制作的魔塔样板,支持全平台游戏! ### 2019.7.5 V2.6.3 +* [x] 标题界面大幅美化,支持键盘开始游戏 * [x] 事件编辑器支持自动补全,能对flag和API列表等进行补全 * [x] 剧情文本中\\c修改字体大小,\\d和\\e切换粗体和斜体 +* [x] 可以指定每个选择项的出现条件,动态生成 * [x] 楼层传送器的平面传送模式(哪里离开飞回到哪里) -* [x] UI绘制事件增添绘制圆和绘制圆边框 -* [x] 所有的UI绘制事件均可以双击预览 +* [x] UI绘制事件增添绘制圆(边框),且可直接双击预览 +* [x] 播放BGM事件可以一直持续播放直到下次调用 * [x] \f立绘支持alpha值 +* [x] 只有一个全局商店时V键能直接打开 +* [x] 支持在脚本编辑中直接flags.xxx调用自定义变量 +* [x] 首次获得道具将给予提示 * [x] 等待用户操作支持滚轮,视为PgUp和PgDn * [x] 脚本编辑器语法错误将禁止保存 * [x] 录像播放时B键查看数据统计 diff --git a/更新说明.txt b/更新说明.txt index 1ad4ea48..8e690e8e 100644 --- a/更新说明.txt +++ b/更新说明.txt @@ -1,11 +1,16 @@ HTML5魔塔样板V2.6.3 +标题界面大幅美化,支持键盘开始游戏 事件编辑器支持自动补全,能对flag和API列表等进行补全 剧情文本中\\c修改字体大小,\\d和\\e切换粗体和斜体 +可以指定每个选择项的出现条件,动态生成 楼层传送器的平面传送模式(哪里离开飞回到哪里) UI绘制事件增添绘制圆和绘制圆边框 所有的UI绘制事件均可以双击预览 +播放BGM事件可以一直持续播放直到下次调用 \f立绘支持alpha值 +支持在脚本编辑中直接flags.xxx调用自定义变量 +首次获得道具将给予提示 等待用户操作支持滚轮,视为PgUp和PgDn 脚本编辑器语法错误将禁止保存 录像播放时B键查看数据统计 From 6190b6e37732b35f29e0ca3cd5149c50fa24fc68 Mon Sep 17 00:00:00 2001 From: oc Date: Sat, 6 Jul 2019 08:39:11 +0800 Subject: [PATCH 20/34] Fix main.js bug --- main.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/main.js b/main.js index e4cf16c4..d5b70a61 100644 --- a/main.js +++ b/main.js @@ -344,6 +344,8 @@ main.prototype.selectButton = function (index) { } } + if (core.dom.startPanel.style.display != 'block') return; + if (main.dom.startButtons.style.display == 'block') { select(main.dom.startButtons.children); } @@ -372,7 +374,8 @@ main.dom.body.onkeydown = function(e) { ////// 在界面上放开某按键时 ////// main.dom.body.onkeyup = function(e) { - if (main.dom.startButtons.style.display == 'block' || main.dom.levelChooseButtons.style.display == 'block') { + if (core.dom.startPanel.style.display == 'block' && + (main.dom.startButtons.style.display == 'block' || main.dom.levelChooseButtons.style.display == 'block')) { if (e.keyCode == 38 || e.keyCode == 33) // up/pgup main.selectButton((main.selectedButton||0) - 1); else if (e.keyCode == 40 || e.keyCode == 34) // down/pgdn From 834e987212f3fbc5a8472ae5174c558f6629bdae Mon Sep 17 00:00:00 2001 From: oc Date: Sat, 6 Jul 2019 09:18:57 +0800 Subject: [PATCH 21/34] Fix main.js --- main.js | 52 ++++++++++++++++++++++++++-------------------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/main.js b/main.js index d5b70a61..e19c4143 100644 --- a/main.js +++ b/main.js @@ -374,20 +374,33 @@ main.dom.body.onkeydown = function(e) { ////// 在界面上放开某按键时 ////// main.dom.body.onkeyup = function(e) { - if (core.dom.startPanel.style.display == 'block' && - (main.dom.startButtons.style.display == 'block' || main.dom.levelChooseButtons.style.display == 'block')) { - if (e.keyCode == 38 || e.keyCode == 33) // up/pgup - main.selectButton((main.selectedButton||0) - 1); - else if (e.keyCode == 40 || e.keyCode == 34) // down/pgdn - main.selectButton((main.selectedButton||0) + 1); - else if (e.keyCode == 67 || e.keyCode == 13 || e.keyCode == 32) // C/Enter/Space - main.selectButton(main.selectedButton); - return; - } - try { - if (main.dom.inputDiv.style.display == 'block') return; - if (main.core && (main.core.isPlaying() || main.core.status.lockControl)) + if (main.dom.startPanel.style.display == 'block' && + (main.dom.startButtons.style.display == 'block' || main.dom.levelChooseButtons.style.display == 'block')) { + if (e.keyCode == 38 || e.keyCode == 33) // up/pgup + main.selectButton((main.selectedButton||0) - 1); + else if (e.keyCode == 40 || e.keyCode == 34) // down/pgdn + main.selectButton((main.selectedButton||0) + 1); + else if (e.keyCode == 67 || e.keyCode == 13 || e.keyCode == 32) // C/Enter/Space + main.selectButton(main.selectedButton); + e.stopPropagation(); + return; + } + if (main.dom.inputDiv.style.display == 'block') { + if (e.keyCode == 13) { + setTimeout(function () { + main.dom.inputYes.click(); + }, 50); + } + else if (e.keyCode == 27) { + setTimeout(function () { + main.dom.inputNo.click(); + }, 50); + } + return; + } + if (main.core && main.core.isPlaying && main.core.status && + (main.core.isPlaying() || main.core.status.lockControl)) main.core.onkeyUp(e); } catch (ee) { main.log(ee); } } @@ -732,19 +745,6 @@ main.dom.inputNo.onclick = function () { if (func) func(null); } -main.dom.inputDiv.onkeyup = function (e) { - if (e.keyCode == 13) { - setTimeout(function () { - main.dom.inputYes.click(); - }, 50); - } - else if (e.keyCode == 27) { - setTimeout(function () { - main.dom.inputNo.click(); - }, 50); - } -} - }//listen end var main = new main(); \ No newline at end of file From 7732b367497b3298c5c1dfac49e00371bef15659 Mon Sep 17 00:00:00 2001 From: oc Date: Sat, 6 Jul 2019 09:58:32 +0800 Subject: [PATCH 22/34] fix inputdiv --- libs/utils.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libs/utils.js b/libs/utils.js index daea03ea..6c99e3bb 100644 --- a/libs/utils.js +++ b/libs/utils.js @@ -914,7 +914,8 @@ utils.prototype.myconfirm = function (hint, yesCallback, noCallback) { main.dom.inputDiv.style.display = 'block'; main.dom.inputMessage.innerHTML = hint.replace(/\n/g, '
'); main.dom.inputBox.style.display = 'none'; - main.dom.inputYes.focus(); + main.dom.inputYes.blur(); + main.dom.inputNo.blur(); core.status.holdingKeys = []; core.platform.successCallback = yesCallback; @@ -927,6 +928,8 @@ utils.prototype.myprompt = function (hint, value, callback) { main.dom.inputMessage.innerHTML = hint.replace(/\n/g, '
'); main.dom.inputBox.style.display = 'block'; main.dom.inputBox.value = value==null?"":value; + main.dom.inputYes.blur(); + main.dom.inputNo.blur(); setTimeout(function () { main.dom.inputBox.focus(); }); From 519b76eb480e5672174f85a24a7c64b9f3547815 Mon Sep 17 00:00:00 2001 From: oc Date: Sat, 6 Jul 2019 15:34:20 +0800 Subject: [PATCH 23/34] fix changeFloor onDownInterval --- libs/events.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libs/events.js b/libs/events.js index 0c30dfb0..4d61b05a 100644 --- a/libs/events.js +++ b/libs/events.js @@ -528,6 +528,8 @@ events.prototype.changeFloor = function (floorId, stair, heroLoc, time, callback core.stopAutomaticRoute(); core.clearContinueAutomaticRoute(); core.status.replay.animate = true; + clearInterval(core.interval.onDownInterval); + core.interval.onDownInterval = 'tmp'; this._changeFloor_beforeChange(info, callback); } From bb28ba72b97010e00016e3e45875ae436e289a36 Mon Sep 17 00:00:00 2001 From: oc Date: Sun, 7 Jul 2019 09:49:33 +0800 Subject: [PATCH 24/34] extendKeyBoard --- API列表.txt | 1 - _docs/api.md | 1 - libs/actions.js | 9 --------- libs/control.js | 2 +- libs/core.js | 2 -- libs/ui.js | 1 - main.js | 2 +- 7 files changed, 2 insertions(+), 16 deletions(-) diff --git a/API列表.txt b/API列表.txt index 9c8b2129..52e1a2b0 100644 --- a/API列表.txt +++ b/API列表.txt @@ -56,7 +56,6 @@ core.platform.isPC (是否是电脑端) core.platform.isAndroid (是否是安卓端) core.platform.isIOS (是否是iOS端) core.platform.useLocalForage (是否开启了新版存档) -core.platform.extendKeyBoard (是否开启了拓展键盘) core.domStyle diff --git a/_docs/api.md b/_docs/api.md index 5bcbe0ed..980c3b3a 100644 --- a/_docs/api.md +++ b/_docs/api.md @@ -57,7 +57,6 @@ core.platform.isPC (是否是电脑端) core.platform.isAndroid (是否是安卓端) core.platform.isIOS (是否是iOS端) core.platform.useLocalForage (是否开启了新版存档) -core.platform.extendKeyBoard (是否开启了拓展键盘) core.domStyle diff --git a/libs/actions.js b/libs/actions.js index 51eefbab..09b44ce2 100644 --- a/libs/actions.js +++ b/libs/actions.js @@ -1934,8 +1934,6 @@ actions.prototype._clickSwitchs = function (x, y) { case 7: return this._clickSwitchs_clickMove(); case 8: - return this._clickSwitchs_ExtendKeyboard(); - case 9: core.status.event.selection = 0; core.ui.drawSettings(); break; @@ -2000,13 +1998,6 @@ actions.prototype._clickSwitchs_clickMove = function () { core.ui.drawSwitchs(); } -actions.prototype._clickSwitchs_ExtendKeyboard = function () { - core.platform.extendKeyboard = !core.platform.extendKeyboard; - core.setLocalStorage('extendKeyboard', core.platform.extendKeyboard); - core.updateStatusBar(); - core.ui.drawSwitchs(); -} - ////// 系统设置界面时,放开某个键的操作 ////// actions.prototype._keyUpSwitchs = function (keycode) { if (keycode == 27 || keycode == 88) { diff --git a/libs/control.js b/libs/control.js index 50d25713..8c672646 100644 --- a/libs/control.js +++ b/libs/control.js @@ -2465,7 +2465,7 @@ control.prototype.setToolbarButton = function (useButton) { } if (useButton == null) useButton = core.domStyle.toolbarBtn; - if (!core.domStyle.isVertical || !core.platform.extendKeyboard) useButton = false; + if (!core.domStyle.isVertical) useButton = false; core.domStyle.toolbarBtn = useButton; if (useButton) { diff --git a/libs/core.js b/libs/core.js index be98ccfe..6cbe83cf 100644 --- a/libs/core.js +++ b/libs/core.js @@ -72,7 +72,6 @@ function core() { 'isChrome': false, // 是否是Chrome 'supportCopy': false, // 是否支持复制到剪切板 'useLocalForage': true, - 'extendKeyboard': false, 'fileInput': null, // FileInput 'fileReader': null, // 是否支持FileReader @@ -285,7 +284,6 @@ core.prototype._init_platform = function () { core.platform.isQQ = /QQ/i.test(navigator.userAgent); core.platform.isWeChat = /MicroMessenger/i.test(navigator.userAgent); this._init_checkLocalForage(); - core.platform.extendKeyboard = core.getLocalStorage("extendKeyboard", false); if (window.FileReader) { core.platform.fileReader = new FileReader(); core.platform.fileReader.onload = function () { diff --git a/libs/ui.js b/libs/ui.js index 2050669b..e4e79e7d 100644 --- a/libs/ui.js +++ b/libs/ui.js @@ -1507,7 +1507,6 @@ ui.prototype.drawSwitchs = function() { "领域显伤: "+(core.flags.displayExtraDamage ? "[ON]" : "[OFF]"), "新版存档: "+(core.platform.useLocalForage ? "[ON]":"[OFF]"), "单击瞬移: "+(!core.hasFlag("__noClickMove__") ? "[ON]":"[OFF]"), - "拓展键盘: "+(core.platform.extendKeyboard ? "[ON]":"[OFF]"), "返回主菜单" ]; this.drawChoices(null, choices); diff --git a/main.js b/main.js index e19c4143..fff02c79 100644 --- a/main.js +++ b/main.js @@ -642,7 +642,7 @@ main.statusBar.image.settings.onclick = function (e) { } ////// 点击工具栏时 ////// -main.dom.toolBar.onclick = function () { +main.dom.hard.onclick = function () { if (core.isReplaying()) return; main.core.control.setToolbarButton(!core.domStyle.toolbarBtn); From 0b5de8ccb106bfade19d6af977ee76565cba46b5 Mon Sep 17 00:00:00 2001 From: oc Date: Tue, 9 Jul 2019 12:52:40 +0800 Subject: [PATCH 25/34] css onChoice animate --- libs/control.js | 2 +- libs/ui.js | 2 -- main.js | 23 +++++++++++++++++++++-- styles.css | 25 ++++++++++++++++++++++++- 4 files changed, 46 insertions(+), 6 deletions(-) diff --git a/libs/control.js b/libs/control.js index 8c672646..294a2adf 100644 --- a/libs/control.js +++ b/libs/control.js @@ -19,7 +19,7 @@ control.prototype._init = function () { this.registerAnimationFrame("totalTime", false, this._animationFrame_totalTime); this.registerAnimationFrame("autoSave", true, this._animationFrame_autoSave); this.registerAnimationFrame("globalAnimate", true, this._animationFrame_globalAnimate); - this.registerAnimationFrame("selector", false, this._animationFrame_selector); + //this.registerAnimationFrame("selector", false, this._animationFrame_selector); this.registerAnimationFrame("animate", true, this._animationFrame_animate); this.registerAnimationFrame("heroMoving", true, this._animationFrame_heroMoving); this.registerAnimationFrame("weather", true, this._animationFrame_weather); diff --git a/libs/ui.js b/libs/ui.js index e4e79e7d..7391eea5 100644 --- a/libs/ui.js +++ b/libs/ui.js @@ -640,7 +640,6 @@ ui.prototype._getPosition = function (content) { ui.prototype.drawWindowSelector = function(background, x, y, w, h) { w = Math.round(w), h = Math.round(h); var ctx = core.ui.createCanvas("_selector", x, y, w, h, 165); - ctx.canvas.style.opacity = 0.8; this._drawSelector(ctx, background, w, h); } @@ -662,7 +661,6 @@ ui.prototype._uievent_drawSelector = function (data) { var z = 136; if (core.dymCanvas.uievent) z = (parseInt(core.dymCanvas.uievent.canvas.style.zIndex) || 135) + 1; var ctx = core.createCanvas('_uievent_selector', x, y, w, h, z); - ctx.canvas.style.opacity = 0.8; this._drawSelector(ctx, background, w, h); } diff --git a/main.js b/main.js index fff02c79..32948c93 100644 --- a/main.js +++ b/main.js @@ -216,6 +216,7 @@ main.prototype.init = function (mode, callback) { })(span,value[1]); main.dom.levelChooseButtons.appendChild(span); }); + main.createOnChoiceAnimation(); main.loadJs('libs', main.loadList, function () { main.core = core; @@ -328,14 +329,32 @@ main.prototype.log = function (e) { } } +main.prototype.createOnChoiceAnimation = function () { + var borderColor = main.dom.startButtonGroup.style.caretColor || "rgb(255, 215, 0)"; + // get rgb value + var rgb = /^rgba?\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(,\s*\d+\s*)?\)$/.exec(borderColor); + if (rgb != null) { + var value = rgb[1] + ", " + rgb[2] + ", " + rgb[3]; + var style = document.createElement("style"); + style.type = 'text/css'; + var keyFrames = "onChoice { " + + "0% { border-color: rgba("+value+", 0.9); } " + + "50% { border-color: rgba("+value+", 0.3); } " + + "100% { border-color: rgba("+value+", 0.9); } " + + "}"; + style.innerHTML = "@-webkit-keyframes " + keyFrames + " @keyframes " + keyFrames; + document.body.appendChild(style); + } +} + ////// 选项 ////// main.prototype.selectButton = function (index) { var select = function (children) { index = (index + children.length) % children.length; for (var i = 0;i < children.length; ++i) { - children[i].style.borderColor = 'transparent'; + children[i].classList.remove("onChoiceAnimate"); } - children[index].style.borderColor = main.dom.startButtonGroup.style.caretColor || '#FFD700'; + children[index].classList.add("onChoiceAnimate"); if (main.selectedButton == index) { children[index].click(); } diff --git a/styles.css b/styles.css index ccdb83cb..19d546ed 100644 --- a/styles.css +++ b/styles.css @@ -159,6 +159,11 @@ border-radius: 6px; } +.onChoiceAnimate { + animation: 2s ease-in-out 0s infinite normal none running; + animation-name: onChoice; +} + #floorMsgGroup { top: 3px; right: 3px; @@ -374,4 +379,22 @@ p#name { #inputNo { float:right; margin-right: 10%; -} \ No newline at end of file +} + +#_selector, #_uievent_selector { + animation: 2s ease-in-out 0s infinite normal none running; + animation-name: selector; +} + +@-webkit-keyframes selector { + 0% { opacity: 0.95; } + 50% { opacity: 0.55; } + 100% { opacity: 0.95; } +} + +@keyframes selector { + 0% { opacity: 0.95; } + 50% { opacity: 0.55; } + 100% { opacity: 0.95; } +} + From 9491ab92877d48e5497f0078b75967cdb423ea05 Mon Sep 17 00:00:00 2001 From: oc Date: Tue, 9 Jul 2019 16:08:44 +0800 Subject: [PATCH 26/34] drawTextBox next --- editor-mobile.html | 1 + editor.html | 1 + index.html | 1 + libs/control.js | 23 +++++------------------ libs/ui.js | 15 +++++++++++++-- main.js | 3 ++- styles.css | 34 ++++++++++++++++++++++++++++++---- 7 files changed, 53 insertions(+), 25 deletions(-) diff --git a/editor-mobile.html b/editor-mobile.html index d6ccc0ae..b8d2e0eb 100644 --- a/editor-mobile.html +++ b/editor-mobile.html @@ -515,6 +515,7 @@ 此浏览器不支持HTML5 +
diff --git a/libs/control.js b/libs/control.js index 294a2adf..a4aa24e4 100644 --- a/libs/control.js +++ b/libs/control.js @@ -19,7 +19,6 @@ control.prototype._init = function () { this.registerAnimationFrame("totalTime", false, this._animationFrame_totalTime); this.registerAnimationFrame("autoSave", true, this._animationFrame_autoSave); this.registerAnimationFrame("globalAnimate", true, this._animationFrame_globalAnimate); - //this.registerAnimationFrame("selector", false, this._animationFrame_selector); this.registerAnimationFrame("animate", true, this._animationFrame_animate); this.registerAnimationFrame("heroMoving", true, this._animationFrame_heroMoving); this.registerAnimationFrame("weather", true, this._animationFrame_weather); @@ -151,23 +150,6 @@ control.prototype._animationFrame_globalAnimate = function (timestamp) { core.animateFrame.globalTime = timestamp; } -control.prototype._animationFrame_selector = function (timestamp) { - if (timestamp - core.animateFrame.selectorTime <= 20) return; - var opacity = null; - if (core.dymCanvas._selector) opacity = parseFloat(core.dymCanvas._selector.canvas.style.opacity); - else if (core.dymCanvas._uievent_selector) opacity = parseFloat(core.dymCanvas._uievent_selector.canvas.style.opacity); - if (!core.isset(opacity)) return; - if (core.animateFrame.selectorUp) - opacity += 0.02; - else - opacity -= 0.02; - if (opacity > 0.95 || opacity < 0.55) - core.animateFrame.selectorUp = !core.animateFrame.selectorUp; - core.setOpacity("_selector", opacity); - core.setOpacity("_uievent_selector", opacity); - core.animateFrame.selectorTime = timestamp; -} - control.prototype._animationFrame_animate = function (timestamp) { if (timestamp - core.animateFrame.animateTime < 50 || !core.status.animateObjs || core.status.animateObjs.length == 0) return; core.clearMap('animate'); @@ -2648,6 +2630,11 @@ control.prototype._resize_canvas = function (obj) { canvas.style.left = parseFloat(canvas.getAttribute("_left")) * core.domStyle.scale + "px"; canvas.style.top = parseFloat(canvas.getAttribute("_top")) * core.domStyle.scale + "px"; } + // resize next + main.dom.next.style.width = main.dom.next.style.height = 5 * core.domStyle.scale + "px"; + main.dom.next.style.borderBottomWidth = main.dom.next.style.borderRightWidth = 4 * core.domStyle.scale + "px"; + + } control.prototype._resize_statusBar = function (obj) { diff --git a/libs/ui.js b/libs/ui.js index 7391eea5..46738a4f 100644 --- a/libs/ui.js +++ b/libs/ui.js @@ -452,6 +452,7 @@ ui.prototype.closePanel = function () { ui.prototype.clearUI = function () { core.status.boxAnimateObjs = []; if (core.dymCanvas._selector) core.deleteCanvas("_selector"); + main.dom.next.style.display = 'none'; core.clearMap('ui'); core.setAlpha('ui', 1); } @@ -1117,10 +1118,20 @@ ui.prototype.drawTextBox = function(content, showAll) { var content_top = this._drawTextBox_drawTitleAndIcon(titleInfo, hPos, vPos, alpha); // Step 5: 绘制正文 - return this.drawTextContent('ui', content, { + var config = this.drawTextContent('ui', content, { left: hPos.content_left, top: content_top, maxWidth: hPos.validWidth, lineHeight: vPos.lineHeight, time: (showAll || textAttribute.time<=0 || core.status.event.id!='action')?0:textAttribute.time }); + + // Step 6: 绘制光标 + main.dom.next.style.display = 'block'; + main.dom.next.style.borderRightColor = main.dom.next.style.borderBottomColor = core.arrayToRGB(textAttribute.text); + main.dom.next.style.top = (vPos.bottom - 20) * core.domStyle.scale + "px"; + var left = (hPos.left + hPos.right) / 2; + if (pInfo.position == 'up' && pInfo.px != null && Math.abs(pInfo.px * 32 + 16 - left) < 50) + left = hPos.right - 64; + main.dom.next.style.left = left * core.domStyle.scale + "px"; + return config; } ui.prototype._drawTextBox_drawImages = function (content) { @@ -1168,7 +1179,7 @@ ui.prototype._drawTextBox_getHorizontalPosition = function (content, titleInfo, ui.prototype._drawTextBox_getVerticalPosition = function (content, titleInfo, posInfo, validWidth) { var textAttribute = core.status.textAttribute || core.initStatus.textAttribute; var lineHeight = textAttribute.textfont + 6; - var height = 30 + this.getTextContentHeight(content, { + var height = 45 + this.getTextContentHeight(content, { lineHeight: lineHeight, maxWidth: validWidth }); if (titleInfo.title) height += textAttribute.titlefont + 5; diff --git a/main.js b/main.js index 32948c93..1434550c 100644 --- a/main.js +++ b/main.js @@ -74,7 +74,8 @@ function main() { 'inputMessage': document.getElementById('inputMessage'), 'inputBox': document.getElementById('inputBox'), 'inputYes': document.getElementById('inputYes'), - 'inputNo': document.getElementById('inputNo') + 'inputNo': document.getElementById('inputNo'), + 'next': document.getElementById('next') }; this.mode = 'play'; this.loadList = [ diff --git a/styles.css b/styles.css index 19d546ed..3a428992 100644 --- a/styles.css +++ b/styles.css @@ -160,8 +160,7 @@ } .onChoiceAnimate { - animation: 2s ease-in-out 0s infinite normal none running; - animation-name: onChoice; + animation: onChoice 2s ease-in-out 0s infinite normal none running; } #floorMsgGroup { @@ -382,8 +381,7 @@ p#name { } #_selector, #_uievent_selector { - animation: 2s ease-in-out 0s infinite normal none running; - animation-name: selector; + animation: selector 2s ease-in-out 0s infinite normal none running; } @-webkit-keyframes selector { @@ -398,3 +396,31 @@ p#name { 100% { opacity: 0.95; } } +#next { + width: 5px; + height: 5px; + display: none; + position: absolute; + transform: rotate(45deg); + border-bottom-width: 4px; + border-bottom-style: solid; + border-right-width: 4px; + border-right-style: solid; + -webkit-animation: next .5s ease-in-out alternate infinite; + animation: next .5s ease-in-out alternate infinite; + left: 0; + top: 0; + opacity: 0.7; + z-index: 169; +} + +@-webkit-keyframes next { + 100% { + transform: rotate(45deg) translate(-3px, -3px); + } +} +@keyframes next { + 100% { + transform: rotate(45deg) translate(-3px, -3px); + } +} \ No newline at end of file From 83828e57a7f6d9b0e4b7bdc9067d3dcc405641ca Mon Sep 17 00:00:00 2001 From: oc Date: Tue, 9 Jul 2019 16:22:57 +0800 Subject: [PATCH 27/34] drag bg/fg --- _server/editor.js | 36 ++++++++++++++++++++++++++++++++++++ _server/editor_unsorted_1.js | 5 ++++- 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/_server/editor.js b/_server/editor.js index 033187da..cb7490a3 100644 --- a/_server/editor.js +++ b/_server/editor.js @@ -556,6 +556,42 @@ editor.prototype.exchangePos = function (startPos, endPos, callback) { }); } +editor.prototype.moveBgFg = function (startPos, endPos, name, callback) { + if (!startPos || !endPos || ["bgmap","fgmap"].indexOf(name)<0) return; + if (startPos.x == endPos.x && startPos.y == endPos.y) return; + editor[name][endPos.y][endPos.x] = editor[name][startPos.y][startPos.x]; + editor[name][startPos.y][startPos.x] = 0; + editor.updateMap(); + editor.file.saveFloorFile(function (err) { + if (err) { + printe(err); + throw(err) + } + ;printf('移动图块成功'); + editor.drawPosSelection(); + if (callback) callback(); + }); +} + +editor.prototype.exchangeBgFg = function (startPos, endPos, name, callback) { + if (!startPos || !endPos || ["bgmap","fgmap"].indexOf(name)<0) return; + if (startPos.x == endPos.x && startPos.y == endPos.y) return; + var value = editor[name][endPos.y][endPos.x]; + editor[name][endPos.y][endPos.x] = editor[name][startPos.y][startPos.x]; + editor[name][startPos.y][startPos.x] = value; + editor.updateMap(); + editor.file.saveFloorFile(function (err) { + if (err) { + printe(err); + throw(err) + } + ;printf('交换图块成功'); + editor.drawPosSelection(); + if (callback) callback(); + }); + +} + editor.prototype.clearPos = function (clearPos, pos, callback) { var fields = Object.keys(editor.file.comment._data.floors._data.loc._data); pos = pos || editor.pos; diff --git a/_server/editor_unsorted_1.js b/_server/editor_unsorted_1.js index 73955ab2..d3b4c5c0 100644 --- a/_server/editor_unsorted_1.js +++ b/_server/editor_unsorted_1.js @@ -209,7 +209,10 @@ editor.constructor.prototype.listen=function () { if (!selectBox.isSelected()) { //tip.whichShow(1); // editor.movePos(startPos, endPos); - editor.exchangePos(startPos, endPos); + if (editor.layerMod == 'map') + editor.exchangePos(startPos, endPos); + else + editor.exchangeBgFg(startPos, endPos, editor.layerMod); startPos = endPos = null; uc.clearRect(0, 0, core.__PIXELS__, core.__PIXELS__); return false; From 7de3964525a27a3e001416e23efb88cb17b4c255 Mon Sep 17 00:00:00 2001 From: oc Date: Tue, 9 Jul 2019 17:20:07 +0800 Subject: [PATCH 28/34] setBlock multiple locs --- _server/MotaAction.g4 | 60 ++++++++++++++++++++++++++++++------ _server/editor_blockly.js | 16 ++++++++-- _server/editor_unsorted_1.js | 5 ++- _server/editor_unsorted_3.js | 2 +- libs/events.js | 12 +++++--- 5 files changed, 76 insertions(+), 19 deletions(-) diff --git a/_server/MotaAction.g4 b/_server/MotaAction.g4 index 27bacb0f..4deab014 100644 --- a/_server/MotaAction.g4 +++ b/_server/MotaAction.g4 @@ -756,7 +756,7 @@ return code; */; setBlock_s - : '转变图块为' EvalString 'x' PosString? ',' 'y' PosString? '楼层' IdString? Newline + : '转变图块为' EvalString 'x' EvalString? ',' 'y' EvalString? '楼层' IdString? Newline /* setBlock_s @@ -765,8 +765,21 @@ helpUrl : https://h5mota.com/games/template/_docs/#/event?id=setblock%EF%BC%9A%E colour : this.mapColor default : ["yellowDoor","","",""] var floorstr = ''; -if (PosString_0 && PosString_1) { - floorstr = ', "loc": ['+PosString_0+','+PosString_1+']'; +if (EvalString_1 && EvalString_2) { + var pattern1 = MotaActionFunctions.pattern.id; + if(pattern1.test(EvalString_1) || pattern1.test(EvalString_2)){ + EvalString_1=MotaActionFunctions.PosString_pre(EvalString_1); + EvalString_2=MotaActionFunctions.PosString_pre(EvalString_2); + EvalString_1=[EvalString_1,EvalString_2] + } else { + var pattern2 = /^([+-]?\d+)(,[+-]?\d+)*$/; + if(!pattern2.test(EvalString_1) || !pattern2.test(EvalString_2))throw new Error('坐标格式错误,请右键点击帮助查看格式'); + EvalString_1=EvalString_1.split(','); + EvalString_2=EvalString_2.split(','); + if(EvalString_1.length!==EvalString_2.length)throw new Error('坐标格式错误,请右键点击帮助查看格式'); + for(var ii=0;ii Date: Tue, 9 Jul 2019 20:23:52 +0800 Subject: [PATCH 29/34] setViewport & moveViewport --- _server/MotaAction.g4 | 45 ++++++++++++++++++++++++++++++++++++++- _server/editor_blockly.js | 2 ++ libs/control.js | 43 +++++++++++++++++++++++++++++++++++++ libs/events.js | 17 ++++++++++++++- 4 files changed, 105 insertions(+), 2 deletions(-) diff --git a/_server/MotaAction.g4 b/_server/MotaAction.g4 index 4deab014..e7001609 100644 --- a/_server/MotaAction.g4 +++ b/_server/MotaAction.g4 @@ -293,6 +293,8 @@ action | changeFloor_s | changePos_0_s | changePos_1_s + | setViewport_s + | moveViewport_s | useItem_s | openShop_s | disableShop_s @@ -1241,6 +1243,38 @@ var code = '{"type": "animate", "name": "'+IdString_0+'"'+EvalString_0+async+'}, return code; */; +setViewport_s + : '设置视角' '左上角坐标' 'x' PosString? ',' 'y' PosString? Newline + + +/* setViewport_s +tooltip : setViewport: 设置视角 +helpUrl : https://h5mota.com/games/template/_docs/#/event?id=changepos%EF%BC%9A%E5%BD%93%E5%89%8D%E4%BD%8D%E7%BD%AE%E5%88%87%E6%8D%A2%E5%8B%87%E5%A3%AB%E8%BD%AC%E5%90%91 +default : ["",""] +colour : this.soundColor +var loc = ''; +if (PosString_0 && PosString_1) { + loc = ', "loc": ['+PosString_0+','+PosString_1+']'; +} +var code = '{"type": "setViewport"'+loc+'},\n'; +return code; +*/; + +moveViewport_s + : '移动视角' '动画时间' Int? '不等待执行完毕' Bool BGNL? StepString Newline + + +/* moveViewport_s +tooltip : moveViewport:移动视角 +helpUrl : https://h5mota.com/games/template/_docs/#/event?id=movehero%EF%BC%9A%E7%A7%BB%E5%8A%A8%E5%8B%87%E5%A3%AB +default : [300,false,"上右3下2左"] +colour : this.soundColor +Int_0 = Int_0!=='' ?(', "time": '+Int_0):''; +Bool_0 = Bool_0?', "async": true':''; +var code = '{"type": "moveViewport"'+Int_0+Bool_0+', "steps": '+JSON.stringify(StepString_0)+'},\n'; +return code; +*/; + showImage_s : '显示图片' '图片编号' Int '图片' EvalString BGNL? '绘制的起点像素' 'x' PosString 'y' PosString '不透明度' Number '时间' Int '不等待执行完毕' Bool Newline @@ -2993,6 +3027,15 @@ ActionParser.prototype.parseAction = function() { this.next = MotaActionBlocks['animate_s'].xmlText([ data.name,animate_loc,data.async||false,this.next]); break; + case "setViewport": // 设置视角 + data.loc = data.loc||['','']; + this.next = MotaActionBlocks['setViewport_s'].xmlText([ + data.loc[0],data.loc[1],this.next]); + break; + case "moveViewport": // 移动视角 + this.next = MotaActionBlocks['moveViewport_s'].xmlText([ + data.time||0,data.async||false,this.StepString(data.steps),this.next]); + break; case "vibrate": // 画面震动 this.next = MotaActionBlocks['vibrate_s'].xmlText([data.time||0, data.async||false, this.next]); break; @@ -3547,7 +3590,7 @@ MotaActionFunctions.IdString_pre = function(IdString){ MotaActionFunctions.PosString_pre = function(PosString){ if (!PosString || /^-?\d+$/.test(PosString)) return PosString; - if (!(MotaActionFunctions.pattern.id.test(PosString)))throw new Error(PosString+'中包含了0-9 a-z A-Z _ 和中文之外的字符,或者是没有以flag: 开头'); + //if (!(MotaActionFunctions.pattern.id.test(PosString)))throw new Error(PosString+'中包含了0-9 a-z A-Z _ 和中文之外的字符,或者是没有以flag: 开头'); return '"'+PosString+'"'; } diff --git a/_server/editor_blockly.js b/_server/editor_blockly.js index 2f813293..1bdf8a76 100644 --- a/_server/editor_blockly.js +++ b/_server/editor_blockly.js @@ -150,6 +150,8 @@ editor_blockly = function () { MotaActionBlocks['waitAsync_s'].xmlText(), MotaActionBlocks['vibrate_s'].xmlText(), MotaActionBlocks['animate_s'].xmlText(), + MotaActionBlocks['setViewport_s'].xmlText(), + MotaActionBlocks['moveViewport_s'].xmlText(), MotaActionBlocks['showStatusBar_s'].xmlText(), MotaActionBlocks['hideStatusBar_s'].xmlText(), MotaActionBlocks['setCurtain_0_s'].xmlText(), diff --git a/libs/control.js b/libs/control.js index a4aa24e4..3823e105 100644 --- a/libs/control.js +++ b/libs/control.js @@ -779,6 +779,7 @@ control.prototype.drawHero = function (status, offset) { }); core.control.updateViewport(); + core.setGameCanvasTranslate('hero', 0, 0); } control.prototype._drawHero_getDrawObjs = function (direction, x, y, status, offset) { @@ -852,6 +853,48 @@ control.prototype.updateViewport = function() { core.relocateCanvas('route', core.status.automaticRoute.offsetX - core.bigmap.offsetX, core.status.automaticRoute.offsetY - core.bigmap.offsetY); } +////// 设置视野范围 ////// +control.prototype.setViewport = function (x, y) { + core.bigmap.offsetX = core.clamp(x, 0, 32 * core.bigmap.width - core.__PIXELS__); + core.bigmap.offsetY = core.clamp(y, 0, 32 * core.bigmap.height - core.__PIXELS__); + this.updateViewport(); + // ------ hero层也需要! + var hero_x = core.clamp((core.getHeroLoc('x') - core.__HALF_SIZE__) * 32, 0, 32*core.bigmap.width-core.__PIXELS__); + var hero_y = core.clamp((core.getHeroLoc('y') - core.__HALF_SIZE__) * 32, 0, 32*core.bigmap.height-core.__PIXELS__); + core.control.setGameCanvasTranslate('hero', hero_x - core.bigmap.offsetX, hero_y - core.bigmap.offsetY); +} + +////// 移动视野范围 ////// +control.prototype.moveViewport = function (steps, time, callback) { + time = time || core.values.moveSpeed || 300; + var step = 0, moveSteps = (steps||[]).filter(function (t) { + return ['up','down','left','right'].indexOf(t)>=0; + }); + var animate=window.setInterval(function() { + if (moveSteps.length==0) { + delete core.animateFrame.asyncId[animate]; + clearInterval(animate); + if (callback) callback(); + } + else { + if (core.control._moveViewport_moving(++step, moveSteps)) + step = 0; + } + }, time / 16 / core.status.replay.speed); + + core.animateFrame.asyncId[animate] = true; +} + +control.prototype._moveViewport_moving = function (step, moveSteps) { + var direction = moveSteps[0], scan = core.utils.scan[direction]; + core.setViewport(core.bigmap.offsetX + 2 * scan.x, core.bigmap.offsetY + 2 * scan.y); + if (step == 16) { + moveSteps.shift(); + return true; + } + return false; +} + ////// 获得勇士面对位置的x坐标 ////// control.prototype.nextX = function(n) { if (n == null) n = 1; diff --git a/libs/events.js b/libs/events.js index bcb122cb..80f688b2 100644 --- a/libs/events.js +++ b/libs/events.js @@ -1077,6 +1077,21 @@ events.prototype._action_animate = function (data, x, y, prefix) { this.__action_doAsyncFunc(data.async, core.drawAnimate, data.name, data.loc[0], data.loc[1]); } +events.prototype._action_setViewport = function (data, x, y, prefix) { + if (data.loc == null) { + core.drawHero(); + } + else { + var loc = this.__action_getLoc(data.loc, x, y, prefix); + core.setViewport(32 * loc[0], 32 * loc[1]); + } + core.doAction(); +} + +events.prototype._action_moveViewport = function (data, x, y, prefix) { + this.__action_doAsyncFunc(data.async, core.moveViewport, data.steps, data.time); +} + events.prototype._action_move = function (data, x, y, prefix) { var loc = this.__action_getLoc(data.loc, x, y, prefix); this.__action_doAsyncFunc(data.async, core.moveBlock, loc[0], loc[1], data.steps, data.time, data.keep); @@ -2268,7 +2283,7 @@ events.prototype._eventMoveHero_moving = function (step, moveSteps) { core.drawHero('leftFoot', 4 * o * step); } else if (step <= 8) { - core.drawHero('rightFoot', 4 * o * step); + core.drawHero('rightFoot', 4 * o * step);SGTM } if (step == 8) { core.setHeroLoc('x', x + o * core.utils.scan[direction].x, true); From 3a62d366e0c7d91411d3ab24a8803b7d28da12b9 Mon Sep 17 00:00:00 2001 From: oc Date: Wed, 10 Jul 2019 22:18:48 +0800 Subject: [PATCH 30/34] fix 263 bug --- _server/table/data.comment.js | 8 +++++++- libs/events.js | 4 ++-- project/data.js | 1 + 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/_server/table/data.comment.js b/_server/table/data.comment.js index 3e1bacf1..0748cba5 100644 --- a/_server/table/data.comment.js +++ b/_server/table/data.comment.js @@ -554,11 +554,17 @@ var data_comment_c456ea59_6018_45ef_8bcc_211a24c627dc = { "_data": "如果此项为true,则视为钥匙盒,红黄蓝钥匙+1;若为false,则视为大黄门钥匙" }, "steelDoorWithoutKey": { - "_left": true, + "_leaf": true, "_type": "checkbox", "_bool": "bool", "_data": "铁门是否不需要钥匙开启。如果此项为true,则无需钥匙也可以开铁门。" }, + "itemFirstText": { + "_leaf": true, + "_type": "checkbox", + "_bool": "bool", + "_data": "首次获得道具是否提示" + }, "equipment": { "_leaf": true, "_type": "checkbox", diff --git a/libs/events.js b/libs/events.js index 80f688b2..b5989364 100644 --- a/libs/events.js +++ b/libs/events.js @@ -462,7 +462,7 @@ events.prototype.getItem = function (id, num, x, y, callback) { // --- 首次获得道具的提示 if (!core.hasFlag("__itemHint__")) core.setFlag("__itemHint__", []); var itemHint = core.getFlag("__itemHint__"); - if (itemHint.indexOf(id) < 0 && itemCls != 'items') { + if (core.flags.itemFirstText && itemHint.indexOf(id) < 0 && itemCls != 'items') { var hint = core.material.items[id].text || "该道具暂无描述"; try { hint = core.replaceText(hint); @@ -2283,7 +2283,7 @@ events.prototype._eventMoveHero_moving = function (step, moveSteps) { core.drawHero('leftFoot', 4 * o * step); } else if (step <= 8) { - core.drawHero('rightFoot', 4 * o * step);SGTM + core.drawHero('rightFoot', 4 * o * step); } if (step == 8) { core.setHeroLoc('x', x + o * core.utils.scan[direction].x, true); diff --git a/project/data.js b/project/data.js index 29c59b80..f8ec9780 100644 --- a/project/data.js +++ b/project/data.js @@ -396,6 +396,7 @@ var data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d = "snowFourDirections": false, "bigKeyIsBox": false, "steelDoorWithoutKey": false, + "itemFirstText": true, "equipment": false, "equipboxButton": false, "iconInEquipbox": false, From cd3c0e084d1352a5b16dec31d521b9f9d2d2647f Mon Sep 17 00:00:00 2001 From: oc Date: Wed, 10 Jul 2019 23:41:00 +0800 Subject: [PATCH 31/34] hideStatusBar editor --- libs/control.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libs/control.js b/libs/control.js index 3823e105..081a82ec 100644 --- a/libs/control.js +++ b/libs/control.js @@ -2368,6 +2368,7 @@ control.prototype._updateStatusBar_setToolboxIcon = function () { } control.prototype.showStatusBar = function () { + if (main.mode == 'editor') return; if (core.domStyle.showStatusBar) return; var statusItems = core.dom.status; core.domStyle.showStatusBar = true; @@ -2380,6 +2381,8 @@ control.prototype.showStatusBar = function () { } control.prototype.hideStatusBar = function (showToolbox) { + if (main.mode == 'editor') return; + // 如果原本就是隐藏的,则先显示 if (!core.domStyle.showStatusBar) this.showStatusBar(); From 2ea8b012a85ff0143289ed91e08de389649a3d7d Mon Sep 17 00:00:00 2001 From: oc Date: Tue, 23 Jul 2019 14:49:05 +0800 Subject: [PATCH 32/34] v2.6.3 --- _server/editor_blockly.js | 5 +++-- libs/maps.js | 37 +++++++++++++++++++------------------ main.js | 3 +++ 3 files changed, 25 insertions(+), 20 deletions(-) diff --git a/_server/editor_blockly.js b/_server/editor_blockly.js index 1bdf8a76..7c87bf1e 100644 --- a/_server/editor_blockly.js +++ b/_server/editor_blockly.js @@ -762,7 +762,7 @@ function omitedcheckUpdateFunction(event) { "closeDoor_s": ["PosString_0", "PosString_1"], "show_s": ["EvalString_0", "EvalString_1", "IdString_0"], "hide_s": ["EvalString_0", "EvalString_1", "IdString_0"], - "setBlock_s": ["PosString_0", "PosString_1", "IdString_0"], + "setBlock_s": ["EvalString_1", "EvalString_2", "IdString_0"], "move_s": ["PosString_0", "PosString_1"], "jump_s": ["PosString_2", "PosString_3"], // 跳跃暂时只考虑终点 "showBgFgMap_s": ["EvalString_0", "EvalString_1", "IdString_0"], @@ -772,7 +772,8 @@ function omitedcheckUpdateFunction(event) { "hideFloorImg_s": ["EvalString_0", "EvalString_1", "IdString_0"], "trigger_s": ["PosString_0", "PosString_1"], "insert_2_s": ["PosString_0", "PosString_1", "IdString_0"], - "animate_s": ["EvalString_0", "EvalString_0"] + "animate_s": ["EvalString_0", "EvalString_0"], + "setViewport_s": ["PosString_0", "PosString_1"] } editor_blockly.selectPoint = function () { diff --git a/libs/maps.js b/libs/maps.js index 3cda4b57..71f8cf36 100644 --- a/libs/maps.js +++ b/libs/maps.js @@ -939,24 +939,25 @@ maps.prototype._drawFloorImage = function (ctx, name, type, image, offsetX, widt ////// 绘制Autotile ////// maps.prototype._drawAutotile = function (ctx, mapArr, block, size, left, top, status) { - var indexArrs = [ //16种组合的图块索引数组; // 将autotile分割成48块16*16的小块; 数组索引即对应各个小块 - // +----+----+----+----+----+----+ - [10, 9, 4, 3], //0 bin:0000 | 1 | 2 | 3 | 4 | 5 | 6 | - [10, 9, 4, 13], //1 bin:0001 +----+----+----+----+----+----+ - [10, 9, 18, 3], //2 bin:0010 | 7 | 8 | 9 | 10 | 11 | 12 | - [10, 9, 16, 15], //3 bin:0011 +----+----+----+----+----+----+ - [10, 43, 4, 3], //4 bin:0100 | 13 | 14 | 15 | 16 | 17 | 18 | - [10, 31, 4, 25], //5 bin:0101 +----+----+----+----+----+----+ - [10, 7, 2, 3], //6 bin:0110 | 19 | 20 | 21 | 22 | 23 | 24 | - [10, 31, 16, 5], //7 bin:0111 +----+----+----+----+----+----+ - [48, 9, 4, 3], //8 bin:1000 | 25 | 26 | 27 | 28 | 29 | 30 | - [8, 9, 4, 1], //9 bin:1001 +----+----+----+----+----+----+ - [36, 9, 30, 3], //10 bin:1010 | 31 | 32 | 33 | 34 | 35 | 36 | - [36, 9, 6, 15], //11 bin:1011 +----+----+----+----+----+----+ - [46, 45, 4, 3], //12 bin:1100 | 37 | 38 | 39 | 40 | 41 | 42 | - [46, 11, 4, 25], //13 bin:1101 +----+----+----+----+----+----+ - [12, 45, 30, 3], //14 bin:1110 | 43 | 44 | 45 | 46 | 47 | 48 | - [34, 33, 28, 27] //15 bin:1111 +----+----+----+----+----+----+ + var indexArrs = [ //16种组合的图块索引数组; + // 将autotile分割成48块16*16的小块; 数组索引即对应各个小块 + // +----+----+----+----+----+----+ + [10, 9, 4, 3], //0 bin:0000 | 1 | 2 | 3 | 4 | 5 | 6 | + [10, 9, 4, 13], //1 bin:0001 +----+----+----+----+----+----+ + [10, 9, 18, 3], //2 bin:0010 | 7 | 8 | 9 | 10 | 11 | 12 | + [10, 9, 16, 15], //3 bin:0011 +----+----+----+----+----+----+ + [10, 43, 4, 3], //4 bin:0100 | 13 | 14 | 15 | 16 | 17 | 18 | + [10, 31, 4, 25], //5 bin:0101 +----+----+----+----+----+----+ + [10, 43, 18, 3], //6 bin:0110 | 19 | 20 | 21 | 22 | 23 | 24 | + [10, 31, 16, 5], //7 bin:0111 +----+----+----+----+----+----+ + [48, 9, 4, 3], //8 bin:1000 | 25 | 26 | 27 | 28 | 29 | 30 | + [48, 9, 4, 13], //9 bin:1001 +----+----+----+----+----+----+ + [36, 9, 30, 3], //10 bin:1010 | 31 | 32 | 33 | 34 | 35 | 36 | + [36, 9, 6, 15], //11 bin:1011 +----+----+----+----+----+----+ + [46, 45, 4, 3], //12 bin:1100 | 37 | 38 | 39 | 40 | 41 | 42 | + [46, 11, 4, 25], //13 bin:1101 +----+----+----+----+----+----+ + [12, 45, 30, 3], //14 bin:1110 | 43 | 44 | 45 | 46 | 47 | 48 | + [20, 23, 38, 41] //15 bin:1111 +----+----+----+----+----+----+ ]; // 开始绘制autotile diff --git a/main.js b/main.js index 1434550c..e2c8cf15 100644 --- a/main.js +++ b/main.js @@ -403,6 +403,9 @@ main.dom.body.onkeyup = function(e) { main.selectButton((main.selectedButton||0) + 1); else if (e.keyCode == 67 || e.keyCode == 13 || e.keyCode == 32) // C/Enter/Space main.selectButton(main.selectedButton); + else if (e.keyCode == 27 && main.dom.levelChooseButtons.style.display == 'block') { // ESC + main.core.showStartAnimate(true); + } e.stopPropagation(); return; } From 36cdcd0dbdf736bbb71b13d7fa73349557ee9210 Mon Sep 17 00:00:00 2001 From: oc Date: Wed, 24 Jul 2019 10:46:22 +0800 Subject: [PATCH 33/34] Fix awesomplete keydown --- _server/editor_blockly.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/_server/editor_blockly.js b/_server/editor_blockly.js index 7c87bf1e..4c6d5257 100644 --- a/_server/editor_blockly.js +++ b/_server/editor_blockly.js @@ -948,6 +948,17 @@ Blockly.FieldTextInput.prototype.showInlineEditor_ = function(quietInput) { } } else { + + htmlInput.onkeydown = function (e) { + if (e.keyCode == 13 && awesomplete.opened && awesomplete.selected) { + e.stopPropagation(); + e.stopImmediatePropagation(); + e.preventDefault(); + awesomplete.select(); + return false; + } + } + // --- awesomplete var awesomplete = new Awesomplete(htmlInput, { minChars: 4, From e59898db2b0ce5e09a81bcaca823aecf95e535fb Mon Sep 17 00:00:00 2001 From: oc Date: Wed, 24 Jul 2019 18:12:42 +0800 Subject: [PATCH 34/34] V2.6.3 --- README.md | 11 ++++++----- libs/actions.js | 4 ++-- libs/control.js | 5 +++-- 更新说明.txt | 5 +++-- 4 files changed, 14 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 4d83c518..7ccf34ca 100644 --- a/README.md +++ b/README.md @@ -55,17 +55,18 @@ HTML5 canvas制作的魔塔样板,支持全平台游戏! ## 更新说明 -### 2019.7.5 V2.6.3 +### 2019.7.24 V2.6.3 -* [x] 标题界面大幅美化,支持键盘开始游戏 +* [x] 标题界面大幅美化,增加闪烁光标,支持键盘开始游戏 * [x] 事件编辑器支持自动补全,能对flag和API列表等进行补全 * [x] 剧情文本中\\c修改字体大小,\\d和\\e切换粗体和斜体 -* [x] 可以指定每个选择项的出现条件,动态生成 +* [x] 事件:设置视角&移动视角 +* [x] 可以指定显示选择项的出现条件并动态生成 * [x] 楼层传送器的平面传送模式(哪里离开飞回到哪里) -* [x] UI绘制事件增添绘制圆(边框),且可直接双击预览 +* [x] UI绘制事件增添绘制圆和绘制圆边框 +* [x] 所有的UI绘制事件均可以双击预览 * [x] 播放BGM事件可以一直持续播放直到下次调用 * [x] \f立绘支持alpha值 -* [x] 只有一个全局商店时V键能直接打开 * [x] 支持在脚本编辑中直接flags.xxx调用自定义变量 * [x] 首次获得道具将给予提示 * [x] 等待用户操作支持滚轮,视为PgUp和PgDn diff --git a/libs/actions.js b/libs/actions.js index 09b44ce2..648b8dd6 100644 --- a/libs/actions.js +++ b/libs/actions.js @@ -137,7 +137,7 @@ actions.prototype._sys_onkeyDown = function (e) { return; } } - e.preventDefault(); + if (e.preventDefault) e.preventDefault(); core.status.holdingKeys.push(e.keyCode); this.pressKey(e.keyCode); } else { @@ -199,7 +199,7 @@ actions.prototype._sys_onkeyUp = function (e) { break; } } - e.preventDefault(); + if (e.preventDefault) e.preventDefault(); this.keyUp(e.keyCode, e.altKey); } else { if (e.keyCode == 17) core.status.ctrlDown = false; diff --git a/libs/control.js b/libs/control.js index 081a82ec..e6d297bc 100644 --- a/libs/control.js +++ b/libs/control.js @@ -1236,7 +1236,7 @@ control.prototype.bookReplay = function () { // 从“浏览地图”页面打开 if (core.status.event.id=='viewMaps') - core.status.event.selection = core.status.event.data; + core.status.event.ui = core.status.event.data; core.lockControl(); core.status.event.id='book'; @@ -2386,6 +2386,7 @@ control.prototype.hideStatusBar = function (showToolbox) { // 如果原本就是隐藏的,则先显示 if (!core.domStyle.showStatusBar) this.showStatusBar(); + if (core.isReplaying()) showToolbox = true; var statusItems = core.dom.status, toolItems = core.dom.tools; core.domStyle.showStatusBar = false; @@ -2493,7 +2494,7 @@ control.prototype.setToolbarButton = function (useButton) { } if (useButton == null) useButton = core.domStyle.toolbarBtn; - if (!core.domStyle.isVertical) useButton = false; + if (!core.domStyle.isVertical || core.isReplaying()) useButton = false; core.domStyle.toolbarBtn = useButton; if (useButton) { diff --git a/更新说明.txt b/更新说明.txt index 8e690e8e..8b3e2419 100644 --- a/更新说明.txt +++ b/更新说明.txt @@ -1,9 +1,10 @@ HTML5魔塔样板V2.6.3 -标题界面大幅美化,支持键盘开始游戏 +标题界面大幅美化,增加闪烁光标,支持键盘开始游戏 事件编辑器支持自动补全,能对flag和API列表等进行补全 剧情文本中\\c修改字体大小,\\d和\\e切换粗体和斜体 -可以指定每个选择项的出现条件,动态生成 +事件:设置视角&移动视角 +可以指定显示选择项的出现条件并动态生成 楼层传送器的平面传送模式(哪里离开飞回到哪里) UI绘制事件增添绘制圆和绘制圆边框 所有的UI绘制事件均可以双击预览