diff --git a/README.md b/README.md index cc9133ec..96af4734 100644 --- a/README.md +++ b/README.md @@ -56,6 +56,7 @@ HTML5 canvas制作的魔塔样板,支持全平台游戏! ### 2018.10.14 V2.4.3 * [x] 并行事件处理 +* [x] 事件:设置楼层属性 * [x] 增加光环属性,还可以制作区域光环效果 * [x] 将部分代码移动到脚本编辑中 * [x] 事件改变天气或画面色调,读档后仍有效 diff --git a/_server/blockly/MotaAction.g4 b/_server/blockly/MotaAction.g4 index 67bbc574..b398d157 100644 --- a/_server/blockly/MotaAction.g4 +++ b/_server/blockly/MotaAction.g4 @@ -185,6 +185,7 @@ action | setText_s | tip_s | setValue_s + | setFloor_s | show_s | hide_s | trigger_s @@ -367,6 +368,21 @@ var code = '{"type": "setValue", "name": "'+idString_e_0+'", "value": "'+express return code; */; +setFloor_s + : '设置楼层属性' ':' Floor_Meta_List '楼层名' IdString? '值' EvalString Newline + + +/* setFloor_s +tooltip : setFloor:设置楼层属性;该楼层属性和编辑器中的楼层属性一一对应 +helpUrl : https://ckcz123.github.io/mota-js/#/event?id=setFloor%ef%bc%9a%e8%ae%be%e7%bd%ae%e6%a5%bc%e5%b1%82%e5%b1%9e%e6%80%a7 +default : ["title","","'字符串类型的值要加引号,其他类型则不用'"] +colour : this.dataColor +IdString_0 = IdString_0 && (', "floorId": "'+IdString_0+'"'); +var code = '{"type": "setFloor", "name": "'+Floor_Meta_List_0+'"'+IdString_0+', "value": "'+EvalString_0+'"},\n'; +return code; +*/; + + show_s : '显示事件' 'x' EvalString? ',' 'y' EvalString? '楼层' IdString? '动画时间' Int? Newline @@ -1461,6 +1477,9 @@ Bg_Fg_List : '背景层'|'前景层' /*Bg_Fg_List ['bg','fg']*/; +Floor_Meta_List + : '楼层中文名'|'状态栏名称'|'能否使用楼传'|'能否打开快捷商店'|'是否不可浏览地图'|'默认地面ID'|'楼层贴图'|'宝石血瓶效果'|'上楼点坐标'|'下楼点坐标'|'背景音乐'|'画面色调'|'天气和强度'|'是否地下层' + /*Floor_Meta_List ['title','name','canFlyTo', 'canUseQuickShop', 'cannotViewMap', 'defaultGround', 'images', 'item_ratio', 'upFloor', 'downFloor', 'bgm', 'color', 'weather', 'underGround']*/; Bool: 'TRUE' | 'FALSE' @@ -1921,6 +1940,10 @@ ActionParser.prototype.parseAction = function() { MotaActionBlocks['evalString_e'].xmlText([data.value]), this.next]); break; + case "setFloor": + this.next = MotaActionBlocks['setFloor_s'].xmlText([ + data.name, data.floorId||null, data.value, this.next]); + break; case "input": this.next = MotaActionBlocks['input_s'].xmlText([ data.text,this.next]); diff --git a/_server/editor_blockly.js b/_server/editor_blockly.js index bb6724d9..4a12dd87 100644 --- a/_server/editor_blockly.js +++ b/_server/editor_blockly.js @@ -87,6 +87,7 @@ editor_blockly = function () { MotaActionBlocks['setValue_s'].xmlText([ MotaActionBlocks['idString_1_e'].xmlText(['status','hp']) ]), + MotaActionBlocks['setFloor_s'].xmlText(), MotaActionBlocks['input_s'].xmlText(), MotaActionBlocks['input2_s'].xmlText(), MotaActionBlocks['update_s'].xmlText(), diff --git a/docs/event.md b/docs/event.md index 8d438840..82075336 100644 --- a/docs/event.md +++ b/docs/event.md @@ -359,6 +359,31 @@ value是一个表达式,将通过这个表达式计算出的结果赋值给nam 另外注意一点的是,如果hp被设置成了0或以下,将触发lose事件,直接死亡。 +### setFloor:设置楼层属性 + +使用`{"type":"setFloor"}`可以设置某层楼的楼层属性。 + +``` js +"x,y": [ // 实际执行的事件列表 + {"type": "setFloor", "name": "title", "value": "'主塔 0 层'" } // 设置当前楼层的中文名为主塔0层 + {"type": "setFloor", "name": "canFlyTo", "floorId": "MT2", "value": "false" } // 设置MT2层不可飞行 + {"type": "setFloor", "name": "cannotViewMap", "floorId": "MT0", "value": "true" } // 设置MT0层不可被浏览地图 + {"type": "setFloor", "name": "item_ratio", "value": "5" } // 设置当前楼层的宝石血瓶属性加成为5 + {"type": "setFloor", "name": "images", "value": "[[0,0,'tree.png',2]]" } // 设置当前楼层的楼层贴图 + {"type": "setFloor", "name": "upFloor", "value": "[2,3]" } // 设置当前楼层的上楼梯 + {"type": "setFloor", "name": "bgm", "floorId": "MT10", "value": "'233.mp3'" } // 设置当前楼层的背景音乐 +] +``` + +name为必填项,代表要修改的楼层属性。其和楼层属性中一一对应,目前只能为`"title", "name", "canFlyTo", "canUseQuickShop", "cannotViewMap", "color", "weather", +"defaultGround", "images", "item_ratio", "upFloor", "bgm", "downFloor", "underGround"`。 + +floorId为可选项,代表要修改的楼层ID;可以省略代表当前楼层。 + +value为必填项,代表要修改到的数值。其应该和楼层属性中的对应数值类型完全一致,对于字符串需要加单引号,其他类型(数字、true/false、数组)等则不需要引号。 + +!> 如果修改到的是字符串类型,比如楼层中文名、状态栏名称、地面素材ID、背景音乐等,必须加引号,否则会报错。 + ### show:将一个禁用事件启用 我们上面提到了,所有事件都必须靠其他事件驱动来完成,不存在当某个flag为true时自动执行的说法。那么,我们自然要有启用事件的写法。 diff --git a/libs/actions.js b/libs/actions.js index ecccf697..ea8e84cc 100644 --- a/libs/actions.js +++ b/libs/actions.js @@ -1047,14 +1047,14 @@ actions.prototype.clickViewMaps = function (x,y) { if(y<=4 && (mh==13 || (x>=2 && x<=10))) { index++; - while (index=8 && (mh==13 || (x>=2 && x<=10))) { index--; - while (index>=0 && index!=now && core.floors[core.floorIds[index]].cannotViewMap) + while (index>=0 && index!=now && core.status.maps[core.floorIds[index]].cannotViewMap) index--; if (index>=0) core.ui.drawMaps(index); diff --git a/libs/control.js b/libs/control.js index c3c94630..c15c547c 100644 --- a/libs/control.js +++ b/libs/control.js @@ -2590,8 +2590,8 @@ control.prototype.resumeBgm = function () { } else { if (core.bgms.length>0) { - if (core.isset(core.floors[core.status.floorId].bgm)) { - core.playBgm(core.floors[core.status.floorId].bgm); + if (core.isset(core.status.thisMap.bgm)) { + core.playBgm(core.status.thisMap.bgm); } else core.playBgm(core.bgms[0]); diff --git a/libs/events.js b/libs/events.js index 2938afd6..bfb5ba3f 100644 --- a/libs/events.js +++ b/libs/events.js @@ -793,6 +793,13 @@ events.prototype.doAction = function() { this.doAction(); } break; + case "setFloor": + { + core.status.maps[data.floorId||core.status.floorId][data.name] = core.calValue(data.value); + core.updateStatusBar(); + this.doAction(); + break; + } case "setHeroIcon": { this.setHeroIcon(data.name); @@ -1188,6 +1195,29 @@ events.prototype.trigger = function (x, y) { } } +events.prototype.setFloorName = function (floorId) { + floorId = floorId || core.status.floorId; + // 根据文字判断是否斜体 + var floorName = core.status.maps[floorId].name || ""; + if (typeof floorName == 'number') floorName = ""+floorName; + if (!core.isset(floorName) || floorName=="") floorName=" " + if (core.statusBar.floor.innerHTML == floorName) return; + core.statusBar.floor.innerHTML = floorName; + if (/^[+-]?\d+$/.test(floorName)) { + core.statusBar.floor.style.fontStyle = 'italic'; + core.statusBar.floor.style.fontSize = '1.1em'; + } + else { + core.statusBar.floor.style.fontStyle = 'normal'; + if (floorName.length<=5) + core.statusBar.floor.style.fontSize = '1.1em'; + else if (floorName.length==6) + core.statusBar.floor.style.fontSize = '0.9em'; + else + core.statusBar.floor.style.fontSize = '0.7em'; + } +} + ////// 楼层切换 ////// events.prototype.changeFloor = function (floorId, stair, heroLoc, time, callback, fromLoad) { @@ -1219,9 +1249,9 @@ events.prototype.changeFloor = function (floorId, stair, heroLoc, time, callback if (core.isset(stair)) { if (!core.isset(heroLoc)) heroLoc={}; - if (core.isset(core.floors[floorId][stair])) { - heroLoc.x = core.floors[floorId][stair][0]; - heroLoc.y = core.floors[floorId][stair][1]; + if (core.isset(core.status.maps[floorId][stair])) { + heroLoc.x = core.status.maps[floorId][stair][0]; + heroLoc.y = core.status.maps[floorId][stair][1]; } else { var blocks = core.status.maps[floorId].blocks; @@ -1249,35 +1279,19 @@ events.prototype.changeFloor = function (floorId, stair, heroLoc, time, callback var changing = function () { - // 根据文字判断是否斜体 - var floorName = core.status.maps[floorId].name; - if (!core.isset(floorName) || floorName=="") floorName=" " - core.statusBar.floor.innerHTML = floorName; - if (/^[+-]?\d+$/.test(floorName)) { - core.statusBar.floor.style.fontStyle = 'italic'; - core.statusBar.floor.style.fontSize = '1.1em'; - } - else { - core.statusBar.floor.style.fontStyle = 'normal'; - if (floorName.length<=5) - core.statusBar.floor.style.fontSize = '1.1em'; - else if (floorName.length==6) - core.statusBar.floor.style.fontSize = '0.9em'; - else - core.statusBar.floor.style.fontSize = '0.7em'; - } + core.events.setFloorName(floorId); // 更改BGM - if (core.isset(core.floors[floorId].bgm)) { - var bgm = core.floors[floorId].bgm; + if (core.isset(core.status.maps[floorId].bgm)) { + var bgm = core.status.maps[floorId].bgm; if (bgm instanceof Array) bgm = bgm[0]; core.playBgm(bgm); } // 不存在事件时,更改画面色调 var color = core.getFlag('color', null); - if (!core.isset(color) && core.isset(core.floors[floorId].color)) { - color = core.floors[floorId].color; + if (!core.isset(color) && core.isset(core.status.maps[floorId].color)) { + color = core.status.maps[floorId].color; } if (core.isset(color)) { // 直接变色 @@ -1296,8 +1310,8 @@ events.prototype.changeFloor = function (floorId, stair, heroLoc, time, callback // 更改天气 var weather = core.getFlag('weather', null); - if (!core.isset(weather) && core.isset(core.floors[floorId].weather)) { - weather = core.floors[floorId].weather; + if (!core.isset(weather) && core.isset(core.status.maps[floorId].weather)) { + weather = core.status.maps[floorId].weather; } if (core.isset(weather)) { core.setWeather(weather[0], weather[1]) diff --git a/libs/items.js b/libs/items.js index 82fcd95d..41f96b89 100644 --- a/libs/items.js +++ b/libs/items.js @@ -22,7 +22,7 @@ items.prototype.getItemEffect = function(itemId, itemNum) { var itemCls = core.material.items[itemId].cls; // 消耗品 if (itemCls === 'items') { - var ratio = parseInt(core.floors[core.status.floorId].item_ratio) || 1; + var ratio = parseInt(core.status.thisMap.item_ratio) || 1; var curr_hp = core.status.hero.hp; if (itemId in this.itemEffect)eval(this.itemEffect[itemId]); core.status.hero.statistics.hp += core.status.hero.hp - curr_hp; @@ -37,7 +37,7 @@ items.prototype.getItemEffectTip = function(itemId) { var itemCls = core.material.items[itemId].cls; // 消耗品 if (itemCls === 'items') { - var ratio = parseInt(core.floors[core.status.floorId].item_ratio) || 1; + var ratio = parseInt(core.status.thisMap.item_ratio) || 1; if (itemId in this.itemEffectTip) return eval(this.itemEffectTip[itemId])||""; } return ""; diff --git a/libs/maps.js b/libs/maps.js index 0ccd3926..7e4c36f9 100644 --- a/libs/maps.js +++ b/libs/maps.js @@ -10,12 +10,18 @@ maps.prototype.init = function() { ////// 加载某个楼层(从剧本或存档中) ////// maps.prototype.loadFloor = function (floorId, map) { var floor = core.floors[floorId]; + + if (!core.isset(map)) map = floor.map; + if (map instanceof Array) { + map = {"map": map}; + } var content = {}; - content['floorId'] = floor.floorId; - content['name'] = floor.name; - content['title'] = floor.title; - content['canFlyTo'] = floor.canFlyTo; - if (!core.isset(map)) map=floor.map; + ["floorId", "title", "name", "canFlyTo", "canUseQuickShop", "cannotViewMap", "color", "weather", + "defaultGround", "images", "item_ratio", "upFloor", "bgm", "downFloor", "underGround"].forEach(function (e) { + if (core.isset(map[e])) content[e] = core.clone(map[e]); + else content[e] = core.clone(floor[e]); + }); + map=map.map; var mapIntoBlocks = function(map,maps,floor,floorId){ var blocks = []; var mw = core.floors[floorId].width || 13; @@ -168,7 +174,7 @@ maps.prototype.save = function(maps, floorId) { return map; } - var thisFloor = maps[floorId]; + var thisFloor = core.clone(maps[floorId]); var mw = core.floors[floorId].width || 13; var mh = core.floors[floorId].height || 13; @@ -186,7 +192,9 @@ maps.prototype.save = function(maps, floorId) { } else blocks[block.y][block.x] = block.id; }); - return blocks; + delete thisFloor.blocks; + thisFloor.map = blocks; + return main.mode == 'editor' ? blocks : thisFloor; } ////// 更改地图画布的尺寸 @@ -383,7 +391,7 @@ maps.prototype.drawBgFgMap = function (floorId, canvas, name) { var width = core.floors[floorId].width || 13; var height = core.floors[floorId].height || 13; - var groundId = core.floors[floorId].defaultGround || "ground"; + var groundId = (core.status.maps||core.floors)[floorId].defaultGround || "ground"; var blockIcon = core.material.icons.terrains[groundId]; var blockImage = core.material.images.terrains; @@ -442,8 +450,8 @@ maps.prototype.drawMap = function (mapName, callback) { core.maps.drawBgFgMap(mapName, core.canvas.fg, "fg"); var images = []; - if (core.isset(core.floors[mapName].images)) { - images = core.floors[mapName].images; + if (core.isset(core.status.maps[mapName].images)) { + images = core.status.maps[mapName].images; if (typeof images == 'string') { images = [[0, 0, images]]; } diff --git a/libs/ui.js b/libs/ui.js index e8317f43..4744889b 100644 --- a/libs/ui.js +++ b/libs/ui.js @@ -1628,7 +1628,7 @@ ui.prototype.drawMaps = function (index, x, y) { core.setFont('data', '16px Arial'); - var text = core.floors[floorId].title; + var text = core.status.maps[floorId].title; if (mw>13 || mh>13) text+=" ["+(x-6)+","+(y-6)+"]"; var textX = 16, textY = 18, width = textX + core.canvas.data.measureText(text).width + 16, height = 42; core.fillRect('data', 5, 5, width, height, '#000'); @@ -2050,8 +2050,8 @@ ui.prototype.drawThumbnail = function(floorId, canvas, blocks, x, y, size, cente // background image var images = []; - if (core.isset(core.floors[floorId].images)) { - images = core.floors[floorId].images; + if (core.isset((core.status.maps||core.floors)[floorId].images)) { + images = (core.status.maps||core.floors)[floorId].images; if (typeof images == 'string') { images = [[0, 0, images]]; } @@ -2203,7 +2203,7 @@ ui.prototype.drawStatistics = function () { var current = core.clone(total); core.floorIds.forEach(function (floorId) { - var floor=core.floors[floorId]; + var floor=core.status.maps[floorId]; var blocks=core.status.maps[floorId].blocks; // 隐藏层不给看 if (floor.cannotViewMap && floorId!=core.status.floorId) return; diff --git a/project/functions.js b/project/functions.js index 454cd03f..827b5ed5 100644 --- a/project/functions.js +++ b/project/functions.js @@ -345,7 +345,7 @@ functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = // 返回null代表可以使用 // 检查当前楼层的canUseQuickShop选项是否为false - if (core.floors[core.status.floorId].canUseQuickShop === false) + if (core.status.thisMap.canUseQuickShop === false) return '当前楼层不能使用快捷商店。'; return null; @@ -574,8 +574,8 @@ functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = var fromId = core.status.floorId; // 检查能否飞行 - if (!core.floors[fromId].canFlyTo || !core.floors[toId].canFlyTo) { - core.drawTip("无法飞往" + core.floors[toId].title +"!"); + if (!core.status.maps[fromId].canFlyTo || !core.status.maps[toId].canFlyTo) { + core.drawTip("无法飞往" + core.status.maps[toId].title +"!"); return false; } @@ -583,7 +583,7 @@ functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = var fromIndex = core.floorIds.indexOf(fromId), toIndex = core.floorIds.indexOf(toId); var stair = fromIndex<=toIndex?"downFloor":"upFloor"; // 地下层:同层传送至上楼梯 - if (fromIndex == toIndex && core.floorIds[fromId].underGround) stair = "upFloor"; + if (fromIndex == toIndex && core.status.maps[fromId].underGround) stair = "upFloor"; // 记录录像 core.status.route.push("fly:"+toId); // 传送 @@ -603,6 +603,9 @@ functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = core.setStatus('hp', Math.min(core.getStatus('hpmax'), core.getStatus('hp'))); } + // 设置楼层名 + core.events.setFloorName(); + // 设置勇士名字和图标 core.statusBar.name.innerHTML = core.getStatus('name'); diff --git a/更新说明.txt b/更新说明.txt index b838085c..d713bd0f 100644 --- a/更新说明.txt +++ b/更新说明.txt @@ -1,6 +1,7 @@ HTML5魔塔样板V2.4.3 并行事件处理 +事件:设置楼层属性 增加光环属性,还可以制作区域光环效果 将部分代码移动到脚本编辑中 (怪物属性获取、楼层传送、数据统计等)