From e8b23ff4cb30ca22b8ffe5475454740f82cf0077 Mon Sep 17 00:00:00 2001 From: oc Date: Tue, 19 Feb 2019 22:43:46 +0800 Subject: [PATCH 01/21] compress route --- libs/utils.js | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/libs/utils.js b/libs/utils.js index cd2bfa8f..f1910e4e 100644 --- a/libs/utils.js +++ b/libs/utils.js @@ -462,7 +462,9 @@ utils.prototype.encodeRoute = function (route) { ans+=lastMove.substring(0,1).toUpperCase(); if (cnt>1) ans+=cnt; } - return ans; + // return ans; + // 压缩 + return LZString.compressToBase64(ans); } ////// 解密路线 ////// @@ -470,6 +472,14 @@ utils.prototype.decodeRoute = function (route) { if (!core.isset(route)) return route; + // 解压缩 + try { + var v = LZString.decompressFromBase64(route); + if (core.isset(v) && /^[a-zA-Z0-9:]+$/.test(v)) { + route = v; + } + } catch (e) {} + var ans=[], index=0; var getNumber = function (noparse) { From 15c889146dabd91fa2d33130509dd0c474bd0f1e Mon Sep 17 00:00:00 2001 From: oc Date: Wed, 20 Feb 2019 21:15:43 +0800 Subject: [PATCH 02/21] viewMaps while replaying on mobile --- libs/control.js | 9 +++++++-- main.js | 10 ++++++++-- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/libs/control.js b/libs/control.js index fa540022..6c1e7f6e 100644 --- a/libs/control.js +++ b/libs/control.js @@ -2151,6 +2151,9 @@ control.prototype.autosave = function (removeLast) { /////// 实际进行自动存档 ////// control.prototype.checkAutosave = function () { + + if (!core.animateFrame || !core.saves || !core.saves.autosave) return; + core.setLocalStorage('totalTime', core.animateFrame.totalTime); if (core.saves.autosave.data == null || !core.saves.autosave.updated) return; @@ -2765,7 +2768,8 @@ control.prototype.updateStatusBar = function () { core.statusBar.image.toolbox.src = core.statusBar.icons.rewind.src; core.statusBar.image.keyboard.src = core.statusBar.icons.book.src; - core.statusBar.image.shop.style.opacity = 0; + + core.statusBar.image.shop.src = core.statusBar.icons.floor.src; core.statusBar.image.save.src = core.statusBar.icons.speedDown.src; @@ -2790,7 +2794,8 @@ control.prototype.updateStatusBar = function () { core.statusBar.image.toolbox.src = core.statusBar.icons.toolbox.src; core.statusBar.image.keyboard.src = core.statusBar.icons.keyboard.src; - core.statusBar.image.shop.style.opacity = 1; + + core.statusBar.image.shop.src = core.statusBar.icons.shop.src; core.statusBar.image.save.src = core.statusBar.icons.save.src; diff --git a/main.js b/main.js index befbbd0e..aa3b6d8e 100644 --- a/main.js +++ b/main.js @@ -490,7 +490,6 @@ main.statusBar.image.toolbox.ondblclick = function (e) { e.stopPropagation(); if (core.isReplaying()) { - core.rewindReplay(); return; } @@ -516,6 +515,11 @@ main.statusBar.image.keyboard.onclick = function (e) { main.statusBar.image.shop.onclick = function (e) { e.stopPropagation(); + if (core.isReplaying()) { + core.viewMapReplay(); + return; + } + if (main.core.isPlaying()) main.core.openQuickShop(true); } @@ -664,7 +668,9 @@ main.dom.musicBtn.onclick = function () { window.onblur = function () { if (main.core && main.core.control) { - main.core.control.checkAutosave(); + try { + main.core.control.checkAutosave(); + } catch (e) {main.log(e);} } } From f98c85442f3f0c561d5332c17e1f80386a345542 Mon Sep 17 00:00:00 2001 From: oc Date: Wed, 20 Feb 2019 21:30:30 +0800 Subject: [PATCH 03/21] 48 in bg/fg --- _server/editor.js | 30 +++++++++++++----------------- libs/maps.js | 9 +++++++-- 2 files changed, 20 insertions(+), 19 deletions(-) diff --git a/_server/editor.js b/_server/editor.js index 2f184f30..42d8c154 100644 --- a/_server/editor.js +++ b/_server/editor.js @@ -797,25 +797,21 @@ editor.prototype.listen = function () { currDrawData.info = JSON.parse(JSON.stringify(editor.info)); reDo = null; // console.log(stepPostfix); - if (editor.layerMod!='map' && editor.info.images && editor.info.images.indexOf('48')!==-1){ - printe('前景/背景不支持48的图块'); - } else { - if(editor.brushMod==='tileset' && core.tilesets.indexOf(editor.info.images)!==-1){ - var imgWidth=~~(core.material.images.tilesets[editor.info.images].width/32); - var x0=stepPostfix[0].x; - var y0=stepPostfix[0].y; - var idnum=editor.info.idnum; - for (var ii = 0; ii < stepPostfix.length; ii++){ - if(stepPostfix[ii].y!=y0){ - y0++; - idnum+=imgWidth; - } - editor[editor.layerMod][stepPostfix[ii].y][stepPostfix[ii].x] = editor.ids[editor.indexs[idnum+stepPostfix[ii].x-x0]]; + if(editor.brushMod==='tileset' && core.tilesets.indexOf(editor.info.images)!==-1){ + var imgWidth=~~(core.material.images.tilesets[editor.info.images].width/32); + var x0=stepPostfix[0].x; + var y0=stepPostfix[0].y; + var idnum=editor.info.idnum; + for (var ii = 0; ii < stepPostfix.length; ii++){ + if(stepPostfix[ii].y!=y0){ + y0++; + idnum+=imgWidth; } - } else { - for (var ii = 0; ii < stepPostfix.length; ii++) - editor[editor.layerMod][stepPostfix[ii].y][stepPostfix[ii].x] = editor.info; + editor[editor.layerMod][stepPostfix[ii].y][stepPostfix[ii].x] = editor.ids[editor.indexs[idnum+stepPostfix[ii].x-x0]]; } + } else { + for (var ii = 0; ii < stepPostfix.length; ii++) + editor[editor.layerMod][stepPostfix[ii].y][stepPostfix[ii].x] = editor.info; } // console.log(editor.map); editor.updateMap(); diff --git a/libs/maps.js b/libs/maps.js index e8e3c0e4..3ad953a4 100644 --- a/libs/maps.js +++ b/libs/maps.js @@ -432,11 +432,16 @@ maps.prototype.drawBlock = function (block, animate, dx, dy) { if (!blockInfo.isTileset) x = (animate||0)%(block.event.animate||1); if (core.isset(block.name)) { - core.clearMap(block.name, block.x * 32, block.y * 32, 32, 32); + core.clearMap(block.name, block.x * 32, block.y * 32 + 32 - height, 32, height); if (block.name == 'bg') { + if (height>32) { + core.clearMap(block.name, block.x * 32, block.y * 32 - 32, 32, 32); + core.drawImage('bg', core.material.groundCanvas.canvas, block.x * 32, block.y * 32 - 32); + } core.drawImage('bg', core.material.groundCanvas.canvas, block.x * 32, block.y * 32); } - core.drawImage(block.name, image, x * 32, y * 32, 32, 32, block.x * 32, block.y * 32, 32, 32); + core.drawImage(block.name, image, x * 32, y * height, 32, height, + block.x * 32, block.y * 32 + 32 - height, 32, height); return; } From 7c05ccf128bdb18ba7065781832debcf61d46fb4 Mon Sep 17 00:00:00 2001 From: oc Date: Wed, 20 Feb 2019 21:45:50 +0800 Subject: [PATCH 04/21] replay info --- libs/control.js | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/libs/control.js b/libs/control.js index 6c1e7f6e..e97f3178 100644 --- a/libs/control.js +++ b/libs/control.js @@ -1654,7 +1654,7 @@ control.prototype.setReplaySpeed = function (speed) { control.prototype.stopReplay = function () { if (!core.isPlaying()) return; if (core.status.event.id=='save' || (core.status.event.id||"").indexOf('book')==0 || core.status.event.id=='viewMaps') return; - if (!core.isReplaying()) return; + // if (!core.isReplaying()) return; core.status.replay.toReplay = []; core.status.replay.totalList = []; core.status.replay.replaying=false; @@ -1962,8 +1962,27 @@ control.prototype.replay = function () { return; } - core.stopReplay(); - core.insertAction("录像文件出错"); + // core.stopReplay(); + // core.insertAction("录像文件出错"); + + core.status.replay.replaying = false; + main.log("录像文件出错,当前操作:"+action+ + "\n接下来10个操作是:"+core.status.replay.toReplay.slice(0, 10).toString()); + core.ui.drawConfirmBox("录像文件出错,你想回到上个节点吗?", function () { + core.ui.closePanel(); + if (core.status.replay.save.length > 0) { + core.status.replay.replaying = true; + core.status.replay.pausing = true; + core.rewindReplay(); + } + else { + core.drawTip("无法回到上一个节点"); + core.stopReplay(); + } + }, function () { + core.ui.closePanel(); + core.stopReplay(); + }); } From b11d8339886fb66c01f347a8cb68644d5cf77cdf Mon Sep 17 00:00:00 2001 From: oc Date: Wed, 20 Feb 2019 21:51:09 +0800 Subject: [PATCH 05/21] drawConfirmBox closePanel --- libs/events.js | 1 + 1 file changed, 1 insertion(+) diff --git a/libs/events.js b/libs/events.js index 57b81c4a..fa30955f 100644 --- a/libs/events.js +++ b/libs/events.js @@ -109,6 +109,7 @@ events.prototype.startGame = function (hard, seed, route, callback) { core.clearStatusBar(); var post_start = function () { + core.ui.closePanel(); core.control.triggerStatusBar('show'); core.dom.musicBtn.style.display = 'none'; From aef96516102a4bcc3b76cd0745fffb310c88cf0a Mon Sep 17 00:00:00 2001 From: oc Date: Wed, 20 Feb 2019 21:51:16 +0800 Subject: [PATCH 06/21] drawConfirmBox closePanel --- libs/actions.js | 1 + libs/control.js | 1 + libs/events.js | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/libs/actions.js b/libs/actions.js index a1011943..bd23b4d9 100644 --- a/libs/actions.js +++ b/libs/actions.js @@ -2062,6 +2062,7 @@ actions.prototype.clickSyncSave = function (x,y) { core.removeLocalForage("save"+i); } } + core.ui.closePanel(); core.drawText("读取成功!\n你的本地所有存档均已被覆盖。"); }, function () { core.status.event.selection=0; diff --git a/libs/control.js b/libs/control.js index e97f3178..bdefeb45 100644 --- a/libs/control.js +++ b/libs/control.js @@ -2369,6 +2369,7 @@ control.prototype.syncLoad = function () { core.removeLocalForage("save"+i); } } + core.ui.closePanel(); core.drawText("同步成功!\n你的本地所有存档均已被覆盖。"); }, function () { core.status.event.selection=0; diff --git a/libs/events.js b/libs/events.js index fa30955f..d92d3c96 100644 --- a/libs/events.js +++ b/libs/events.js @@ -278,7 +278,7 @@ events.prototype.gameOver = function (ending, fromReplay, norank) { var doUpload = function(username) { var hp = core.status.hero.hp; if (username==undefined) hp = 1; - + core.ui.closePanel(); // upload var formData = new FormData(); formData.append('type', 'score'); From 2b92921e43f41e0dccc6f2e0af9e4e8152421295 Mon Sep 17 00:00:00 2001 From: oc Date: Wed, 20 Feb 2019 23:36:26 +0800 Subject: [PATCH 07/21] color in choices --- _server/blockly/MotaAction.g4 | 23 +- _server/editor_blockly.js | 8 +- libs/ui.js | 158 ++-- project/floors/sample1.js | 1501 +++++++++++++++++---------------- 4 files changed, 853 insertions(+), 837 deletions(-) diff --git a/_server/blockly/MotaAction.g4 b/_server/blockly/MotaAction.g4 index d81a1128..d87bd35e 100644 --- a/_server/blockly/MotaAction.g4 +++ b/_server/blockly/MotaAction.g4 @@ -1528,15 +1528,22 @@ return code; */; choicesContext - : '子选项' EvalString BGNL? Newline action+ + : '子选项' EvalString '颜色' EvalString? Colour 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 -var code = '{"text": "'+EvalString_0+'", "action": [\n'+action_0+']},\n'; +if (EvalString_1) { + var colorRe = /^(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)?$/; + if (colorRe.test(EvalString_1)) + EvalString_1 = ', "color": ['+EvalString_1+']'; + else + EvalString_1 = ', "color": "'+EvalString_1+'"'; +} +var code = '{"text": "'+EvalString_0+'"'+EvalString_1+', "action": [\n'+action_0+']},\n'; return code; */; @@ -2095,7 +2102,9 @@ ActionParser.prototype.parseAction = function() { if (!/^\w+\.png$/.test(data.background)) data.background=setTextfunc(data.background); this.next = MotaActionBlocks['setText_s'].xmlText([ - data.position,data.offset,data.title,`rgba(${data.title})`,data.text,`rgba(${data.text})`,data.background,`rgba(${data.background})`,data.bold,data.titlefont,data.textfont,data.time,this.next]); + data.position,data.offset,data.title,'rgba('+data.title+')', + data.text,'rgba('+data.text+')',data.background,'rgba('+data.background+')', + data.bold,data.titlefont,data.textfont,data.time,this.next]); break; case "tip": this.next = MotaActionBlocks['tip_s'].xmlText([ @@ -2267,7 +2276,7 @@ ActionParser.prototype.parseAction = function() { case "setFg": // 颜色渐变 if(this.isset(data.color)){ this.next = MotaActionBlocks['setFg_0_s'].xmlText([ - data.color,`rgba(${data.color})`,data.time||0,data.async||false,this.next]); + data.color,'rgba('+data.color+')',data.time||0,data.async||false,this.next]); } else { this.next = MotaActionBlocks['setFg_1_s'].xmlText([ data.time||0,data.async||false,this.next]); @@ -2275,7 +2284,7 @@ ActionParser.prototype.parseAction = function() { break; case "screenFlash": // 画面闪烁 this.next = MotaActionBlocks['screenFlash_s'].xmlText([ - data.color,`rgba(${data.color})`,data.time||500,data.times||1,data.async||false,this.next]); + data.color,'rgba('+data.color+')',data.time||500,data.times||1,data.async||false,this.next]); break; case "setWeather": // 更改天气 this.next = MotaActionBlocks['setWeather_s'].xmlText([ @@ -2402,7 +2411,7 @@ ActionParser.prototype.parseAction = function() { var text_choices = null; for(var ii=data.choices.length-1,choice;choice=data.choices[ii];ii--) { text_choices=MotaActionBlocks['choicesContext'].xmlText([ - choice.text,this.insertActionList(choice.action),text_choices]); + choice.text,choice.color,'rgba('+choice.color+')',this.insertActionList(choice.action),text_choices]); } this.next = MotaActionBlocks['choices_s'].xmlText([ this.isset(data.text)?this.EvalString(data.text):null,'','',text_choices,this.next]); diff --git a/_server/editor_blockly.js b/_server/editor_blockly.js index 020fab43..f9c6723c 100644 --- a/_server/editor_blockly.js +++ b/_server/editor_blockly.js @@ -64,9 +64,9 @@ editor_blockly = function () { MotaActionBlocks['lose_s'].xmlText(), MotaActionBlocks['choices_s'].xmlText([ '选择剑或者盾','流浪者','man',MotaActionBlocks['choicesContext'].xmlText([ - '剑',MotaActionFunctions.actionParser.parseList([{"type": "openDoor", "loc": [3,3]}]), + '剑','',null,MotaActionFunctions.actionParser.parseList([{"type": "openDoor", "loc": [3,3]}]), MotaActionBlocks['choicesContext'].xmlText([ - '盾',MotaActionFunctions.actionParser.parseList([{"type": "openDoor", "loc": [9,3]}]), + '盾','',null,MotaActionFunctions.actionParser.parseList([{"type": "openDoor", "loc": [9,3]}]), ]) ]) ]), @@ -175,7 +175,7 @@ editor_blockly = function () { MotaActionFunctions.actionParser.parse([ {"type": "choices", "text": "\t[老人,man]少年,你需要钥匙吗?\n我这里有大把的!", "choices": [ - {"text": "黄钥匙(\${9+flag:shop_times}金币)", "action": [ + {"text": "黄钥匙(\${9+flag:shop_times}金币)", "color": [255,255,0,1], "action": [ {"type": "if", "condition": "status:money>=9+flag:shop_times", "true": [ {"type": "setValue", "name": "status:money", "value": "status:money-(9+flag:shop_times)"}, @@ -187,7 +187,7 @@ editor_blockly = function () { ] } ]}, - {"text": "蓝钥匙(\${18+2*flag:shop_times}金币)", "action": [ + {"text": "蓝钥匙(\${18+2*flag:shop_times}金币)", "color": [0,0,255,1], "action": [ ]}, {"text": "离开", "action": [ {"type": "exit"} diff --git a/libs/ui.js b/libs/ui.js index 04209587..26f86589 100644 --- a/libs/ui.js +++ b/libs/ui.js @@ -503,6 +503,73 @@ ui.prototype.calTextBoxWidth = function (canvas, content, min_width, max_width) } } +ui.prototype.__drawText = function (canvas, content, content_left, content_top, valid_width, + color, per_height, time) { + + var offsetx = content_left, offsety = content_top; + core.setFillStyle(canvas, color); + var index = 0, currcolor = color, changed = false; + + var drawNext = function () { + if (index >= content.length) return false; + if (changed) { + core.setFillStyle(canvas, currcolor); + changed = false; + } + + // get next character + var ch = content.charAt(index++); + // \n, \\n + if (ch == '\n' || (ch=='\\' && content.charAt(index)=='n')) { + offsetx = content_left; + offsety += per_height; + if (ch=='\\') index++; + return drawNext(); + } + // \r, \\r + if (ch == '\r' || (ch=='\\' && content.charAt(index)=='r')) { + if (ch == '\\') index++; + changed = true; + // 检查是不是 [] + var index2; + if (content.charAt(index) == '[' && ((index2=content.indexOf(']', index))>=0)) { + // 变色 + var str = content.substring(index+1, index2); + if (str=="") currcolor = color; + else currcolor = str; + index = index2+1; + } + else currcolor = color; + return drawNext(); + } + // 检查是不是自动换行 + if (core.isset(valid_width)) { + var charwidth = core.calWidth(canvas, ch); + if (offsetx + charwidth > content_left + valid_width) { + index--; + offsetx = content_left; + offsety += per_height; + return drawNext(); + } + } + // 输出 + core.fillText(canvas, ch, offsetx, offsety); + offsetx += charwidth; + return true; + }; + + if (!core.isset(time) || time<=0) while (drawNext()); + else { + core.status.event.interval = setInterval(function () { + changed = true; + if (!drawNext()) { + clearInterval(core.status.event.interval); + core.status.event.interval = null; + } + }, time); + } +} + ////// 绘制一个对话框 ////// ui.prototype.drawTextBox = function(content, showAll) { @@ -729,69 +796,10 @@ ui.prototype.drawTextBox = function(content, showAll) { core.drawImage('ui', image, 0, 0, image.width, image.height, left+10, top+10, 70, 70); } - var offsetx = content_left, offsety = content_top; core.setFont('ui', font); - core.setFillStyle('ui', textColor); - var index = 0, currcolor = textColor, changed = false; - var drawNext = function () { - if (index >= content.length) return false; - if (changed) { - core.setFillStyle('ui', currcolor); - changed = false; - } - - // get next character - var ch = content.charAt(index++); - // \n, \\n - if (ch == '\n' || (ch=='\\' && content.charAt(index)=='n')) { - offsetx = content_left; - offsety += textfont+5; - if (ch=='\\') index++; - return drawNext(); - } - // \r, \\r - if (ch == '\r' || (ch=='\\' && content.charAt(index)=='r')) { - if (ch == '\\') index++; - changed = true; - // 检查是不是 [] - var index2; - if (content.charAt(index) == '[' && ((index2=content.indexOf(']', index))>=0)) { - // 变色 - var str = content.substring(index+1, index2); - if (str=="") currcolor = textColor; - else currcolor = str; - index = index2+1; - } - else currcolor = textColor; - return drawNext(); - } - // 检查是不是自动换行 - var charwidth = core.calWidth('ui', ch); - if (offsetx + charwidth > content_left + validWidth) { - index--; - offsetx = content_left; - offsety += textfont+5; - return drawNext(); - } - // 输出 - core.fillText('ui', ch, offsetx, offsety); - offsetx += charwidth; - return true; - }; - - if (showAll || textAttribute.time<=0 || core.status.event.id!='action') { - while (drawNext()); - } - else { - core.status.event.interval = setInterval(function () { - changed = true; - if (!drawNext()) { - clearInterval(core.status.event.interval); - core.status.event.interval = null; - } - }, textAttribute.time); - } + this.__drawText('ui', content, content_left, content_top, validWidth, textColor, textfont + 5, + (showAll || textAttribute.time<=0 || core.status.event.id!='action')?0:textAttribute.time); } @@ -812,7 +820,8 @@ ui.prototype.drawScrollText = function (content, time, callback) { var font = textfont+"px "+core.status.globalAttribute.font; if (textAttribute.bold) font = "bold "+font; - var contents = core.splitLines('ui', content), lines = contents.length; + var realContent = content.replace(/(\r|\\r)(\[.*?])?/g, ""); + var contents = core.splitLines('ui', realContent), lines = contents.length; // 计算总高度,按1.4倍行距计算 var width = 416, height = textfont * 1.4 * lines; @@ -821,15 +830,8 @@ ui.prototype.drawScrollText = function (content, time, callback) { tempCanvas.canvas.height = height; tempCanvas.clearRect(0, 0, width, height); tempCanvas.font = font; - tempCanvas.fillStyle = textColor; - // 全部绘制 - var currH = textfont; - for (var i = 0; i < lines; ++i) { - var text = contents[i]; - tempCanvas.fillText(text, offset, currH); - currH += 1.4 * textfont; - } + this.__drawText(tempCanvas, content, 0, textfont, null, textColor, 1.4*textfont, 0); // 开始绘制到UI上 core.clearMap('ui'); @@ -891,17 +893,19 @@ ui.prototype.drawChoices = function(content, choices) { var contents = null; var content_left = left + 15; + var validWidth = width-(content_left-left)-10; if (core.isset(content)) { - // 获得name, image, icon // 获得name, image, icon var info = this.getTitleAndIcon(content); content = core.replaceText(info.content); + var realContent = content.replace(/(\r|\\r)(\[.*?])?/g, ""); id=info.id; name=info.name; image=info.image; icon=info.icon; iconHeight=info.iconHeight; animate=info.animate; if (id=='hero' || core.isset(icon)) content_left = left+60; - contents = core.splitLines('ui', content, width-(content_left-left)-10, 'bold 15px '+globalFont); + validWidth = width-(content_left-left)-10 + contents = core.splitLines('ui', realContent, validWidth, 'bold 15px '+globalFont); // content部分高度 var cheight=0; @@ -964,16 +968,16 @@ ui.prototype.drawChoices = function(content, choices) { } core.setTextAlign('ui', 'left'); - for (var i=0;i=9+flag:woman_times", - "true": [ - { - "type": "setValue", - "name": "status:money", - "value": "status:money-(9+flag:woman_times)" - }, - { - "type": "setValue", - "name": "item:yellowKey", - "value": "item:yellowKey+1" - } - ], - "false": [ - "\t[老人,woman]你的金钱不足!", - { - "type": "revisit" - } - ] - } - ] - }, - { - "text": "蓝钥匙(${18+2*flag:woman_times}金币)", - "action": [ - { - "type": "if", - "condition": "status:money>=18+2*flag:woman_times", - "true": [ - { - "type": "setValue", - "name": "status:money", - "value": "status:money-(18+2*flag:woman_times)" - }, - { - "type": "setValue", - "name": "item:blueKey", - "value": "item:blueKey+1" - } - ], - "false": [ - "\t[老人,woman]你的金钱不足!", - { - "type": "revisit" - } - ] - } - ] - }, - { - "text": "红钥匙(${36+4*flag:woman_times}金币)", - "action": [ - { - "type": "if", - "condition": "status:money>=36+4*flag:woman_times", - "true": [ - { - "type": "setValue", - "name": "status:money", - "value": "status:money-(36+4*flag:woman_times)" - }, - { - "type": "setValue", - "name": "item:redKey", - "value": "item:redKey+1" - } - ], - "false": [ - "\t[老人,woman]你的金钱不足!", - { - "type": "revisit" - } - ] - } - ] - }, - { - "text": "离开", - "action": [ - { - "type": "exit" - } - ] - } - ] - } + [ + 0, + 7 + ], + [ + 1, + 8 + ], + [ + 2, + 7 ] - } - ] - }, - { - "type": "setValue", - "name": "flag:woman_times", - "value": "flag:woman_times+1" - }, - { - "type": "revisit" - } - ], - "12,11": [ - "\t[老人,womanMagician]使用 {\"type\":\"function\"} 可以写自定义的JS脚本。\n本塔支持的所有主要API会在doc文档内给出。", - "\t[老人,womanMagician]例如这个例子:即将弹出一个输入窗口,然后会将你的输入结果直接加到你的攻击力上。", - { - "type": "input", - "text": "请输入你要加攻击力的数值:" - }, - { - "type": "if", - "condition": "flag:input>0", - "true": [ - { - "type": "setValue", - "name": "status:atk", - "value": "status:atk+flag:input" - }, - { - "type": "tip", - "text": "操作成功,攻击+${flag:input}" - }, - "操作成功,攻击+${flag:input}" - ], - "false": [] - }, - "\t[老人,womanMagician]具体可参见样板中本事件的写法。" - ], - "10,12": null, - "12,12": [ - { - "type": "switch", - "condition": "flag:woman_times", - "caseList": [ - { - "case": "0", - "action": [ - "\t[老人,woman]现在使用switch改写这个例子" + ], + "time": 500 + }, + "\t[hero]什么?", + { + "type": "playSound", + "name": "attack.mp3" + }, + { + "type": "setValue", + "name": "status:atk", + "value": "status:atk/10" + }, + { + "type": "setValue", + "name": "status:def", + "value": "status:def/10" + }, + { + "type": "hide", + "loc": [ + [ + 1, + 6 + ], + [ + 0, + 7 + ], + [ + 2, + 7 + ], + [ + 1, + 8 ] - }, - { - "case": "8", - "action": [ - "\t[老人,woman]你购买的钥匙已经够多了,再继续卖给你的话我会有危险的。", - "\t[老人,woman]看在你贡献给我这么多钱的份上,送你一把大黄门钥匙吧,希望你能好好用它。", - { - "type": "setValue", - "name": "item:bigKey", - "value": "item:bigKey+1" - }, - "\t[老人,woman]我先走了,拜拜~", - { - "type": "hide", - "time": 500 - }, - { - "type": "exit" - } - ] - }, - { - "case": "default", - "action": [ - { - "type": "comment", - "text": "当没有符合的值的场合执行此事件" - }, - { - "type": "choices", - "text": "\t[老人,woman]少年,你需要钥匙吗?\n我这里有大把的!", - "choices": [ - { - "text": "黄钥匙(${9+flag:woman_times}金币)", - "action": [ - { - "type": "if", - "condition": "status:money>=9+flag:woman_times", - "true": [ - { - "type": "setValue", - "name": "status:money", - "value": "status:money-(9+flag:woman_times)" - }, - { - "type": "setValue", - "name": "item:yellowKey", - "value": "item:yellowKey+1" - } - ], - "false": [ - "\t[老人,woman]你的金钱不足!", - { - "type": "revisit" - } - ] - } - ] - }, - { - "text": "蓝钥匙(${18+2*flag:woman_times}金币)", - "action": [ - { - "type": "if", - "condition": "status:money>=18+2*flag:woman_times", - "true": [ - { - "type": "setValue", - "name": "status:money", - "value": "status:money-(18+2*flag:woman_times)" - }, - { - "type": "setValue", - "name": "item:blueKey", - "value": "item:blueKey+1" - } - ], - "false": [ - "\t[老人,woman]你的金钱不足!", - { - "type": "revisit" - } - ] - } - ] - }, - { - "text": "红钥匙(${36+4*flag:woman_times}金币)", - "action": [ - { - "type": "if", - "condition": "status:money>=36+4*flag:woman_times", - "true": [ - { - "type": "setValue", - "name": "status:money", - "value": "status:money-(36+4*flag:woman_times)" - }, - { - "type": "setValue", - "name": "item:redKey", - "value": "item:redKey+1" - } - ], - "false": [ - "\t[老人,woman]你的金钱不足!", - { - "type": "revisit" - } - ] - } - ] - }, - { - "text": "离开", - "action": [ - { - "type": "exit" - } - ] - } - ] - } - ] - } - ] + ] + }, + { + "type": "hide", + "loc": [ + 1, + 5 + ], + "time": 500 + }, + { + "type": "hide" + }, + { + "type": "setFg", + "color": [ + 0, + 0, + 0 + ], + "time": 1250 + }, + { + "type": "sleep", + "time": 700 + }, + { + "type": "changeFloor", + "floorId": "sample1", + "loc": [ + 1, + 11 + ], + "direction": "right", + "time": 1000 + }, + { + "type": "trigger", + "loc": [ + 2, + 11 + ] + } + ], + "2,11": [ + "\t[杰克,thief]喂!醒醒!快醒醒!", + { + "type": "setFg", + "time": 1500 + }, + "\t[hero]额,我这是在什么地方?", + "\t[杰克,thief]你被魔王抓了起来扔进了监狱,和我关在了一起,但是幸运的是我在昨天刚刚挖好一条越狱的暗道!", + { + "type": "openDoor", + "loc": [ + 3, + 11 + ] + }, + { + "type": "sleep", + "time": 300 + }, + "\t[杰克,thief]我先走了,祝你好运!", + { + "type": "move", + "time": 750, + "steps": [ + { + "direction": "right", + "value": 2 + }, + "down" + ] + }, + "上面是个move事件,可以对NPC等进行移动。\n详见样板中小偷事件的写法。", + "\t[hero]怎么跑的这么快..." + ], + "4,2": [ + "\t[老人,man]本塔的商店有两类,全局商店和非全局商店。\n\n所谓非全局商店,就类似于右下角那个卖钥匙的老人一样,一定要碰到才能触发事件。\n\n而全局商店,则能在快捷商店中直接使用。", + "\t[老人,man]要注册一个全局商店,你需要在 data.js 中,找到 shops,并在内添加你的商店信息。", + "\t[老人,man]商店信息添加后,可以在需要的事件处调用{\"type\": \"openShop\"}来打开你添加的全局商店。", + "\t[老人,man]在上面的例子里,左边是一个仿50层的金币商店,右边是一个仿24层的经验商店。\n\n商店被访问后即可在快捷商店中进行使用。", + "\t[老人,man]如果你需要在某层暂时禁用快捷商店,可以在data.js中设置cannotUseQuickShop。\n如果需要永久禁用商店,请使用{\"type\":\"disableShop\"}", + { + "type": "hide", + "time": 500 + } + ], + "1,0": [ + { + "type": "openShop", + "id": "moneyShop1" + } + ], + "5,0": [ + { + "type": "openShop", + "id": "expShop1" + } + ], + "7,7": [ + "\t[老人,man]这是一个典型的杀怪开门、强制战斗事件。", + { + "type": "hide" + } + ], + "8,7": { + "enable": false, + "data": [] }, - { - "type": "setValue", - "name": "flag:woman_times", - "value": "flag:woman_times+1" + "9,7": [ + { + "type": "show", + "loc": [ + 8, + 7 + ] + }, + { + "type": "hide" + } + ], + "10,4": [ + "\t[blackKing]你终于还是来了。", + "\t[hero]放开我们的公主!", + "\t[blackKing]如果我不愿意呢?", + "\t[hero]无需多说,拔剑吧!", + { + "type": "battle", + "id": "blackKing" + }, + { + "type": "hide", + "loc": [ + 10, + 2 + ] + }, + { + "type": "openDoor", + "loc": [ + 8, + 7 + ] + }, + "\t[blackKing]没想到你已经变得这么强大了... 算你厉害。\n公主就交给你了,请好好对她。", + { + "type": "hide" + } + ], + "10,0": [ + "\t[hero]公主,我来救你了~", + "\t[公主,princess]快救我出去!我受够这里了!", + "\t[hero]公主别怕,我们走吧~", + { + "type": "win", + "reason": "救出公主" + } + ], + "6,12": { + "enable": false, + "data": [] }, - { - "type": "revisit" - } - ] -}, -"changeFloor": { - "4,12": { - "floorId": "sample0", - "loc": [ - 6, - 0 + "6,11": [ + "\t[仙子,fairy]通过调用 {\"type\": \"show\"} 可以使隐藏的事件显示出来。\n比如我下面这个机关门。", + { + "type": "show", + "loc": [ + 6, + 12 + ] + }, + "\t[仙子,fairy]通过调用 {\"type\": \"openDoor\"} 可以无需钥匙打开一扇门或暗墙。", + { + "type": "openDoor", + "loc": [ + 6, + 12 + ] + }, + "\t[仙子,fairy]同时,也可以对其它层进行操作,比如楼下的机关门,现在已经为你打开了。", + { + "type": "openDoor", + "loc": [ + 11, + 10 + ], + "floorId": "sample0" + }, + "\t[仙子,fairy]如果 show 或 hide 指定了 time 参数,则以动画效果显示,指定的参数作为消失时间(毫秒)来计算。", + "\t[仙子,fairy]现在到楼下来找我吧~", + { + "type": "show", + "loc": [ + 12, + 10 + ], + "floorId": "sample0" + }, + { + "type": "hide", + "time": 500 + } + ], + "8,11": [ + { + "type": "setValue", + "name": "flag:man_times", + "value": "flag:man_times+1" + }, + "\t[老人,man]在文字中使用${' ${ '}和 } 可以计算并显示一个表达式的结果。\n", + "\t[老人,man]例如:\n你的当前攻击力是${status:atk},防御力是${status:def}。\n攻防和的十倍是${10*(status:atk+status:def)},攻防之积是${status:atk*status:def}。\n你有${item:yellowKey}把黄钥匙,${item:blueKey}把蓝钥匙,${item:redKey}把红钥匙。\n你有${item:pickaxe}个破,${item:bomb}个炸,${item:centerFly}个飞。\n这是你第${flag:man_times}次和我对话。", + "\t[老人,man]同时,你也可以通过{\"type\": \"setValue\"}来设置一个勇士的属性、道具,或某个Flag。", + "\t[老人,man]例如:\n现在我将让你的攻防提升50%,再将攻防和的十倍加到生命值上。", + { + "type": "setValue", + "name": "status:atk", + "value": "status:atk*1.5" + }, + { + "type": "setValue", + "name": "status:def", + "value": "status:def*1.5" + }, + { + "type": "setValue", + "name": "status:hp", + "value": "status:hp+10*(status:atk+status:def)" + }, + "\t[老人,man]再送你500金币,1000经验,1破2炸3飞!", + { + "type": "setValue", + "name": "status:money", + "value": "status:money+500" + }, + { + "type": "setValue", + "name": "status:experience", + "value": "status:experience+1000" + }, + { + "type": "setValue", + "name": "item:pickaxe", + "value": "item:pickaxe+1" + }, + { + "type": "setValue", + "name": "item:bomb", + "value": "item:bomb+2" + }, + { + "type": "setValue", + "name": "item:centerFly", + "value": "item:centerFly+3" + }, + "\t[老人,man]status:xxx 代表勇士的某个属性。\n其中xxx可取hp, atk, def, mdef, money,experience这几项。\n\nitem:xxx 代表勇士的某个道具的个数。\nxxx为道具ID,具体可参见items.js中的定义。\n\nflag:xxx 代表某个自定义Flag或变量。\nxxx为Flag/变量名,可以自行定义,由字母、数字和下划线组成。\n未定义过而直接取用的Flag默认值为false。", + "\t[老人,man]你现在可以重新和我进行对话,进一步看到属性值的改变。" + ], + "10,11": [ + { + "type": "if", + "condition": "flag:woman_times==0", + "true": [ + "\t[老人,woman]这是个很复杂的例子,它将教会你如何使用if 语句进行条件判断,以及 choices 提供选项来供用户进行选择。", + "\t[老人,woman]第一次访问我将显示这段文字;从第二次开始将会向你出售钥匙。\n钥匙价格将随着访问次数递增。\n当合计出售了七把钥匙后,将送你一把大黄门钥匙,并消失不再出现。", + "\t[老人,woman]这部分的逻辑比较长,请细心看样板的写法,是很容易看懂并理解的。" + ], + "false": [ + { + "type": "if", + "condition": "flag:woman_times==8", + "true": [ + "\t[老人,woman]你购买的钥匙已经够多了,再继续卖给你的话我会有危险的。", + "\t[老人,woman]看在你贡献给我这么多钱的份上,送你一把大黄门钥匙吧,希望你能好好用它。", + { + "type": "setValue", + "name": "item:bigKey", + "value": "item:bigKey+1" + }, + "\t[老人,woman]我先走了,拜拜~", + { + "type": "hide", + "time": 500 + }, + { + "type": "exit" + } + ], + "false": [ + { + "type": "choices", + "text": "\t[老人,woman]少年,你需要钥匙吗?\n我这里有大把的!", + "choices": [ + { + "text": "黄钥匙(${9+flag:woman_times}金币)", + "action": [ + { + "type": "if", + "condition": "status:money>=9+flag:woman_times", + "true": [ + { + "type": "setValue", + "name": "status:money", + "value": "status:money-(9+flag:woman_times)" + }, + { + "type": "setValue", + "name": "item:yellowKey", + "value": "item:yellowKey+1" + } + ], + "false": [ + "\t[老人,woman]你的金钱不足!", + { + "type": "revisit" + } + ] + } + ] + }, + { + "text": "蓝钥匙(${18+2*flag:woman_times}金币)", + "action": [ + { + "type": "if", + "condition": "status:money>=18+2*flag:woman_times", + "true": [ + { + "type": "setValue", + "name": "status:money", + "value": "status:money-(18+2*flag:woman_times)" + }, + { + "type": "setValue", + "name": "item:blueKey", + "value": "item:blueKey+1" + } + ], + "false": [ + "\t[老人,woman]你的金钱不足!", + { + "type": "revisit" + } + ] + } + ] + }, + { + "text": "红钥匙(${36+4*flag:woman_times}金币)", + "action": [ + { + "type": "if", + "condition": "status:money>=36+4*flag:woman_times", + "true": [ + { + "type": "setValue", + "name": "status:money", + "value": "status:money-(36+4*flag:woman_times)" + }, + { + "type": "setValue", + "name": "item:redKey", + "value": "item:redKey+1" + } + ], + "false": [ + "\t[老人,woman]你的金钱不足!", + { + "type": "revisit" + } + ] + } + ] + }, + { + "text": "离开", + "action": [ + { + "type": "exit" + } + ] + } + ] + } + ] + } + ] + }, + { + "type": "setValue", + "name": "flag:woman_times", + "value": "flag:woman_times+1" + }, + { + "type": "revisit" + } + ], + "12,11": [ + "\t[老人,womanMagician]使用 {\"type\":\"function\"} 可以写自定义的JS脚本。\n本塔支持的所有主要API会在doc文档内给出。", + "\t[老人,womanMagician]例如这个例子:即将弹出一个输入窗口,然后会将你的输入结果直接加到你的攻击力上。", + { + "type": "input", + "text": "请输入你要加攻击力的数值:" + }, + { + "type": "if", + "condition": "flag:input>0", + "true": [ + { + "type": "setValue", + "name": "status:atk", + "value": "status:atk+flag:input" + }, + { + "type": "tip", + "text": "操作成功,攻击+${flag:input}" + }, + "操作成功,攻击+${flag:input}" + ], + "false": [] + }, + "\t[老人,womanMagician]具体可参见样板中本事件的写法。" + ], + "10,12": null, + "12,12": [ + { + "type": "switch", + "condition": "flag:woman_times", + "caseList": [ + { + "case": "0", + "action": [ + "\t[老人,woman]现在使用switch改写这个例子" + ] + }, + { + "case": "8", + "action": [ + "\t[老人,woman]你购买的钥匙已经够多了,再继续卖给你的话我会有危险的。", + "\t[老人,woman]看在你贡献给我这么多钱的份上,送你一把大黄门钥匙吧,希望你能好好用它。", + { + "type": "setValue", + "name": "item:bigKey", + "value": "item:bigKey+1" + }, + "\t[老人,woman]我先走了,拜拜~", + { + "type": "hide", + "time": 500 + }, + { + "type": "exit" + } + ] + }, + { + "case": "default", + "action": [ + { + "type": "comment", + "text": "当没有符合的值的场合执行此事件" + }, + { + "type": "choices", + "text": "\t[老人,woman]少年,你需要钥匙吗?\n我这里有大把的!", + "choices": [ + { + "text": "黄钥匙(${9+flag:woman_times}金币)", + "color": [255,255,0,1], + "action": [ + { + "type": "if", + "condition": "status:money>=9+flag:woman_times", + "true": [ + { + "type": "setValue", + "name": "status:money", + "value": "status:money-(9+flag:woman_times)" + }, + { + "type": "setValue", + "name": "item:yellowKey", + "value": "item:yellowKey+1" + } + ], + "false": [ + "\t[老人,woman]你的金钱不足!", + { + "type": "revisit" + } + ] + } + ] + }, + { + "text": "蓝钥匙(${18+2*flag:woman_times}金币)", + "color": [0,0,255,1], + "action": [ + { + "type": "if", + "condition": "status:money>=18+2*flag:woman_times", + "true": [ + { + "type": "setValue", + "name": "status:money", + "value": "status:money-(18+2*flag:woman_times)" + }, + { + "type": "setValue", + "name": "item:blueKey", + "value": "item:blueKey+1" + } + ], + "false": [ + "\t[老人,woman]你的金钱不足!", + { + "type": "revisit" + } + ] + } + ] + }, + { + "text": "红钥匙(${36+4*flag:woman_times}金币)", + "color": [255,0,0,1], + "action": [ + { + "type": "if", + "condition": "status:money>=36+4*flag:woman_times", + "true": [ + { + "type": "setValue", + "name": "status:money", + "value": "status:money-(36+4*flag:woman_times)" + }, + { + "type": "setValue", + "name": "item:redKey", + "value": "item:redKey+1" + } + ], + "false": [ + "\t[老人,woman]你的金钱不足!", + { + "type": "revisit" + } + ] + } + ] + }, + { + "text": "离开", + "action": [ + { + "type": "exit" + } + ] + } + ] + } + ] + } + ] + }, + { + "type": "setValue", + "name": "flag:woman_times", + "value": "flag:woman_times+1" + }, + { + "type": "revisit" + } ] }, - "5,5": { - "floorId": "sample2", - "stair": "downFloor", - "direction": "up" + "changeFloor": { + "4,12": { + "floorId": "sample0", + "loc": [ + 6, + 0 + ] + }, + "5,5": { + "floorId": "sample2", + "stair": "downFloor", + "direction": "up" + }, + "10,12": null }, - "10,12": null -}, -"afterBattle": { - "9,6": [ - { - "type": "setValue", - "name": "flag:door", - "value": "flag:door+1" - }, - { - "type": "if", - "condition": "flag:door==2", - "true": [ - { - "type": "openDoor", - "loc": [ - 10, - 5 - ] - } - ], - "false": [] - } - ], - "11,6": [ - { - "type": "setValue", - "name": "flag:door", - "value": "flag:door+1" - }, - { - "type": "if", - "condition": "flag:door==2", - "true": [ - { - "type": "openDoor", - "loc": [ - 10, - 5 - ] - } - ], - "false": [] - } - ], - "10,12": null -}, -"afterGetItem": {}, -"afterOpenDoor": {}, -"cannotMove": {}, -"bgmap": [ + "afterBattle": { + "9,6": [ + { + "type": "setValue", + "name": "flag:door", + "value": "flag:door+1" + }, + { + "type": "if", + "condition": "flag:door==2", + "true": [ + { + "type": "openDoor", + "loc": [ + 10, + 5 + ] + } + ], + "false": [] + } + ], + "11,6": [ + { + "type": "setValue", + "name": "flag:door", + "value": "flag:door+1" + }, + { + "type": "if", + "condition": "flag:door==2", + "true": [ + { + "type": "openDoor", + "loc": [ + 10, + 5 + ] + } + ], + "false": [] + } + ], + "10,12": null + }, + "afterGetItem": {}, + "afterOpenDoor": {}, + "cannotMove": {}, + "bgmap": [ ], -"fgmap": [ + "fgmap": [ -], +] } \ No newline at end of file From 2c3011c17a282b34acbb599aeba067ede279faf0 Mon Sep 17 00:00:00 2001 From: oc Date: Wed, 20 Feb 2019 23:43:39 +0800 Subject: [PATCH 08/21] v255 --- README.md | 2 ++ _docs/event.md | 17 +++++++++++------ 更新说明.txt | 2 ++ 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 2eb8f744..314b01b8 100644 --- a/README.md +++ b/README.md @@ -59,9 +59,11 @@ HTML5 canvas制作的魔塔样板,支持全平台游戏! * [x] 存档方式优化,大幅降低单个存档的占用空间 * [x] 脚本编辑器增加代码格式化的选项 * [x] 事件和脚本编辑器中Ctrl+S可以进行保存 +* [x] 显示选择项提供颜色控制 * [x] 事件的移动勇士增加前进和后退两个操作 * [x] 事件编辑器的下拉框增加滚动条 * [x] 通关后将询问是否进行评分 +* [x] 录像播放失败后可以回退到上个节点 * [x] 修复已知的所有Bug,大量细节优化 ### 2019.2.4 V2.5.4 diff --git a/_docs/event.md b/_docs/event.md index 4ea13806..01c0f726 100644 --- a/_docs/event.md +++ b/_docs/event.md @@ -1528,7 +1528,8 @@ choices是一个很麻烦的事件,它将弹出一个列表供用户进行选 ``` js "x,y": [ // 实际执行的事件列表 - {"type": "choices", "text": "...", // 提示文字 + {"type": "choices", "text": "...", // 提示文字 + "color": [255,0,0,1], // 颜色 "choices": [ {"text": "选项1文字", "action": [ // 选项1执行的事件 @@ -1544,11 +1545,15 @@ choices是一个很麻烦的事件,它将弹出一个列表供用户进行选 ] ``` -其中最外面的"text"为提示文本。同上面的`"type":"text"`一样,支持`${}`表达式的计算,和\t显示名称、图标。text可省略,如果省略将不显示任何提示文字。 +其中最外面的"text"为提示文本。同上面的`"type":"text"`一样,支持`${}`表达式的计算,和\t显示名称、图标,\r更改颜色。text可省略,如果省略将不显示任何提示文字。 choices为一个数组,其中每一项都是一个选项列表。 -每一项的text为显示在屏幕上的选项名,也支持${}的表达式计算,但不支持`\t[]`的显示。action为当用户选择了该选项时将执行的事件。 +每一项的text为显示在屏幕上的选项名,也支持${}的表达式计算,但不支持`\t[]`的显示。 + +action为当用户选择了该选项时将执行的事件。 + +color为可选的,可以是一个字符串(#FF0000),或者一个RGBA数组([255,0,0,1])。 选项可以有任意多个,但一般不要超过6个,否则屏幕可能塞不下。 @@ -1577,7 +1582,7 @@ choices为一个数组,其中每一项都是一个选项列表。 "false": [ // 否则,显示选择页面 {"type": "choices", "text": "\t[老人,woman]少年,你需要钥匙吗?\n我这里有大把的!", // 显示一个卖钥匙的选择页面 "choices": [ // 提供四个选项:黄钥匙、蓝钥匙、红钥匙、离开。前三个选项显示需要的金额 - {"text": "黄钥匙(${9+flag:woman_times}金币)", "action": [ // 第一个选项,黄钥匙 + {"text": "黄钥匙(${9+flag:woman_times}金币)", "color": [255,255,0,1], "action": [ // 第一个选项,黄钥匙 // 选择该选项的执行内容 {"type": "if", "condition": "status:money>=9+flag:woman_times", // 条件判断:钱够不够 "true": [ @@ -1591,10 +1596,10 @@ choices为一个数组,其中每一项都是一个选项列表。 ] } ]}, - {"text": "蓝钥匙(${18+2*flag:woman_times}金币)", "action": [ // 第二个选项:蓝钥匙 + {"text": "蓝钥匙(${18+2*flag:woman_times}金币)", "color": [0,0,255,1], "action": [ // 第二个选项:蓝钥匙 // 逻辑和上面黄钥匙完全相同,略 ]}, - {"text": "红钥匙(${36+4*flag:woman_times}金币)", "action": [ // 第三个选项:红钥匙 + {"text": "红钥匙(${36+4*flag:woman_times}金币)", "color": [255,0,0,1], "action": [ // 第三个选项:红钥匙 // 逻辑和上面黄钥匙完全相同,略 ]}, {"text": "离开", "action": [ // 第四个选项:离开 diff --git a/更新说明.txt b/更新说明.txt index d0ff4cbf..4bf78891 100644 --- a/更新说明.txt +++ b/更新说明.txt @@ -4,9 +4,11 @@ 存档方式优化,大幅降低单个存档的占用空间 脚本编辑器增加代码格式化的选项 事件和脚本编辑器中Ctrl+S可以进行保存 +显示选择项提供颜色控制 事件的移动勇士增加前进和后退两个操作 事件编辑器的下拉框增加滚动条 通关后将询问是否进行评分 +录像播放失败后可以回退到上个节点 修复已知的所有Bug,大量细节优化 ----------------------------------------------------------------------- From 2ae0de551d659b590f49ae230403ec5295db0335 Mon Sep 17 00:00:00 2001 From: ckcz123 Date: Thu, 21 Feb 2019 15:51:10 +0800 Subject: [PATCH 09/21] Fix decodeRoute base64 --- libs/utils.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/utils.js b/libs/utils.js index f1910e4e..f51ca99b 100644 --- a/libs/utils.js +++ b/libs/utils.js @@ -475,7 +475,7 @@ utils.prototype.decodeRoute = function (route) { // 解压缩 try { var v = LZString.decompressFromBase64(route); - if (core.isset(v) && /^[a-zA-Z0-9:]+$/.test(v)) { + if (core.isset(v) && /^[a-zA-Z0-9+\/=:]+$/.test(v)) { route = v; } } catch (e) {} From 49daef63fbb5a28b4a256423afdee292a290199b Mon Sep 17 00:00:00 2001 From: oc Date: Thu, 21 Feb 2019 20:41:50 +0800 Subject: [PATCH 10/21] resume bgm --- _server/editor_blockly.js | 2 +- libs/control.js | 4 +++- libs/core.js | 1 + libs/events.js | 2 -- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/_server/editor_blockly.js b/_server/editor_blockly.js index f9c6723c..b624e7c4 100644 --- a/_server/editor_blockly.js +++ b/_server/editor_blockly.js @@ -137,7 +137,7 @@ editor_blockly = function () { MotaActionBlocks['setWeather_s'].xmlText(), MotaActionBlocks['playBgm_s'].xmlText(), MotaActionBlocks['pauseBgm_s'].xmlText(), - // MotaActionBlocks['resumeBgm_s'].xmlText(), + MotaActionBlocks['resumeBgm_s'].xmlText(), MotaActionBlocks['loadBgm_s'].xmlText(), MotaActionBlocks['freeBgm_s'].xmlText(), MotaActionBlocks['playSound_s'].xmlText(), diff --git a/libs/control.js b/libs/control.js index bdefeb45..f3f96378 100644 --- a/libs/control.js +++ b/libs/control.js @@ -2604,6 +2604,7 @@ control.prototype.playBgm = function (bgm) { if (!core.musicStatus.bgmStatus) { try { core.musicStatus.playingBgm = bgm; + core.musicStatus.lastBgm = bgm; core.material.bgms[bgm].pause(); } catch (e) { @@ -2637,6 +2638,7 @@ control.prototype.playBgm = function (bgm) { core.material.bgms[bgm].currentTime = 0; core.material.bgms[bgm].play(); core.musicStatus.playingBgm = bgm; + core.musicStatus.lastBgm = bgm; } catch (e) { console.log("无法播放BGM "+bgm); @@ -2667,7 +2669,7 @@ control.prototype.resumeBgm = function () { // 恢复BGM try { - core.playBgm(core.musicStatus.playingBgm); + core.playBgm(core.musicStatus.playingBgm || core.musicStatus.lastBgm); } catch (e) { console.log("无法恢复BGM"); diff --git a/libs/core.js b/libs/core.js index ace726a7..f62fb9ce 100644 --- a/libs/core.js +++ b/libs/core.js @@ -53,6 +53,7 @@ function core() { 'bgmStatus': false, // 是否播放BGM 'soundStatus': true, // 是否播放SE 'playingBgm': null, // 正在播放的BGM + 'lastBgm': null, // 上次播放的bgm 'gainNode': null, 'playingSounds': {}, // 正在播放的SE 'volume': 1.0, // 音量 diff --git a/libs/events.js b/libs/events.js index d92d3c96..3cad299e 100644 --- a/libs/events.js +++ b/libs/events.js @@ -967,12 +967,10 @@ events.prototype.doAction = function() { core.pauseBgm(); this.doAction(); break - /* case "resumeBgm": core.resumeBgm(); this.doAction(); break - */ case "loadBgm": if (core.platform.isPC) core.loadBgm(data.name); From a1c044f0793251630cfe45a535c4fbb5f2f625ab Mon Sep 17 00:00:00 2001 From: ckcz123 Date: Fri, 22 Feb 2019 12:13:11 +0800 Subject: [PATCH 11/21] Fix scrollText bug --- libs/ui.js | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/libs/ui.js b/libs/ui.js index 26f86589..9d11eefa 100644 --- a/libs/ui.js +++ b/libs/ui.js @@ -505,6 +505,7 @@ ui.prototype.calTextBoxWidth = function (canvas, content, min_width, max_width) ui.prototype.__drawText = function (canvas, content, content_left, content_top, valid_width, color, per_height, time) { + core.setTextAlign(canvas, 'left'); var offsetx = content_left, offsety = content_top; core.setFillStyle(canvas, color); @@ -543,14 +544,12 @@ ui.prototype.__drawText = function (canvas, content, content_left, content_top, return drawNext(); } // 检查是不是自动换行 - if (core.isset(valid_width)) { - var charwidth = core.calWidth(canvas, ch); - if (offsetx + charwidth > content_left + valid_width) { - index--; - offsetx = content_left; - offsety += per_height; - return drawNext(); - } + var charwidth = core.calWidth(canvas, ch); + if (core.isset(valid_width) && offsetx + charwidth > content_left + valid_width) { + index--; + offsetx = content_left; + offsety += per_height; + return drawNext(); } // 输出 core.fillText(canvas, ch, offsetx, offsety); @@ -831,7 +830,7 @@ ui.prototype.drawScrollText = function (content, time, callback) { tempCanvas.clearRect(0, 0, width, height); tempCanvas.font = font; - this.__drawText(tempCanvas, content, 0, textfont, null, textColor, 1.4*textfont, 0); + this.__drawText(tempCanvas, content, offset, textfont, null, textColor, 1.4*textfont, 0); // 开始绘制到UI上 core.clearMap('ui'); @@ -967,7 +966,6 @@ ui.prototype.drawChoices = function(content, choices) { } } - core.setTextAlign('ui', 'left'); core.setFont('ui', 'bold 15px '+globalFont); this.__drawText('ui', content, content_left, content_top, validWidth, textColor, 20, 0); } From 3e12cfd0b82a2f4efc1592a4513cfe0f8b97ca33 Mon Sep 17 00:00:00 2001 From: ckcz123 Date: Fri, 22 Feb 2019 13:27:40 +0800 Subject: [PATCH 12/21] fix log --- main.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.js b/main.js index aa3b6d8e..802e058b 100644 --- a/main.js +++ b/main.js @@ -316,7 +316,7 @@ main.prototype.setMainTipsText = function (text) { main.prototype.log = function (e) { if (e) { if (main.core && main.core.platform && !main.core.platform.isPC) { - console.log((e.stack || e.toString()).replace("\n", " --- ")); + console.log((e.stack || e.toString())); } else { console.log(e); From 5cd2613f78300d3f57ab4b5004d2d5cbb50a2edd Mon Sep 17 00:00:00 2001 From: ckcz123 Date: Fri, 22 Feb 2019 18:59:21 +0800 Subject: [PATCH 13/21] Fix moveImage --- libs/events.js | 2 +- libs/maps.js | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/libs/events.js b/libs/events.js index 3cad299e..27627d6e 100644 --- a/libs/events.js +++ b/libs/events.js @@ -1810,7 +1810,7 @@ events.prototype.moveImage = function (code, to, opacityVal, time, callback) { var animate = setInterval(function () { step++; moveStep(); - if (step > steps) { + if (step == steps) { if (core.isset(opacityVal)) core.setOpacity(name, opacityVal); delete core.animateFrame.asyncId[animate]; diff --git a/libs/maps.js b/libs/maps.js index 3ad953a4..c0ba3b1f 100644 --- a/libs/maps.js +++ b/libs/maps.js @@ -208,13 +208,14 @@ maps.prototype.decompressMap = function (mapArr, floorId) { var mw = core.floors[floorId].width || 13; var mh = core.floors[floorId].height || 13; for (var x=0;x Date: Mon, 25 Feb 2019 01:40:21 +0800 Subject: [PATCH 14/21] Fix openDoor replay Bug --- _docs/api.md | 1 + libs/core.js | 2 +- libs/events.js | 20 ++++++++++++-------- 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/_docs/api.md b/_docs/api.md index 68606a04..88697135 100644 --- a/_docs/api.md +++ b/_docs/api.md @@ -176,6 +176,7 @@ core.openDoor(id, x, y, needKey, callback) [异步] 尝试开门操作。id为目标点的ID,x和y为坐标,needKey表示是否需要使用钥匙,callback为开门完毕后的回调函数。 id可为null代表使用地图上的值。 例如:core.openDoor('yellowDoor', 10, 3, false, function() {console.log("1")}) +此函数返回true代表成功开门,并将执行callback回调;返回false代表无法开门,且不会执行回调函数。 core.battle(id, x, y, force, callback) [异步] diff --git a/libs/core.js b/libs/core.js index f62fb9ce..0092ac83 100644 --- a/libs/core.js +++ b/libs/core.js @@ -623,7 +623,7 @@ core.prototype.nearHero = function (x, y) { ////// 开门 ////// core.prototype.openDoor = function (id, x, y, needKey, callback) { - core.events.openDoor(id, x, y, needKey, callback); + return core.events.openDoor(id, x, y, needKey, callback); } ////// 战斗 ////// diff --git a/libs/events.js b/libs/events.js index 3cad299e..d351f2e5 100644 --- a/libs/events.js +++ b/libs/events.js @@ -864,11 +864,15 @@ events.prototype.doAction = function() { y = core.calValue(data.loc[1], prefix); } var floorId=data.floorId || core.status.floorId; - if (floorId==core.status.floorId) - core.openDoor(null, x, y, data.needKey, function() { + if (floorId==core.status.floorId) { + var _callback = function () { core.lockControl(); core.events.doAction(); - }) + } + if (!core.openDoor(null, x, y, data.needKey, _callback)) { + _callback(); + } + } else { core.removeBlock(x, y, floorId); this.doAction(); @@ -1423,8 +1427,7 @@ events.prototype.openDoor = function (id, x, y, needKey, callback) { // 是否存在门 if (!core.terrainExists(x, y, id) || !(id.endsWith("Door") || id.endsWith("Wall")) || !core.isset(core.material.icons.animates[id])) { - if (core.isset(callback)) callback(); - return; + return false; } if (core.status.automaticRoute.moveStepBeforeStop.length==0) { core.status.automaticRoute.moveStepBeforeStop=core.status.automaticRoute.autoStepRoutes.slice(core.status.automaticRoute.autoStep-1,core.status.automaticRoute.autoStepRoutes.length); @@ -1440,8 +1443,7 @@ events.prototype.openDoor = function (id, x, y, needKey, callback) { core.drawTip("你没有" + ((core.material.items[key]||{}).name||"钥匙")); else core.drawTip("无法开启此门"); core.clearContinueAutomaticRoute(); - if (core.isset(callback)) callback(); - return; + return false; } core.autosave(true); core.removeItem(key); @@ -1469,7 +1471,9 @@ events.prototype.openDoor = function (id, x, y, needKey, callback) { } core.clearMap('event', 32 * x, 32 * y, 32, 32); core.drawImage('event', core.material.images.animates, 32 * state, 32 * door, 32, 32, 32 * x, 32 * y, 32, 32); - }, speed / core.status.replay.speed) + }, speed / core.status.replay.speed); + + return true; } ////// 战斗 ////// From 3271e79971de7227e264c8bcac67854d1b38b8e5 Mon Sep 17 00:00:00 2001 From: oc Date: Mon, 25 Feb 2019 01:47:42 +0800 Subject: [PATCH 15/21] Fix decompress bug --- libs/maps.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/maps.js b/libs/maps.js index c0ba3b1f..c01f6881 100644 --- a/libs/maps.js +++ b/libs/maps.js @@ -208,7 +208,7 @@ maps.prototype.decompressMap = function (mapArr, floorId) { var mw = core.floors[floorId].width || 13; var mh = core.floors[floorId].height || 13; for (var x=0;x Date: Mon, 25 Feb 2019 17:11:48 +0800 Subject: [PATCH 16/21] Fix centerFly insertAction --- libs/actions.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/actions.js b/libs/actions.js index bd23b4d9..3f33ba50 100644 --- a/libs/actions.js +++ b/libs/actions.js @@ -734,6 +734,7 @@ actions.prototype.keyDownCtrl = function () { ////// actions.prototype.clickCenterFly = function(x, y) { + core.ui.closePanel(); if (x==core.status.event.data.poxX && y==core.status.event.data.posY) { if (core.canUseItem('centerFly')) { core.useItem('centerFly'); @@ -742,10 +743,10 @@ actions.prototype.clickCenterFly = function(x, y) { core.drawTip('当前不能使用中心对称飞行器'); } } - core.ui.closePanel(); } actions.prototype.keyUpCenterFly = function (keycode) { + core.ui.closePanel(); if (keycode==51 || keycode==13 || keycode==32 || keycode==67) { if (core.canUseItem('centerFly')) { core.useItem('centerFly'); @@ -754,7 +755,6 @@ actions.prototype.keyUpCenterFly = function (keycode) { core.drawTip('当前不能使用中心对称飞行器'); } } - core.ui.closePanel(); } From 8170d308611c2d544c4362942bc5188b10adb400 Mon Sep 17 00:00:00 2001 From: ckcz123 Date: Mon, 25 Feb 2019 17:17:38 +0800 Subject: [PATCH 17/21] Fix centerFly insertAction --- libs/actions.js | 3 ++- libs/events.js | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/libs/actions.js b/libs/actions.js index 3f33ba50..a899d99e 100644 --- a/libs/actions.js +++ b/libs/actions.js @@ -734,8 +734,9 @@ actions.prototype.keyDownCtrl = function () { ////// actions.prototype.clickCenterFly = function(x, y) { + var posX = core.status.event.data.posX, posY = core.status.event.data.posY; core.ui.closePanel(); - if (x==core.status.event.data.poxX && y==core.status.event.data.posY) { + if (x==posX&& y==posY) { if (core.canUseItem('centerFly')) { core.useItem('centerFly'); } diff --git a/libs/events.js b/libs/events.js index 16f3ed3e..55a10979 100644 --- a/libs/events.js +++ b/libs/events.js @@ -2050,7 +2050,7 @@ events.prototype.useItem = function(itemId) { core.ui.drawThumbnail(core.status.floorId, 'ui', core.status.thisMap.blocks, 0, 0, 416, toX, toY, core.status.hero.loc, core.getFlag('heroIcon', "hero.png")); var offsetX = core.clamp(toX-6, 0, core.bigmap.width-13), offsetY = core.clamp(toY-6, 0, core.bigmap.height-13); core.fillRect('ui',(toX-offsetX)*32,(toY-offsetY)*32,32,32,fillstyle); - core.status.event.data = {"x": toX, "y": toY, "poxX": toX-offsetX, "posY": toY-offsetY}; + core.status.event.data = {"x": toX, "y": toY, "posX": toX-offsetX, "posY": toY-offsetY}; core.drawTip("请确认当前中心对称飞行器的位置"); return; } From 4ae6decb8ab4a003342343d4eed0ff245cedfd0c Mon Sep 17 00:00:00 2001 From: oc Date: Mon, 25 Feb 2019 22:25:26 +0800 Subject: [PATCH 18/21] compressMap __initFloorMap --- libs/maps.js | 36 +++++++++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/libs/maps.js b/libs/maps.js index c01f6881..6b7d28c9 100644 --- a/libs/maps.js +++ b/libs/maps.js @@ -178,20 +178,42 @@ maps.prototype.initMaps = function (floorIds) { return maps; } +maps.prototype.__initFloorMap = function (floorId) { + var map = core.clone(core.floors[floorId].map); + + var mw = core.floors[floorId].width || 13; + var mh = core.floors[floorId].height || 13; + + for (var x=0;x Date: Tue, 26 Feb 2019 00:19:56 +0800 Subject: [PATCH 19/21] iconLib scrollBar --- _server/editor.js | 35 +++++++++++++++++++++++++++++------ 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/_server/editor.js b/_server/editor.js index 42d8c154..5e49f784 100644 --- a/_server/editor.js +++ b/_server/editor.js @@ -645,12 +645,6 @@ editor.prototype.listen = function () { if(clickpath.length>=2 && clickpath[0].indexOf('id_')===0){editor.lastClickId=clickpath[0]} } - var iconLib=document.getElementById('iconLib'); - iconLib.onmousedown = function (e) { - console.log("iconLib: ("+e.clientX+","+e.clientY+")"); - e.stopPropagation(); - } - var eui=document.getElementById('eui'); var uc = eui.getContext('2d'); @@ -971,9 +965,38 @@ editor.prototype.listen = function () { } } + var getScrollBarHeight = function () { + var outer = document.createElement("div"); + outer.style.visibility = "hidden"; + outer.style.width = "100px"; + outer.style.msOverflowStyle = "scrollbar"; // needed for WinJS apps + + document.body.appendChild(outer); + + var widthNoScroll = outer.offsetWidth; + // force scrollbars + outer.style.overflow = "scroll"; + + // add innerdiv + var inner = document.createElement("div"); + inner.style.width = "100%"; + outer.appendChild(inner); + + var widthWithScroll = inner.offsetWidth; + + // remove divs + outer.parentNode.removeChild(outer); + + return widthNoScroll - widthWithScroll; + } + var scrollBarHeight = getScrollBarHeight(); + console.log(scrollBarHeight); + var dataSelection = document.getElementById('dataSelection'); + var iconLib=document.getElementById('iconLib'); iconLib.onmousedown = function (e) { e.stopPropagation(); + if (!editor.isMobile && e.clientY>=(635 - 5 - scrollBarHeight)) return; var scrollLeft = document.documentElement.scrollLeft || document.body.scrollLeft; var scrollTop = document.documentElement.scrollTop || document.body.scrollTop; var loc = { From e904032d3a572daf2c583036245ee8e610716246 Mon Sep 17 00:00:00 2001 From: oc Date: Tue, 26 Feb 2019 00:23:12 +0800 Subject: [PATCH 20/21] getEnemyInfo if damage is null --- libs/enemys.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/libs/enemys.js b/libs/enemys.js index d3a56e3e..6049ce82 100644 --- a/libs/enemys.js +++ b/libs/enemys.js @@ -184,8 +184,9 @@ enemys.prototype.nextCriticals = function (enemy, number, x, y, floorId) { var info = this.getDamageInfo(enemy, core.status.hero.hp, core.status.hero.atk, core.status.hero.def, core.status.hero.mdef, x, y, floorId); if (info == null) { - if (core.status.hero.atk<=enemy.def) { - return [[enemy.def+1-core.status.hero.atk,'?']]; + info = this.getEnemyInfo(enemy, core.status.hero.hp, core.status.hero.atk, core.status.hero.def, core.status.hero.mdef, x, y, floorId); + if (core.status.hero.atk<=info.def) { + return [[info.def+1-core.status.hero.atk,'?']]; } return []; } From d27fc7c3fc3fdabcb9d0925d4010a51480f81600 Mon Sep 17 00:00:00 2001 From: oc Date: Tue, 26 Feb 2019 02:14:24 +0800 Subject: [PATCH 21/21] tilesets 3000 --- _server/editor.js | 4 ++-- libs/loader.js | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/_server/editor.js b/_server/editor.js index 5e49f784..006a4df2 100644 --- a/_server/editor.js +++ b/_server/editor.js @@ -153,8 +153,8 @@ editor.prototype.idsInit = function (maps, icons) { if(img.width%32 || img.height%32){ alert(imgName+'的长或宽不是32的整数倍, 请修改后刷新页面'); } - if(img.width*img.height > 32*32*1000){ - alert(imgName+'上的图块数量超过了1000,请修改后刷新页面'); + if(img.width*img.height > 32*32*3000){ + alert(imgName+'上的图块数量超过了3000,请修改后刷新页面'); } for (var id=startOffset; id 32*32*1000) { - console.warn("警告!"+imgName+"上的图块素材个数大于1000!"); + if (img.width * img.height > 32*32*3000) { + console.warn("警告!"+imgName+"上的图块素材个数大于3000!"); } }