diff --git a/README.md b/README.md index e84d092e..2a60c151 100644 --- a/README.md +++ b/README.md @@ -63,6 +63,19 @@ HTML5 canvas制作的魔塔样板,支持全平台游戏! ## 更新说明 +### 2018.4.25 V2.1.1 + +* [x] 新增事件:改变勇士行走图 +* [x] 楼传器落点设置 +* [x] 录像回放从任意存档点开始 +* [x] 录像过程中允许存档 +* [x] 血网显伤 +* [x] 怪物手册显示接下来的临界表 +* [x] 重置当前楼层地图core.resetMap() +* [x] 支持部分楼层不允许浏览地图 +* [x] 修复部分浏览器无法进入游戏的Bug +* [x] 其他细节优化 + ### 2018.4.19 V2.1 * [x] 编辑器添加新建和删除按钮;地图自动保存 diff --git a/_server/blockly/MotaAction.g4 b/_server/blockly/MotaAction.g4 index 033ed685..55944530 100644 --- a/_server/blockly/MotaAction.g4 +++ b/_server/blockly/MotaAction.g4 @@ -165,6 +165,7 @@ action | revisit_s | exit_s | setBlock_s + | setHeroIcon_s | update_s | sleep_s | battle_s @@ -415,6 +416,20 @@ var code = '{"type": "setBlock", "number":'+Int_0+floorstr+IdString_0+'},\n'; return code; */ +setHeroIcon_s + : '更改角色行走图' EvalString? Newline + ; + +/* setHeroIcon_s +tooltip : setHeroIcon:更改角色行走图 +helpUrl : https://ckcz123.github.io/mota-js/#/event?id=setHeroIcon-%e6%9b%b4%e6%94%b9%e8%a7%92%e8%89%b2%e8%a1%8c%e8%b5%b0%e5%9b%be +colour : this.dataColor +default : ["hero.png"] +EvalString_0 = EvalString_0 && (', "name": "'+EvalString_0+'"'); +var code = '{"type": "setHeroIcon"'+EvalString_0+'},\n'; +return code; +*/ + update_s : '更新状态栏和地图显伤' Newline ; @@ -1262,6 +1277,10 @@ ActionParser.prototype.parseAction = function() { this.next = MotaActionBlocks['setBlock_s'].xmlText([ data.number||0,data.loc[0]||'',data.loc[1]||'',data.floorId||'',this.next]); break; + case "setHeroIcon": // 改变勇士 + this.next = MotaActionBlocks['setHeroIcon_s'].xmlText([ + data.name||"",this.next]); + break; case "move": // 移动事件 data.loc=data.loc||[]; this.next = MotaActionBlocks['move_s'].xmlText([ diff --git a/project/comment.js b/_server/comment.js similarity index 92% rename from project/comment.js rename to _server/comment.js index 835335bc..0a138152 100644 --- a/project/comment.js +++ b/_server/comment.js @@ -256,6 +256,24 @@ comment_c456ea59_6018_45ef_8bcc_211a24c627dc = "_bool": "bool", "_data": "该层是否允许使用快捷商店" }, + "cannotViewMap": { + "_leaf": true, + "_type": "checkbox", + "_bool": "bool", + "_data": "该层是否不允许被浏览地图看到;如果勾上则浏览地图会跳过该层" + }, + "upFloor": { + "_leaf": true, + "_type": "textarea", + "_range": "thiseval==null||((thiseval instanceof Array) && thiseval.length==2)", + "_data": "该层上楼点,如[2,3]。\n如果此项不为null,则楼层转换时的stair:upFloor,以及楼传器的落点会被替换成该点而不是该层的上楼梯。" + }, + "downFloor": { + "_leaf": true, + "_type": "textarea", + "_range": "thiseval==null||((thiseval instanceof Array) && thiseval.length==2)", + "_data": "该层上楼点,如[2,3]。\n如果此项不为null,则楼层转换时的stair:downFloor,以及楼传器的落点会被替换成该点而不是该层的下楼梯。" + }, "defaultGround": { "_leaf": true, "_type": "select", diff --git a/project/data.comment.js b/_server/data.comment.js similarity index 99% rename from project/data.comment.js rename to _server/data.comment.js index c33ab63e..ee5745da 100644 --- a/project/data.comment.js +++ b/_server/data.comment.js @@ -135,7 +135,7 @@ data_comment_c456ea59_6018_45ef_8bcc_211a24c627dc = "constants": { "_leaf": true, "_type": "textarea", - "_data": "初始永久道具个数,例如初始送手册可以写 {'book': true}" + "_data": "初始永久道具个数,例如初始送手册可以写 {'book': 1}" }, "tools": { "_leaf": true, diff --git a/_server/editor_blockly.js b/_server/editor_blockly.js index 0baf0f45..3c8ff664 100644 --- a/_server/editor_blockly.js +++ b/_server/editor_blockly.js @@ -90,6 +90,7 @@ editor_blockly = function () { MotaActionBlocks['battle_s'].xmlText(), MotaActionBlocks['openDoor_s'].xmlText(), MotaActionBlocks['setBlock_s'].xmlText(), + MotaActionBlocks['setHeroIcon_s'].xmlText(), '', MotaActionBlocks['if_s'].xmlText(), MotaActionBlocks['revisit_s'].xmlText(), diff --git a/_server/editor_file.js b/_server/editor_file.js index 47269812..cc80ed8e 100644 --- a/_server/editor_file.js +++ b/_server/editor_file.js @@ -13,9 +13,9 @@ editor_file = function (editor, callback) { var value = commentjs[key]; var script = document.createElement('script'); if (window.location.href.indexOf('_server') !== -1) - script.src = '../project/' + key + '.js'; + script.src = key + '.js'; else - script.src = 'project/' + key + '.js'; + script.src = '_server/' + key + '.js'; document.body.appendChild(script); script.onload = function () { editor_file[value] = eval(key.replace('.', '_') + '_c456ea59_6018_45ef_8bcc_211a24c627dc'); @@ -125,6 +125,7 @@ editor_file = function (editor, callback) { name: "0", canFlyTo: true, canUseQuickShop: true, + cannotViewMap: false, images: [], item_ratio: 1, firstArrive: [], diff --git a/project/functions.comment.js b/_server/functions.comment.js similarity index 100% rename from project/functions.comment.js rename to _server/functions.comment.js diff --git a/project/maps.comment.js b/_server/maps.comment.js similarity index 100% rename from project/maps.comment.js rename to _server/maps.comment.js diff --git a/docs/V2.0.md b/docs/V2.0.md index 2075f6d4..177e2cb5 100644 --- a/docs/V2.0.md +++ b/docs/V2.0.md @@ -78,7 +78,7 @@ GUI界面分为`地图编辑器`,`事件编辑器`和`文本编辑器`。 > 面向有一定编程基础的用户 -修改`project/`下的`*comment.js`可以让地图编辑器对自己添加的属性有更好的支持.例如: +修改`_server/`下的`*comment.js`可以让地图编辑器对自己添加的属性有更好的支持.例如: + 给`comment.js`中`enemys`加入新的键值对,就可以更方便的给怪物在UI界面中添加对应的值. + 在`data.comment.js`中把自己添加的内容标记为叶节点,不再在表格中展开到最末端. diff --git a/docs/element.md b/docs/element.md index 246dd695..83ee5d5c 100644 --- a/docs/element.md +++ b/docs/element.md @@ -165,6 +165,8 @@ floorId指定的是目标楼层的唯一标识符(ID)。 可以指定time,指定后切换动画时长为指定的数值。 +**从2.1.1开始,楼层属性中提供了`upFloor`和`downFloor`两项。如果设置此项(比如`"upFloor": [2,3]`),则写stair:upFloor或者楼传器的落点将用此点来替换楼梯位置(即类似于RM中的上箭头)。** + ## 动画和天气系统 现在我们的H5魔塔支持播放动画,也支持天气系统了。 diff --git a/docs/event.md b/docs/event.md index 7f10a94e..1d60fad1 100644 --- a/docs/event.md +++ b/docs/event.md @@ -482,6 +482,26 @@ number为**要更改到的数字**,有关“数字”的定义详见参见[素 图块更改往往与[同一个点的多事件处理](#同一个点的多事件处理)相关。 +### setHeroIcon:更改角色行走图 + +使用`{"type": "setHeroIcon"}`可以更改角色行走图。 + +``` js +"x,y": [ // 实际执行的事件列表 + {"type": "setHeroIcon", "name": "hero2.png"}, // 将勇士行走图改成hero2.png;必须在全塔属性的images中被定义过。 + {"type": "setHeroIcon"}, // 如果不加name则恢复最初默认状态 + {"type": "setValue", "name": "status:name", "value": "'可绒'"}, // 修改勇士名;请注意value必须加单引号。 +] +``` + +name是可选的,代表目标行走图的文件名。 + +!> **目标行走图必须在全塔属性的this.images中被定义过,且宽度必须是128像素(高度不限)。** + +如果不加name,则恢复默认的角色行走图。 + +如果你需要同时修改勇士的名称,可以使用`setValue`事件来修改`status:name`,但请注意value必须加单引号,不然会报错。 + ### update: 立刻更新状态栏和地图显伤 如果你需要刷新状态栏和地图显伤,只需要简单地调用 `{"type": "update"}` 即可。 diff --git a/libs/actions.js b/libs/actions.js index af7224ef..eb98a683 100644 --- a/libs/actions.js +++ b/libs/actions.js @@ -13,7 +13,7 @@ actions.prototype.init = function () { ////// 按下某个键时 ////// actions.prototype.onkeyDown = function (e) { - if (core.isset(core.status.replay)&&core.status.replay.replaying) return; + if (core.isset(core.status.replay)&&core.status.replay.replaying&&core.status.event.id!='save') return; if (!core.isset(core.status.holdingKeys))core.status.holdingKeys=[]; var isArrow={37:true,38:true,39:true,40:true}[e.keyCode] if(isArrow && !core.status.lockControl){ @@ -31,7 +31,7 @@ actions.prototype.onkeyDown = function (e) { ////// 放开某个键时 ////// actions.prototype.onkeyUp = function(e) { - if (core.isset(core.status.replay)&&core.status.replay.replaying) { + if (core.isset(core.status.replay)&&core.status.replay.replaying&&core.status.event.id!='save') { if (e.keyCode==27) // ESCAPE core.stopReplay(); else if (e.keyCode==90) // Z @@ -42,6 +42,8 @@ actions.prototype.onkeyUp = function(e) { core.triggerReplay(); else if (e.keyCode==65) // A core.rewindReplay(); + else if (e.keyCode==83) + core.saveReplay(); return; } @@ -62,7 +64,7 @@ actions.prototype.onkeyUp = function(e) { ////// 按住某个键时 ////// actions.prototype.pressKey = function (keyCode) { - if (core.isset(core.status.replay)&&core.status.replay.replaying) return; + if (core.isset(core.status.replay)&&core.status.replay.replaying&&core.status.event.id!='save') return; if (keyCode === core.status.holdingKeys.slice(-1)[0]) { this.keyDown(keyCode); window.setTimeout(function(){core.pressKey(keyCode);},30); @@ -71,7 +73,7 @@ actions.prototype.pressKey = function (keyCode) { ////// 根据按下键的code来执行一系列操作 ////// actions.prototype.keyDown = function(keyCode) { - if (core.isset(core.status.replay)&&core.status.replay.replaying) return; + if (core.isset(core.status.replay)&&core.status.replay.replaying&&core.status.event.id!='save') return; if (core.status.lockControl) { // Ctrl跳过对话 if (keyCode==17) { @@ -106,7 +108,7 @@ actions.prototype.keyDown = function(keyCode) { this.keyDownToolbox(keyCode); return; } - if (core.status.event.id=='save' || core.status.event.id=='load') { + if (core.status.event.id=='save' || core.status.event.id=='load' || core.status.event.id=='replayLoad') { this.keyDownSL(keyCode); return; } @@ -138,6 +140,9 @@ actions.prototype.keyDown = function(keyCode) { this.keyDownCursor(keyCode); return; } + if (core.status.event.id=='replay') { + this.keyDownReplay(keyCode); + } return; } if(!core.status.played) { @@ -188,7 +193,7 @@ actions.prototype.keyDown = function(keyCode) { ////// 根据放开键的code来执行一系列操作 ////// actions.prototype.keyUp = function(keyCode, fromReplay) { - if (!fromReplay&&core.isset(core.status.replay)&&core.status.replay.replaying) return; + if (!fromReplay&&core.isset(core.status.replay)&&core.status.replay.replaying&&core.status.event.id!='save') return; if (core.status.lockControl) { core.status.holdingKeys = []; @@ -237,7 +242,7 @@ actions.prototype.keyUp = function(keyCode, fromReplay) { this.keyUpToolbox(keyCode); return; } - if (core.status.event.id=='save' || core.status.event.id=='load') { + if (core.status.event.id=='save' || core.status.event.id=='load' || core.status.event.id=='replayLoad') { this.keyUpSL(keyCode); return; } @@ -269,6 +274,10 @@ actions.prototype.keyUp = function(keyCode, fromReplay) { this.keyUpCursor(keyCode); return; } + if (core.status.event.id=='replay') { + this.keyUpReplay(keyCode); + return; + } return; } @@ -325,19 +334,8 @@ actions.prototype.keyUp = function(keyCode, fromReplay) { core.ui.drawHelp(); break; case 82: // R - if (core.status.heroStop) { - core.ui.drawConfirmBox("确定要回放录像吗?", function () { - core.ui.closePanel(); - var hard=core.status.hard, route=core.clone(core.status.route); - core.resetStatus(core.firstData.hero, hard, core.firstData.floorId, null, core.initStatus.maps); - core.events.setInitData(hard); - core.changeFloor(core.status.floorId, null, core.firstData.hero.loc, null, function() { - core.startReplay(route); - }, true); - }, function () { - core.ui.closePanel(); - }); - } + if (core.status.heroStop) + core.ui.drawReplay(); break; case 33: case 34: // PAGEUP/PAGEDOWN if (core.status.heroStop) { @@ -401,7 +399,7 @@ actions.prototype.keyUp = function(keyCode, fromReplay) { ////// 点击(触摸)事件按下时 ////// actions.prototype.ondown = function (x ,y) { - if (core.isset(core.status.replay)&&core.status.replay.replaying) return; + if (core.isset(core.status.replay)&&core.status.replay.replaying&&core.status.event.id!='save') return; if (!core.status.played || core.status.lockControl) { this.onclick(x, y, []); if (core.timeout.onDownTimeout==null) { @@ -429,7 +427,7 @@ actions.prototype.ondown = function (x ,y) { ////// 当在触摸屏上滑动时 ////// actions.prototype.onmove = function (x ,y) { - if (core.isset(core.status.replay)&&core.status.replay.replaying) return; + if (core.isset(core.status.replay)&&core.status.replay.replaying&&core.status.event.id!='save') return; // if (core.status.holdingPath==0){return;} //core.status.mouseOutCheck =1; var pos={'x':x,'y':y}; @@ -453,7 +451,7 @@ actions.prototype.onmove = function (x ,y) { ////// 当点击(触摸)事件放开时 ////// actions.prototype.onup = function () { - if (core.isset(core.status.replay)&&core.status.replay.replaying) return; + if (core.isset(core.status.replay)&&core.status.replay.replaying&&core.status.event.id!='save') return; clearTimeout(core.timeout.onDownTimeout); core.timeout.onDownTimeout = null; @@ -519,7 +517,7 @@ actions.prototype.getClickLoc = function (x, y) { ////// 具体点击屏幕上(x,y)点时,执行的操作 ////// actions.prototype.onclick = function (x, y, stepPostfix) { - if (core.isset(core.status.replay)&&core.status.replay.replaying) return; + if (core.isset(core.status.replay)&&core.status.replay.replaying&&core.status.event.id!='save') return; // console.log("Click: (" + x + "," + y + ")"); stepPostfix=stepPostfix||[]; @@ -606,7 +604,7 @@ actions.prototype.onclick = function (x, y, stepPostfix) { } // 存读档 - if (core.status.event.id == 'save' || core.status.event.id == 'load') { + if (core.status.event.id == 'save' || core.status.event.id == 'load' || core.status.event.id=='replayLoad') { this.clickSL(x,y); return; } @@ -664,11 +662,16 @@ actions.prototype.onclick = function (x, y, stepPostfix) { return; } + if (core.status.event.id == 'replay') { + this.clickReplay(x,y); + return; + } + } ////// 滑动鼠标滚轮时的操作 ////// actions.prototype.onmousewheel = function (direct) { - if (core.isset(core.status.replay)&&core.status.replay.replaying) return; + if (core.isset(core.status.replay)&&core.status.replay.replaying&&core.status.event.id!='save') return; // 向下滚动是 -1 ,向上是 1 // 楼层飞行器 @@ -694,8 +697,8 @@ actions.prototype.onmousewheel = function (direct) { // 浏览地图 if (core.status.lockControl && core.status.event.id == 'viewMaps') { - if (direct==1) core.ui.drawMaps(core.status.event.data+1); - if (direct==-1) core.ui.drawMaps(core.status.event.data-1); + if (direct==1) this.clickViewMaps(6,2); + if (direct==-1) this.clickViewMaps(6,10); return; } } @@ -927,11 +930,21 @@ actions.prototype.keyUpFly = function (keycode) { ////// 查看地图界面时的点击操作 ////// actions.prototype.clickViewMaps = function (x,y) { + var now = core.floorIds.indexOf(core.status.floorId); + var nextId = core.status.event.data; if(y<=4) { - core.ui.drawMaps(core.status.event.data+1); + nextId++; + while (nextId=8) { - core.ui.drawMaps(core.status.event.data-1); + nextId--; + while (nextId>=0 && nextId!=now && core.floors[core.floorIds[nextId]].cannotViewMap) + nextId--; + if (nextId>=0) + core.ui.drawMaps(nextId); } else { core.clearMap('data', 0, 0, 416, 416); @@ -942,8 +955,12 @@ actions.prototype.clickViewMaps = function (x,y) { ////// 查看地图界面时,按下某个键的操作 ////// actions.prototype.keyDownViewMaps = function (keycode) { - if (keycode==37 || keycode==38 || keycode==33) core.ui.drawMaps(core.status.event.data+1); - else if (keycode==39 || keycode==40 || keycode==34) core.ui.drawMaps(core.status.event.data-1); + if (keycode==37 || keycode==38 || keycode==33) { + this.clickViewMaps(6,2); + } + else if (keycode==39 || keycode==40 || keycode==34) { + this.clickViewMaps(6,10); + } return; } @@ -1888,6 +1905,68 @@ actions.prototype.keyUpStorageRemove = function (keycode) { } } +////// 回放选择界面时的点击操作 ////// +actions.prototype.clickReplay = function (x, y) { + if (x<5 || x>7) return; + var choices = core.status.event.ui.choices; + + var topIndex = 6 - parseInt((choices.length - 1) / 2); + + if (y>=topIndex && y=1 && x<=11) { diff --git a/libs/control.js b/libs/control.js index dfbc18d5..900441ad 100644 --- a/libs/control.js +++ b/libs/control.js @@ -291,10 +291,6 @@ control.prototype.restart = function() { } - - - - /////////////////////// 寻路算法 & 人物行走控制 /////////////////////// ////// 清除自动寻路路线 ////// @@ -357,7 +353,7 @@ control.prototype.setAutomaticRoute = function (destX, destY, stepPostfix) { core.clearMap('hero', 0, 0, 416, 416); core.setHeroLoc('x', destX); core.setHeroLoc('y', destY); - core.drawHero(core.getHeroLoc('direction'), core.getHeroLoc('x'), core.getHeroLoc('y'), 'stop'); + core.drawHero(); core.status.route.push("move:"+destX+":"+destY); } } @@ -594,9 +590,7 @@ control.prototype.setHeroMoveInterval = function (direction, x, y, callback) { core.setHeroLoc('y', y+scan[direction].y); core.moveOneStep(); core.clearMap('hero', 0, 0, 416, 416); - core.drawHero(direction, core.getHeroLoc('x'), core.getHeroLoc('y'), 'stop'); - //if (core.status.heroStop) - // core.drawHero(direction, core.getHeroLoc('x'), core.getHeroLoc('y'), 'stop'); + core.drawHero(direction); clearInterval(core.interval.heroMoveInterval); core.status.heroMoving = 0; if (core.isset(callback)) callback(); @@ -624,7 +618,7 @@ control.prototype.moveAction = function (callback) { core.status.automaticRoute.moveStepBeforeStop = []; if (canMove) // 非箭头:触发 core.trigger(x + scan[direction].x, y + scan[direction].y); - core.drawHero(direction, x, y, 'stop'); + core.drawHero(direction, x, y); if (core.status.automaticRoute.moveStepBeforeStop.length==0) { core.clearContinueAutomaticRoute(); @@ -652,7 +646,7 @@ control.prototype.moveAction = function (callback) { } } else if (core.status.heroStop) { - core.drawHero(core.getHeroLoc('direction'), core.getHeroLoc('x'), core.getHeroLoc('y'), 'stop'); + core.drawHero(); } if (core.status.event.id!='ski') core.status.route.push(direction); @@ -669,7 +663,7 @@ control.prototype.turnHero = function() { else if (core.status.hero.loc.direction == 'right') core.status.hero.loc.direction = 'down'; else if (core.status.hero.loc.direction == 'down') core.status.hero.loc.direction = 'left'; else if (core.status.hero.loc.direction == 'left') core.status.hero.loc.direction = 'up'; - core.drawHero(core.status.hero.loc.direction, core.status.hero.loc.x, core.status.hero.loc.y, 'stop', 0, 0); + core.drawHero(); core.canvas.ui.clearRect(0, 0, 416, 416); core.status.route.push("turn"); } @@ -742,7 +736,7 @@ control.prototype.eventMoveHero = function(steps, time, callback) { var x=core.getHeroLoc('x'), y=core.getHeroLoc('y'); if (moveSteps.length==0) { clearInterval(animate); - core.drawHero(core.getHeroLoc('direction'), x, y, 'stop'); + core.drawHero(null, x, y); core.status.replay.animate=false; if (core.isset(callback)) callback(); } @@ -792,7 +786,7 @@ control.prototype.waitHeroToStop = function(callback) { core.status.automaticRoute.moveDirectly = false; setTimeout(function(){ core.status.replay.animate=false; - core.drawHero(core.getHeroLoc('direction'), core.getHeroLoc('x'), core.getHeroLoc('y'), 'stop'); + core.drawHero(); callback(); }, 30); } @@ -808,10 +802,13 @@ control.prototype.drawHero = function (direction, x, y, status, offsetX, offsetY offsetX = offsetX || 0; offsetY = offsetY || 0; var dx=offsetX==0?0:offsetX/Math.abs(offsetX), dy=offsetY==0?0:offsetY/Math.abs(offsetY); + if (!core.isset(x)) x = core.getHeroLoc('x'); + if (!core.isset(y)) y = core.getHeroLoc('y'); core.clearAutomaticRouteNode(x+dx, y+dy); - var heroIcon = core.material.icons.hero[direction]; x = x * 32; y = y * 32; + status = status || 'stop'; + var heroIcon = core.material.icons.hero[direction || core.getHeroLoc('direction')]; core.canvas.hero.clearRect(x - 32, y - 32, 96, 96); var height=core.material.icons.hero.height; core.canvas.hero.drawImage(core.material.images.hero, heroIcon[status] * 32, heroIcon.loc * height, 32, height, x + offsetX, y + offsetY + 32-height, 32, height); @@ -869,11 +866,16 @@ control.prototype.updateCheckBlock = function() { for (var n=0;n12 || ny<0 || ny>12) continue; var id=core.status.checkBlock.map[13*nx+ny]; if (core.isset(id)) { - var enemy = core.enemys.getEnemys(id); + var enemy = core.material.enemys[id]; if (core.isset(enemy) && core.enemys.hasSpecial(enemy.special, 18)) { snipe.push({'direction': direction, 'x': nx, 'y': ny}); } @@ -982,6 +990,9 @@ control.prototype.checkBlock = function () { if (core.status.checkBlock.betweenAttack[13*x+y] && damage>0) { core.drawTip('受到夹击,生命变成一半'); } + else if (core.status.checkBlock.map[13*x+y]=='lavaNet') { + core.drawTip('受到血网伤害'+damage+'点'); + } // 阻击 else if (snipe.length>0 && damage>0) { core.drawTip('受到阻击伤害'+damage+'点'); @@ -1389,12 +1400,14 @@ control.prototype.startReplay = function (list) { ////// 更改播放状态 ////// control.prototype.triggerReplay = function () { + if (core.status.event.id=='save') return; if (core.status.replay.pausing) this.resumeReplay(); else this.pauseReplay(); } ////// 暂停播放 ////// control.prototype.pauseReplay = function () { + if (core.status.event.id=='save') return; if (!core.status.replay.replaying) return; core.status.replay.pausing = true; core.updateStatusBar(); @@ -1403,6 +1416,7 @@ control.prototype.pauseReplay = function () { ////// 恢复播放 ////// control.prototype.resumeReplay = function () { + if (core.status.event.id=='save') return; if (!core.status.replay.replaying) return; core.status.replay.pausing = false; core.updateStatusBar(); @@ -1412,6 +1426,7 @@ control.prototype.resumeReplay = function () { ////// 加速播放 ////// control.prototype.speedUpReplay = function () { + if (core.status.event.id=='save') return; if (!core.status.replay.replaying) return; core.status.replay.speed = parseInt(10*core.status.replay.speed + 1)/10; if (core.status.replay.speed>3.0) core.status.replay.speed=3.0; @@ -1420,6 +1435,7 @@ control.prototype.speedUpReplay = function () { ////// 减速播放 ////// control.prototype.speedDownReplay = function () { + if (core.status.event.id=='save') return; if (!core.status.replay.replaying) return; core.status.replay.speed = parseInt(10*core.status.replay.speed - 1)/10; if (core.status.replay.speed<0.3) core.status.replay.speed=0.3; @@ -1428,6 +1444,7 @@ control.prototype.speedDownReplay = function () { ////// 停止播放 ////// control.prototype.stopReplay = function () { + if (core.status.event.id=='save') return; if (!core.status.replay.replaying) return; core.status.replay.toReplay = []; core.status.replay.totalList = []; @@ -1442,6 +1459,7 @@ control.prototype.stopReplay = function () { ////// 回退 ////// control.prototype.rewindReplay = function () { + if (core.status.event.id=='save') return; if (!core.status.replay.replaying) return; if (!core.status.replay.pausing) { core.drawTip("请先暂停录像"); @@ -1472,7 +1490,26 @@ control.prototype.rewindReplay = function () { core.updateStatusBar(); core.drawTip("成功回退到上一个节点"); }) +} +////// 回放时存档 ////// +control.prototype.saveReplay = function () { + if (!core.status.replay.replaying) return; + if (!core.status.replay.pausing) { + core.drawTip("请先暂停录像"); + return; + } + if (core.status.replay.animate || core.isset(core.status.event.id)) { + core.drawTip("请等待当前事件的处理结束"); + return; + } + + core.lockControl(); + core.status.event.id='save'; + var saveIndex = core.status.saveIndex; + var page=parseInt((saveIndex-1)/5), offset=saveIndex-5*page; + + core.ui.drawSLPanel(10*page+offset); } ////// 回放 ////// @@ -1601,7 +1638,7 @@ control.prototype.replay = function () { core.clearMap('hero', 0, 0, 416, 416); core.setHeroLoc('x', x); core.setHeroLoc('y', y); - core.drawHero(core.getHeroLoc('direction'), core.getHeroLoc('x'), core.getHeroLoc('y'), 'stop'); + core.drawHero(); core.status.route.push("move:"+x+":"+y); core.replay(); return; @@ -1800,6 +1837,30 @@ control.prototype.doSL = function (id, type) { }); return; } + else if (type == 'replayLoad') { + var data = core.getLocalStorage(id=='autoSave'?id:"save"+id, null); + if (!core.isset(data)) { + core.drawTip("无效的存档"); + return; + } + if (data.version != core.firstData.version) { + core.drawTip("存档版本不匹配"); + return; + } + if (data.hard != core.status.hard) { + core.drawTip("游戏难度不匹配!"); + return; + } + var route = core.subarray(core.status.route, core.decodeRoute(data.route)); + if (!core.isset(route)) { + core.drawTip("无法从此存档回放录像"); + return; + } + core.loadData(data, function () { + core.startReplay(route); + core.drawTip("回退到存档节点"); + }); + } } ////// 同步存档到服务器 ////// @@ -1955,6 +2016,13 @@ control.prototype.loadData = function (data, callback) { } } + // load icons + var icon = core.getFlag("heroIcon", "hero.png"); + if (core.isset(core.material.images.images[icon])) { + core.material.images.hero.src = core.material.images.images[icon].src; + core.material.icons.hero.height = core.material.images.images[icon].height/4; + } + core.events.afterLoadData(data); core.changeFloor(data.floorId, null, data.hero.loc, 0, function() { @@ -2195,7 +2263,8 @@ control.prototype.updateStatusBar = function () { core.statusBar.image.load.src = core.statusBar.icons.speedUp.src; core.statusBar.image.load.style.opacity = 1; - core.statusBar.image.settings.style.opacity = 0; + core.statusBar.image.settings.src = core.statusBar.icons.save.src; + core.statusBar.image.settings.style.opacity = 1; } else { diff --git a/libs/core.js b/libs/core.js index b78e1087..a1fe38db 100644 --- a/libs/core.js +++ b/libs/core.js @@ -923,6 +923,11 @@ core.prototype.stopReplay = function () { core.control.stopReplay(); } +////// 回放时存档 ////// +core.prototype.saveReplay = function () { + core.control.saveReplay(); +} + ////// 回放 ////// core.prototype.replay = function () { core.control.replay(); @@ -1067,6 +1072,11 @@ core.prototype.isset = function (val) { return core.utils.isset(val); } +////// 获得子数组 ////// +core.prototype.subarray = function (a, b) { + return core.utils.subarray(a, b); +} + ////// 读取一个本地文件内容 ////// core.prototype.readFile = function (success, error, readType) { core.utils.readFile(success, error, readType); diff --git a/libs/enemys.js b/libs/enemys.js index dfc4ee21..e72ea82f 100644 --- a/libs/enemys.js +++ b/libs/enemys.js @@ -132,57 +132,72 @@ enemys.prototype.getExtraDamage = function (monster) { return extra_damage; } +////// 接下来若干个临界值计算 ///// +enemys.prototype.nextCriticals = function (monsterId, number) { + + number = number||1; + + var monster = core.material.enemys[monsterId]; + // 坚固、模仿怪物没有临界! + if (this.hasSpecial(monster.special, 3) || this.hasSpecial(monster.special, 10)) return []; + + var info = this.getDamageInfo(monster, core.status.hero.hp, core.status.hero.atk, core.status.hero.def, core.status.hero.mdef); + + if (info == null) { + if (core.status.hero.atk<=monster.def) { + return [(monster.def+1-core.status.hero.atk)+":?"]; + } + return []; + } + if (info.damage <= 0) return []; + + var mon_hp = info.mon_hp, hero_atk = core.status.hero.atk, mon_def = monster.def, turn = info.turn; + + if (turn<=1) return []; + + var list = [], pre = null; + + for (var t = turn-1;t>=1;t--) { + var nextAtk = Math.ceil(mon_hp/t) + mon_def; + if (nextAtk<=hero_atk) break; + if (nextAtk!=pre) { + var nextInfo = this.getDamageInfo(monster, core.status.hero.hp, nextAtk, core.status.hero.def, core.status.hero.mdef); + if (nextInfo==null) break; + list.push((nextAtk-hero_atk)+":"+(info.damage-nextInfo.damage)); + if (nextInfo.damage<=0) break; + pre = nextAtk; + } + if (list.length>=number) + break; + } + return list; +} + ////// 临界值计算 ////// enemys.prototype.getCritical = function (monsterId) { var monster = core.material.enemys[monsterId]; // 坚固、模仿怪物没有临界! if (this.hasSpecial(monster.special, 3) || this.hasSpecial(monster.special, 10)) return "???"; - if (false) { // 采用回合方式 - - var last = this.calDamage(monster, core.status.hero.hp, core.status.hero.atk, core.status.hero.def, core.status.hero.mdef); - - if (last == null) { - if (core.status.hero.atk<=monster.def) - return monster.def+1-core.status.hero.atk; - - return '???'; - } - - if (last <= 0) return 0; - - for (var i = core.status.hero.atk + 1; i <= monster.hp + monster.def; i++) { - var damage = this.calDamage(monster, core.status.hero.hp, i, core.status.hero.def, core.status.hero.mdef); - if (damage == null) return '???'; - if (damage < last) - return core.formatBigNumber(i - core.status.hero.atk); - last = damage; - } - return 0; + var info = this.getDamageInfo(monster, core.status.hero.hp, core.status.hero.atk, core.status.hero.def, core.status.hero.mdef); + if (info == null) { + if (core.status.hero.atk<=monster.def) + return monster.def+1-core.status.hero.atk; + return '???'; } - else { + if (info.damage <= 0) return 0; - var info = this.getDamageInfo(monster, core.status.hero.hp, core.status.hero.atk, core.status.hero.def, core.status.hero.mdef); + var mon_hp = info.mon_hp, hero_atk = core.status.hero.atk, mon_def = monster.def, turn = info.turn; - if (info == null) { - if (core.status.hero.atk<=monster.def) - return monster.def+1-core.status.hero.atk; - return '???'; - } - if (info.damage <= 0) return 0; + // turn 是勇士攻击次数 + if (turn<=1) return 0; // 攻杀 - var mon_hp = info.mon_hp, hero_atk = core.status.hero.atk, mon_def = monster.def, turn = info.turn; + // 每回合最小伤害 = ⎡怪物生命/勇士攻击次数⎤ + var nextAtk = Math.ceil(mon_hp/(turn-1)) + mon_def; - // turn 是勇士攻击次数 - if (turn<=1) return 0; // 攻杀 - - // 每回合最小伤害 = ⎡怪物生命/勇士攻击次数⎤ - var nextAtk = Math.ceil(mon_hp/(turn-1)) + mon_def; - - if (nextAtk <= hero_atk) return 0; - return nextAtk - hero_atk; - } + if (nextAtk <= hero_atk) return 0; + return nextAtk - hero_atk; } @@ -350,6 +365,12 @@ enemys.prototype.getCurrentEnemys = function (floorId) { if (a.damage == b.damage) { return a.money - b.money; } + if (a.damage == null) { + return 1; + } + if (b.damage == null) { + return -1; + } return a.damage - b.damage; }); return enemys; diff --git a/libs/events.js b/libs/events.js index f1e26f9c..43fdfd49 100644 --- a/libs/events.js +++ b/libs/events.js @@ -125,8 +125,7 @@ events.prototype.gameOver = function (ending, fromReplay) { // 清空图片和天气 core.clearMap('animate', 0, 0, 416, 416); - while (core.dom.gif2.firstChild) - core.dom.gif2.removeChild(core.dom.gif2.firstChild); + core.dom.gif2.innerHTML = ""; core.clearMap('weather', 0, 0, 416, 416) core.animateFrame.weather.type = null; core.animateFrame.weather.level = 0; @@ -366,7 +365,7 @@ events.prototype.doAction = function() { } if (floorId==core.status.floorId) { core.drawMap(floorId); - core.drawHero(core.getHeroLoc('direction'), core.getHeroLoc('x'), core.getHeroLoc('y'), 'stop'); + core.drawHero(); core.updateStatusBar(); } } @@ -419,7 +418,7 @@ events.prototype.doAction = function() { core.setHeroLoc('y', data.loc[1]); } if (core.isset(data.direction)) core.setHeroLoc('direction', data.direction); - core.drawHero(core.getHeroLoc('direction'), core.getHeroLoc('x'), core.getHeroLoc('y'), 'stop'); + core.drawHero(); this.doAction(); break; case "showImage": // 显示图片 @@ -454,8 +453,7 @@ events.prototype.doAction = function() { core.dom.gif2.appendChild(gif); } else { - while (core.dom.gif2.firstChild) - core.dom.gif2.removeChild(core.dom.gif2.firstChild); + core.dom.gif2.innerHTML = ""; } this.doAction(); break; @@ -569,6 +567,18 @@ events.prototype.doAction = function() { this.doAction(); } break; + case "setHeroIcon": + { + var name = "hero.png"; + if (core.isset(core.material.images.images[data.name]) && core.material.images.images[data.name].width==128) + name = data.name; + core.setFlag("heroIcon", name); + core.material.images.hero.src = core.material.images.images[name].src; + core.material.icons.hero.height = core.material.images.images[name].height/4; + core.drawHero(); + this.doAction(); + break; + } case "input": { var value; @@ -884,12 +894,19 @@ events.prototype.changeFloor = function (floorId, stair, heroLoc, time, callback heroLoc = core.status.hero.loc; if (core.isset(stair)) { if (!core.isset(heroLoc)) heroLoc={}; - var blocks = core.status.maps[floorId].blocks; - for (var i in blocks) { - if (core.isset(blocks[i].event) && !(core.isset(blocks[i].enable) && !blocks[i].enable) && blocks[i].event.id === stair) { - heroLoc.x = blocks[i].x; - heroLoc.y = blocks[i].y; - break; + + if (core.isset(core.floors[floorId][stair])) { + heroLoc.x = core.floors[floorId][stair][0]; + heroLoc.y = core.floors[floorId][stair][1]; + } + else { + var blocks = core.status.maps[floorId].blocks; + for (var i in blocks) { + if (core.isset(blocks[i].event) && !(core.isset(blocks[i].enable) && !blocks[i].enable) && blocks[i].event.id === stair) { + heroLoc.x = blocks[i].x; + heroLoc.y = blocks[i].y; + break; + } } } if (!core.isset(heroLoc.x)) { @@ -947,8 +964,7 @@ events.prototype.changeFloor = function (floorId, stair, heroLoc, time, callback else core.setWeather(); // 清除gif - while (core.dom.gif.firstChild) - core.dom.gif.removeChild(core.dom.gif.firstChild); + core.dom.gif.innerHTML = ""; // 检查重生 if (!core.isset(fromLoad)) { @@ -965,7 +981,7 @@ events.prototype.changeFloor = function (floorId, stair, heroLoc, time, callback core.setHeroLoc('direction', heroLoc.direction); core.setHeroLoc('x', heroLoc.x); core.setHeroLoc('y', heroLoc.y); - core.drawHero(core.getHeroLoc('direction'), core.getHeroLoc('x'), core.getHeroLoc('y'), 'stop'); + core.drawHero(); core.updateStatusBar(); var changed = function () { @@ -1162,6 +1178,8 @@ events.prototype.passNet = function (data) { // 有鞋子 if (core.hasItem('shoes')) return; if (data.event.id=='lavaNet') { // 血网 + // 在checkBlock中进行处理 + /* core.status.hero.hp -= core.values.lavaDamage; if (core.status.hero.hp<=0) { core.status.hero.hp=0; @@ -1169,7 +1187,8 @@ events.prototype.passNet = function (data) { core.events.lose(); return; } - core.drawTip('经过血网,生命-'+core.values.lavaDamage); + */ + // core.drawTip('经过血网,生命-'+core.values.lavaDamage); } if (data.event.id=='poisonNet') { // 毒网 if (core.hasFlag('poison')) return; diff --git a/libs/loader.js b/libs/loader.js index d5271bb2..969f4f54 100644 --- a/libs/loader.js +++ b/libs/loader.js @@ -30,7 +30,12 @@ loader.prototype.load = function (callback) { core.loader.loadImages(core.materials, core.material.images, function () { // 加载png图片 core.material.images.images = {}; - core.loader.loadImages(core.images, core.material.images.images, function () { + + var images = core.clone(core.images); + if (images.indexOf("hero.png")<0) + images.push("hero.png"); + + core.loader.loadImages(images, core.material.images.images, function () { // 加载autotile core.material.images.autotile = {}; core.loader.loadImages(Object.keys(core.material.icons.autotile), core.material.images.autotile, function () { diff --git a/libs/maps.js b/libs/maps.js index 4b99a178..fa80da9f 100644 --- a/libs/maps.js +++ b/libs/maps.js @@ -331,8 +331,7 @@ maps.prototype.drawMap = function (mapName, callback) { if (!t[3]) { core.canvas.bg.drawImage(image, dx * ratio, dy * ratio, Math.min(size - dx * ratio, ratio * image.width), Math.min(size - dy * ratio, ratio * image.height)); if (/.*\.gif/i.test(p)) { - while (core.dom.gif.firstChild) - core.dom.gif.removeChild(core.dom.gif.firstChild); + core.dom.gif.innerHTML = ""; var gif = new Image(); gif.src = core.material.images.images[p].src; gif.style.position = 'absolute'; @@ -893,7 +892,7 @@ maps.prototype.resetMap = function() { var floorId = core.status.floorId; core.status.maps[floorId] = this.loadFloor(floorId); this.drawMap(floorId, function() { - core.drawHero(core.getHeroLoc('direction'), core.getHeroLoc('x'), core.getHeroLoc('y'), 'stop'); + core.drawHero(); core.updateStatusBar(); }) } \ No newline at end of file diff --git a/libs/ui.js b/libs/ui.js index 89802697..84ea2d28 100644 --- a/libs/ui.js +++ b/libs/ui.js @@ -20,8 +20,7 @@ ui.prototype.clearMap = function (map, x, y, width, height) { for (var m in core.canvas) { core.canvas[m].clearRect(0, 0, 416, 416); } - while (core.dom.gif.firstChild) - core.dom.gif.removeChild(core.dom.gif.firstChild); + core.dom.gif.innerHTML = ""; } else { core.canvas[map].clearRect(x||0, y||0, width||416, height||416); @@ -1132,6 +1131,14 @@ ui.prototype.drawStorageRemove = function () { ]); } +ui.prototype.drawReplay = function () { + core.lockControl(); + core.status.event.id = 'replay'; + this.drawChoices(null, [ + "从头回放录像", "从存档开始回放", "返回游戏" + ]); +} + ////// 绘制分页 ////// ui.prototype.drawPagination = function (page, totalPage) { @@ -1332,6 +1339,10 @@ ui.prototype.drawBookDetail = function (index) { if (hints.length==0) hints.push("该怪物无特殊属性。"); + + hints.push(""); + hints.push("临界表:"+JSON.stringify(core.enemys.nextCriticals(enemyId,10))) + var content=hints.join("\n"); core.status.event.id = 'book-detail'; @@ -1577,7 +1588,7 @@ ui.prototype.drawSLPanel = function(index) { var strokeColor = '#FFD700'; if (core.status.event.selection) strokeColor = '#FF6A6A'; - var name=core.status.event.id=='save'?"存档":"读档"; + var name=core.status.event.id=='save'?"存档":core.status.event.id=='load'?"读档":core.status.event.id=='replayLoad'?"回放":""; for (var i=0;i<6;i++) { var id=5*page+i; var data=core.getLocalStorage(i==0?"autoSave":"save"+id, null); @@ -1585,7 +1596,7 @@ ui.prototype.drawSLPanel = function(index) { core.fillText('ui', i==0?"自动存档":name+id, (2*i+1)*u, 35, '#FFFFFF', "bold 17px Verdana"); core.strokeRect('ui', (2*i+1)*u-size/2, 50, size, size, i==offset?strokeColor:'#FFFFFF', i==offset?6:2); if (core.isset(data) && core.isset(data.floorId)) { - this.drawThumbnail(data.floorId, 'ui', core.maps.load(data.maps, data.floorId).blocks, (2*i+1)*u-size/2, 50, size, data.hero.loc); + this.drawThumbnail(data.floorId, 'ui', core.maps.load(data.maps, data.floorId).blocks, (2*i+1)*u-size/2, 50, size, data.hero.loc, data.hero.flags.heroIcon||"hero.png"); core.fillText('ui', core.formatDate(new Date(data.time)), (2*i+1)*u, 65+size, '#FFFFFF', '10px Verdana'); } else { @@ -1597,7 +1608,7 @@ ui.prototype.drawSLPanel = function(index) { core.fillText('ui', name+id, (2*i-5)*u, 230, '#FFFFFF', "bold 17px Verdana"); core.strokeRect('ui', (2*i-5)*u-size/2, 245, size, size, i==offset?strokeColor:'#FFFFFF', i==offset?6:2); if (core.isset(data) && core.isset(data.floorId)) { - this.drawThumbnail(data.floorId, 'ui', core.maps.load(data.maps, data.floorId).blocks, (2*i-5)*u-size/2, 245, size, data.hero.loc); + this.drawThumbnail(data.floorId, 'ui', core.maps.load(data.maps, data.floorId).blocks, (2*i-5)*u-size/2, 245, size, data.hero.loc, data.hero.flags.heroIcon||"hero.png"); core.fillText('ui', core.formatDate(new Date(data.time)), (2*i-5)*u, 260+size, '#FFFFFF', '10px Verdana'); } else { @@ -1615,7 +1626,7 @@ ui.prototype.drawSLPanel = function(index) { } ////// 绘制一个缩略图 ////// -ui.prototype.drawThumbnail = function(floorId, canvas, blocks, x, y, size, heroLoc) { +ui.prototype.drawThumbnail = function(floorId, canvas, blocks, x, y, size, heroLoc, heroIcon) { core.clearMap(canvas, x, y, size, size); var groundId = core.floors[floorId].defaultGround || "ground"; var blockIcon = core.material.icons.terrains[groundId]; @@ -1664,10 +1675,12 @@ ui.prototype.drawThumbnail = function(floorId, canvas, blocks, x, y, size, heroL } if (core.isset(heroLoc)) { - var heroIcon = core.material.icons.hero[heroLoc.direction]; - var height = core.material.icons.hero.height; + if (!core.isset(core.material.images.images[heroIcon])) + heroIcon = "hero.png"; + var icon = core.material.icons.hero[heroLoc.direction]; + var height = core.material.images.images[heroIcon].height/4; var realHeight = persize*height/32; - core.canvas[canvas].drawImage(core.material.images.hero, heroIcon.stop * 32, heroIcon.loc * height, 32, height, x+persize*heroLoc.x, y+persize*heroLoc.y+persize-realHeight, persize, realHeight); + core.canvas[canvas].drawImage(core.material.images.images[heroIcon], icon.stop * 32, icon.loc * height, 32, height, x+persize*heroLoc.x, y+persize*heroLoc.y+persize-realHeight, persize, realHeight); } images.forEach(function (t) { diff --git a/libs/utils.js b/libs/utils.js index bfa4cae6..9d11609b 100644 --- a/libs/utils.js +++ b/libs/utils.js @@ -300,6 +300,17 @@ utils.prototype.isset = function (val) { return true } +////// 获得子数组 ////// +utils.prototype.subarray = function (a, b) { + if (!core.isset(a) || !core.isset(b) || !(a instanceof Array) || !(b instanceof Array) || a.length0) { + if (na.shift() != nb.shift()) return null; + } + return na; +} + ////// 读取一个本地文件内容 ////// utils.prototype.readFile = function (success, error, readType) { diff --git a/main.js b/main.js index e83fb164..6cd095c0 100644 --- a/main.js +++ b/main.js @@ -2,7 +2,7 @@ function main() { //------------------------ 用户修改内容 ------------------------// - this.version = "2.1"; // 游戏版本号;如果更改了游戏内容建议修改此version以免造成缓存问题。 + this.version = "2.1.1"; // 游戏版本号;如果更改了游戏内容建议修改此version以免造成缓存问题。 this.useCompress = false; // 是否使用压缩文件 // 当你即将发布你的塔时,请使用“JS代码压缩工具”将所有js代码进行压缩,然后将这里的useCompress改为true。 @@ -433,6 +433,12 @@ main.statusBar.image.load.onclick = function () { ////// 点击状态栏中的系统菜单时 ////// main.statusBar.image.settings.onclick = function () { + + if (core.isset(core.status.replay) && core.status.replay.replaying) { + core.saveReplay(); + return; + } + if (main.core.isPlaying()) main.core.openSettings(true); } diff --git a/project/data.js b/project/data.js index 1d14035d..ac0361db 100644 --- a/project/data.js +++ b/project/data.js @@ -23,7 +23,7 @@ data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d = "firstData" : { "title": "魔塔样板", "name": "template", - "version": "Ver 2.1", + "version": "Ver 2.1.1", "floorId": "sample0", "hero": { "name": "阳光", diff --git a/project/floors/MT0.js b/project/floors/MT0.js index 1d9f492e..bb215c0f 100644 --- a/project/floors/MT0.js +++ b/project/floors/MT0.js @@ -1,56 +1,35 @@ -main.floors.MT0 = +main.floors.MT0= { - "floorId": "MT0", // 这里需要改楼层名,请和文件名及下面的floorId保持完全一致 - // 楼层唯一标识符仅能由字母、数字、下划线组成,且不能由数字开头 - // 推荐用法:第20层就用MT20,第38层就用MT38,地下6层就用MT_6(用下划线代替负号),隐藏3层用MT3h(h表示隐藏),等等 - // 楼层唯一标识符,需要和名字完全一致 - "title": "主塔 0 层", // 楼层中文名 - "name": "0", // 显示在状态栏中的层数 - "canFlyTo": true, // 该楼能否被楼传器飞到(不能的话在该楼也不允许使用楼传器) - "canUseQuickShop": true, // 该层是否允许使用快捷商店 - "defaultGround": "ground", // 默认地面的图块ID(terrains中) - "images": [], // 该层默认显示的所有图片;详细用法请查看文档“自定义素材”中的说明。 - // "color": [0,0,0,0.3], // 该层的默认画面色调。本项可不写(代表无色调),如果写需要是一个RGBA数组。 - // "weather": ["snow",5], // 该层的默认天气。本项可忽略表示晴天,如果写则第一项为"rain"或"snow"代表雨雪,第二项为1-10之间的数代表强度。 - // "bgm": "bgm.mp3", // 到达该层后默认播放的BGM。本项可忽略。 - "item_ratio": 1, // 该层的宝石/血瓶倍率 - "map": [ // 地图数据,需要是13x13,建议使用地图生成器来生成 - [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - ], - "firstArrive": [ // 第一次到该楼层触发的事件 - - ], - "events": { // 该楼的所有可能事件列表 - - }, - "changeFloor": { // 楼层转换事件;该事件不能和上面的events有冲突(同位置点),否则会被覆盖 - - }, - "afterBattle": { // 战斗后可能触发的事件列表 - - }, - "afterGetItem": { // 获得道具后可能触发的事件列表 - - }, - "afterOpenDoor": { // 开完门后可能触发的事件列表 - - }, - "cannotMove": { // 每个图块不可通行的方向 - // 可以在这里定义每个点不能前往哪个方向,例如悬崖边不能跳下去 - // "x,y": ["up", "left"], // (x,y)点不能往上和左走 - - }, -} - +"floorId": "MT0", +"title": "主塔 0 层", +"name": "0", +"canFlyTo": true, +"canUseQuickShop": true, +"cannotViewMap": false, +"defaultGround": "ground", +"images": [], +"item_ratio": 1, +"map": [ + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] +], +"firstArrive": [], +"events": {}, +"changeFloor": {}, +"afterBattle": {}, +"afterGetItem": {}, +"afterOpenDoor": {}, +"cannotMove": {}, +"upFloor": null, +} \ No newline at end of file diff --git a/project/items.js b/project/items.js index 6f7d33d1..3a7660ce 100644 --- a/project/items.js +++ b/project/items.js @@ -117,14 +117,14 @@ items_296f5d02_12fd_4166_a7c1_b5e830c9ee3a = "useItemEffect": { "book": "core.ui.drawBook(0);", "fly": "core.ui.drawFly(core.status.hero.flyRange.indexOf(core.status.floorId));", - "earthquake": "core.removeBlockByIds(core.status.floorId, core.status.event.data);\ncore.drawMap(core.status.floorId, function () {\n core.drawHero(core.getHeroLoc('direction'), core.getHeroLoc('x'), core.getHeroLoc('y'), 'stop');\n core.updateFg();\n core.drawTip(core.material.items[itemId].name + '使用成功');\n});", - "pickaxe": "core.removeBlockByIds(core.status.floorId, core.status.event.data);\ncore.drawMap(core.status.floorId, function () {\n core.drawHero(core.getHeroLoc('direction'), core.getHeroLoc('x'), core.getHeroLoc('y'), 'stop');\n core.updateFg();\n core.drawTip(core.material.items[itemId].name + '使用成功');\n});", - "icePickaxe": "core.removeBlockByIds(core.status.floorId, core.status.event.data);\ncore.drawMap(core.status.floorId, function () {\n core.drawHero(core.getHeroLoc('direction'), core.getHeroLoc('x'), core.getHeroLoc('y'), 'stop');\n core.updateFg();\n core.drawTip(core.material.items[itemId].name + '使用成功');\n});", - "snow": "core.removeBlockByIds(core.status.floorId, core.status.event.data);\ncore.drawMap(core.status.floorId, function () {\n core.drawHero(core.getHeroLoc('direction'), core.getHeroLoc('x'), core.getHeroLoc('y'), 'stop');\n core.updateFg();\n core.drawTip(core.material.items[itemId].name + '使用成功');\n});", - "bigKey": "core.removeBlockByIds(core.status.floorId, core.status.event.data);\ncore.drawMap(core.status.floorId, function () {\n core.drawHero(core.getHeroLoc('direction'), core.getHeroLoc('x'), core.getHeroLoc('y'), 'stop');\n core.updateFg();\n core.drawTip(core.material.items[itemId].name + '使用成功');\n});", - "bomb": "core.removeBlockByIds(core.status.floorId, core.status.event.data);\ncore.drawMap(core.status.floorId, function () {\n core.drawHero(core.getHeroLoc('direction'), core.getHeroLoc('x'), core.getHeroLoc('y'), 'stop');\n core.updateFg();\n core.drawTip(core.material.items[itemId].name + '使用成功');\n core.events.afterUseBomb();\n});", - "hammer": "core.removeBlockByIds(core.status.floorId, core.status.event.data);\ncore.drawMap(core.status.floorId, function () {\n core.drawHero(core.getHeroLoc('direction'), core.getHeroLoc('x'), core.getHeroLoc('y'), 'stop');\n core.updateFg();\n core.drawTip(core.material.items[itemId].name + '使用成功');\n core.events.afterUseBomb();\n});", - "centerFly": "core.clearMap('hero', 0, 0, 416, 416);\ncore.setHeroLoc('x', core.status.event.data.x);\ncore.setHeroLoc('y', core.status.event.data.y);\ncore.drawHero(core.getHeroLoc('direction'), core.getHeroLoc('x'), core.getHeroLoc('y'), 'stop');\ncore.drawTip(core.material.items[itemId].name + '使用成功');", + "earthquake": "core.removeBlockByIds(core.status.floorId, core.status.event.data);\ncore.drawMap(core.status.floorId, function () {\n core.drawHero();\n core.updateFg();\n core.drawTip(core.material.items[itemId].name + '使用成功');\n});", + "pickaxe": "core.removeBlockByIds(core.status.floorId, core.status.event.data);\ncore.drawMap(core.status.floorId, function () {\n core.drawHero();\n core.updateFg();\n core.drawTip(core.material.items[itemId].name + '使用成功');\n});", + "icePickaxe": "core.removeBlockByIds(core.status.floorId, core.status.event.data);\ncore.drawMap(core.status.floorId, function () {\n core.drawHero(), 'stop');\n core.updateFg();\n core.drawTip(core.material.items[itemId].name + '使用成功');\n});", + "snow": "core.removeBlockByIds(core.status.floorId, core.status.event.data);\ncore.drawMap(core.status.floorId, function () {\n core.drawHero();\n core.updateFg();\n core.drawTip(core.material.items[itemId].name + '使用成功');\n});", + "bigKey": "core.removeBlockByIds(core.status.floorId, core.status.event.data);\ncore.drawMap(core.status.floorId, function () {\n core.drawHero();\n core.updateFg();\n core.drawTip(core.material.items[itemId].name + '使用成功');\n});", + "bomb": "core.removeBlockByIds(core.status.floorId, core.status.event.data);\ncore.drawMap(core.status.floorId, function () {\n core.drawHero();\n core.updateFg();\n core.drawTip(core.material.items[itemId].name + '使用成功');\n core.events.afterUseBomb();\n});", + "hammer": "core.removeBlockByIds(core.status.floorId, core.status.event.data);\ncore.drawMap(core.status.floorId, function () {\n core.drawHero();\n core.updateFg();\n core.drawTip(core.material.items[itemId].name + '使用成功');\n core.events.afterUseBomb();\n});", + "centerFly": "core.clearMap('hero', 0, 0, 416, 416);\ncore.setHeroLoc('x', core.status.event.data.x);\ncore.setHeroLoc('y', core.status.event.data.y);\ncore.drawHero();\ncore.drawTip(core.material.items[itemId].name + '使用成功');", "upFly": "var loc = {'direction': core.status.hero.loc.direction, 'x': core.status.event.data.x, 'y': core.status.event.data.y};\ncore.changeFloor(core.status.event.data.id, null, loc, null, function (){\n core.drawTip(core.material.items[itemId].name + '使用成功');\n core.replay();\n});", "downFly": "var loc = {'direction': core.status.hero.loc.direction, 'x': core.status.event.data.x, 'y': core.status.event.data.y};\ncore.changeFloor(core.status.event.data.id, null, loc, null, function (){\n core.drawTip(core.material.items[itemId].name + '使用成功');\n core.replay();\n});", "poisonWine": "core.setFlag('poison', false);", diff --git a/更新说明.txt b/更新说明.txt index 0fcf8d06..a2ed95eb 100644 --- a/更新说明.txt +++ b/更新说明.txt @@ -1,16 +1,31 @@ -HTML5魔塔样板V2.1 +HTML5魔塔样板V2.1.1 -编辑器添加新建和删除按钮;地图自动保存 √ -录像支持倒退(录像播放中每20步自动存档,最多存30个) √ -Gif支持:可以作为楼层背景图或者使用显示动图事件 √ -图片显示增加淡入淡出效果 √ -APP端也能下载或读取文件 √ -地图临界显伤 √ -单个存档清理 √ -大数据魔塔的支持(临界计算等) √ -进一步对JS文件和图标进行压缩,大幅提高加载速度 √ -修复有时候无法输入ID的问题 √ -其他细节优化 √ +新增事件:改变勇士行走图 +楼传器落点设置 +录像回放从任意存档点开始 +录像过程中允许存档 +血网显伤 +怪物手册显示接下来的临界表 +重置当前楼层地图core.resetMap() +支持部分楼层不允许浏览地图 +修复部分浏览器无法进入游戏的Bug +其他细节优化 + +----------------------------------------------------------------------- + +HTML5魔塔样板V2.1 + +编辑器添加新建和删除按钮;地图自动保存 +录像支持倒退(录像播放中每20步自动存档,最多存30个) +Gif支持:可以作为楼层背景图或者使用显示动图事件 +图片显示增加淡入淡出效果 +APP端也能下载或读取文件 +地图临界显伤 +单个存档清理 +大数据魔塔的支持(临界计算等) +进一步对JS文件和图标进行压缩,大幅提高加载速度 +修复有时候无法输入ID的问题 +其他细节优化 -----------------------------------------------------------------------