diff --git a/libs/core.js b/libs/core.js index e02a5d54..00f0a7e0 100644 --- a/libs/core.js +++ b/libs/core.js @@ -18,8 +18,7 @@ function core() { 'items': {}, 'enemys': {}, 'icons': {}, - 'events': {}, - 'npcs': {} + 'events': {} } this.timeout = { 'getItemTipTimeout': null @@ -83,7 +82,6 @@ function core() { // event事件 'savePage': null, 'shops': {}, - 'npcs': {}, 'event': { 'id': null, 'data': null @@ -113,10 +111,9 @@ core.prototype.init = function (dom, statusBar, canvas, images, sounds, floorIds core[key] = coreData[key]; } core.flags = core.data.flags; - // core.values = core.clone(core.data.values); + core.values = core.clone(core.data.values); core.firstData = core.data.getFirstData(); core.initStatus.shops = core.firstData.shops; - core.initStatus.npcs = core.firstData.npcs; core.dom.versionLabel.innerHTML = core.firstData.version; core.dom.logoLabel.innerHTML = core.firstData.title; core.material.items = core.items.getItems(); @@ -124,7 +121,6 @@ core.prototype.init = function (dom, statusBar, canvas, images, sounds, floorIds core.material.enemys = core.clone(core.enemys.getEnemys()); core.material.icons = core.icons.getIcons(); core.material.events = core.events.getEvents(); - core.material.npcs = core.npcs.getNpcs(); // test if iOS core.musicStatus.soundStatus = core.getLocalStorage('soundStatus', true); @@ -298,7 +294,7 @@ core.prototype.clearStatus = function() { core.resize(main.dom.body.clientWidth, main.dom.body.clientHeight); } -core.prototype.resetStatus = function(hero, hard, floorId, values, maps) { +core.prototype.resetStatus = function(hero, hard, floorId, maps) { // 停止各个Timeout和Interval for (var i in core.interval) { @@ -310,7 +306,6 @@ core.prototype.resetStatus = function(hero, hard, floorId, values, maps) { core.status.played = true; // 初始化maps core.status.floorId = floorId; - core.values = core.clone(values); core.status.maps = core.clone(maps); // 初始化怪物 core.material.enemys = core.clone(core.enemys.getEnemys()); @@ -327,8 +322,7 @@ core.prototype.resetStatus = function(hero, hard, floorId, values, maps) { core.prototype.startGame = function (hard, callback) { console.log('开始游戏'); - core.resetStatus(core.firstData.hero, hard, core.firstData.floorId, core.data.values, - core.initStatus.maps); + core.resetStatus(core.firstData.hero, hard, core.firstData.floorId, core.initStatus.maps); core.changeFloor(core.status.floorId, null, core.firstData.hero.loc, function() { core.setHeroMoveTriggerInterval(); @@ -449,11 +443,17 @@ core.prototype.keyUp = function(keyCode) { core.ui.closePanel(); if (core.status.event.id == 'load' && (keyCode==76 || keyCode==27)) core.ui.closePanel(); - if ((core.status.event.id == 'shop' || core.status.event.id == 'settings' - || core.status.event.id == 'selectShop') && keyCode==27) + if ((core.status.event.id == 'settings' || core.status.event.id == 'selectShop') && keyCode==27) core.ui.closePanel(); if (core.status.event.id == 'selectShop' && keyCode==75) core.ui.closePanel(); + if (core.status.event.id == 'shop' && keyCode==27) { + core.status.boxAnimateObjs = []; + core.setBoxAnimate(); + if (core.status.event.data.fromList) + core.ui.drawQuickShop(); + else core.ui.closePanel(); + } if (core.status.event.id == 'toolbox' && (keyCode==84 || keyCode==27)) core.ui.closePanel(); if (core.status.event.id == 'about' && (keyCode==13 || keyCode==32)) @@ -490,7 +490,7 @@ core.prototype.keyUp = function(keyCode) { core.turnHero(); break; case 75: // K - core.ui.drawSelectShop(true); + core.ui.drawQuickShop(true); break; case 37: // UP break; @@ -675,12 +675,6 @@ core.prototype.onclick = function (x, y, stepPostfix) { return; } - // NPC - if (core.status.event.id == 'npc') { - core.events.clickNPC(x,y); - return; - } - // 同步存档 if (core.status.event.id == 'syncSave') { if (x>=4 && x<=8) { @@ -1311,13 +1305,17 @@ core.prototype.drawHero = function (direction, x, y, status, offsetX, offsetY) { // 开门 core.prototype.openDoor = function (id, x, y, needKey, callback) { // 是否存在门 - if (!core.doorExists(x, y, id)) return; + if (!core.terrainExists(x, y, id)) { + if (core.isset(callback)) callback(); + return; + } if (core.status.moveStepBeforeStop.length==0) { core.status.moveStepBeforeStop=core.status.autoStepRoutes.slice(core.status.autoStep-1,core.status.autoStepRoutes.length); if (core.status.moveStepBeforeStop.length>=1)core.status.moveStepBeforeStop[0].step-=core.status.movedStep; } core.stopHero(); core.stopAutomaticRoute(); + var speed=30; if (needKey) { var key = id.replace("Door", "Key"); if (!core.rmItem(key)) { @@ -1325,13 +1323,19 @@ core.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; } } // open core.playSound("door", "ogg"); var state = 0; - var door = core.material.icons.animates[id]; + var doorId = id; + if (!(doorId.substring(doorId.length-4)=="Door")) { + doorId=doorId+"Door"; + speed=100; + } + var door = core.material.icons.animates[doorId]; core.interval.openDoorAnimate = window.setInterval(function () { state++; if (state == 4) { @@ -1342,7 +1346,7 @@ core.prototype.openDoor = function (id, x, y, needKey, callback) { } core.canvas.event.clearRect(32 * x, 32 * y, 32, 32); core.canvas.event.drawImage(core.material.images.animates, 32 * state, 32 * door, 32, 32, 32 * x, 32 * y, 32, 32); - }, 30) + }, speed) } // 战斗 @@ -1377,8 +1381,10 @@ core.prototype.battle = function (id, x, y, force, callback) { if (core.hasFlag('curse')) experience=0; core.status.hero.experience += experience; core.updateStatusBar(); - core.removeBlock(x, y); - core.canvas.event.clearRect(32 * x, 32 * y, 32, 32); + if (core.isset(x) && core.isset(y)) { + core.removeBlock(x, y); + core.canvas.event.clearRect(32 * x, 32 * y, 32, 32); + } core.updateFg(); var hint = "打败 " + core.material.enemys[id].name + ",金币+" + money; if (core.flags.enableExperience) @@ -1489,14 +1495,6 @@ core.prototype.strokeRect = function (map, x, y, width, height, style, lineWidth core.canvas[map].strokeRect(x, y, width, height); } -core.prototype.drawBlock = function (map, image, cutX, cutY, x, y, size, zoom, clear) { - zoom = zoom || 1; - if (core.isset(clear) && clear == true) { - core.canvas[map].clearRect(x * size, y * size, size, size); - } - core.canvas[map].drawImage(core.material.images[image], cutX * size, cutY * size, size, size, x * size, y * size, size * zoom, size * zoom); -} - core.prototype.setFont = function (map, font) { core.canvas[map].font = font; } @@ -1518,13 +1516,13 @@ core.prototype.loadCanvas = function (map) { core.canvas[map].restore(); } -core.prototype.setOpacity = function (map, opacity) { +core.prototype.setAlpha = function (map, alpha) { if (map == 'all') { for (var m in core.canvas) { - core.canvas[m].globalAlpha = opacity; + core.canvas[m].globalAlpha = alpha; } } - core.canvas[map].globalAlpha = opacity; + core.canvas[map].globalAlpha = alpha; } core.prototype.setStrokeStyle = function (map, style) { @@ -1596,120 +1594,49 @@ core.prototype.drawMap = function (mapName, callback) { core.addGlobalAnimate(mapBlocks[b].event.animate, mapBlocks[b].x * 32, mapBlocks[b].y * 32, blockIcon, blockImage); } } - core.setGlobalAnimate(core.firstData.animateSpeed); + core.setGlobalAnimate(core.values.animateSpeed); if (core.isset(callback)) callback(); } -/** - * 是否存在不可通行节点 - * @param x - * @param y - * @returns {boolean} - */ core.prototype.noPassExists = function (x, y, floorId) { var block = core.getBlock(x,y,floorId); if (block==null) return false; return core.isset(block.block.event.noPass) && block.block.event.noPass; - /* - var blocks = core.status.thisMap.blocks; - for (var n = 0; n < blocks.length; n++) { - if (blocks[n].x == x && blocks[n].y == y && core.isset(blocks[n].event) - && !(core.isset(blocks[n].enable) && !blocks[n].enable) - && core.isset(blocks[n].event.noPass) && blocks[n].event.noPass) { - return true; - } - } - return false; - */ } -/** - * 是否存在NPC节点 - * @param x - * @param y - * @returns {boolean} - */ core.prototype.npcExists = function (x, y, floorId) { var block = core.getBlock(x,y,floorId); if (block==null) return false; return block.block.event.cls == 'npcs'; - /* - var blocks = core.status.thisMap.blocks; - for (var n = 0; n < blocks.length; n++) { - if (blocks[n].x == x && blocks[n].y == y && core.isset(blocks[n].event) - && !(core.isset(blocks[n].enable) && !blocks[n].enable) - && blocks[n].event.cls == 'npcs') { - return true; - } - } - return false; - */ } -core.prototype.doorExists = function (x, y, id, floorId) { +core.prototype.terrainExists = function (x, y, id, floorId) { var block = core.getBlock(x,y,floorId); if (block==null) return false; return block.block.event.cls=='terrains' && block.block.event.id==id; - - /* - if (x > 12 || y > 12 || x < 0 || y < 0) { - return true; - } - if (core.stairExists(x, y)) { - return false; - } - var blocks = core.status.thisMap.blocks; - for (var t = 0; t < blocks.length; t++) { - if (blocks[t].x == x && blocks[t].y == y) { - if (core.isset(blocks[t][map]) && (blocks[t][map].cls == 'terrains' || (blocks[t][map].cls == 'animates' && core.isset(blocks[t][map].noPass) && blocks[t][map].noPass == true)) && ((core.isset(id) && core.isset(blocks[t][map].id)) ? blocks[t][map].id == id : true)) { - return true; - } - } - } - return false; - */ } -/** - * 是否存在楼梯 - * @param x - * @param y - * @returns {boolean} - */ core.prototype.stairExists = function (x, y, floorId) { var block = core.getBlock(x,y,floorId); if (block==null) return false; return block.block.event.cls=='terrains' && (block.block.event.id=='upFloor' || block.block.event.id=='downFloor'); - /* - var blocks = core.status.thisMap.blocks; - for (var s = 0; s < blocks.length; s++) { - if (blocks[s].x == x && blocks[s].y == y && core.isset(blocks[s].event) && blocks[s].event.cls == 'terrains' && core.isset(blocks[s].event.id) && (blocks[s].event.id == 'upFloor' || blocks[s].event.id == 'downFloor')) { - return true; - } - } - return false; - */ +} + +core.prototype.nearStair = function() { + var x=core.getHeroLoc('x'), y=core.getHeroLoc('y'); + return core.stairExists(x,y) || core.stairExists(x-1,y) || core.stairExists(x,y-1) || core.stairExists(x+1,y) || core.stairExists(x,y+1); } core.prototype.enemyExists = function (x, y, id,floorId) { var block = core.getBlock(x,y,floorId); if (block==null) return false; return block.block.event.cls=='enemys' && block.block.event.id==id; - /* - var blocks = core.status.thisMap.blocks; - for (var e = 0; e < blocks.length; e++) { - if (blocks[e].x == x && blocks[e].y == y && core.isset(blocks[e].event) && blocks[e].event.cls == 'enemys' && ((core.isset(id) && core.isset(blocks[e].event.id)) ? blocks[e].event.id == id : true)) { - return true; - } - } - return false; - */ } core.prototype.getBlock = function (x, y, floorId, needEnable) { - floorId = floorId || core.status.floorId; - needEnable = needEnable || true; + if (!core.isset(floorId)) floorId=core.status.floorId; + if (!core.isset(needEnable)) needEnable=true; var blocks = core.status.maps[floorId].blocks; for (var n=0;n=0) { + blocks[index] = {'x': x, 'y': y, 'event': {'cls': 'terrains', 'id': 'ground', 'noPass': false, 'trigger': 'checkBlock'}}; + return; + } + // 检查该点是否存在事件 var event = core.floors[floorId].events[x+","+y]; + if (!core.isset(event)) + event = core.floors[floorId].changeFloor[x+","+y]; // 不存在事件,直接删除 if (!core.isset(event)) { blocks.splice(index,1); return; } - // 如果该点事件是“checkBlock”,则替换现有的事件 - if ((event instanceof Object) && event.trigger == 'checkBlock') { - blocks[index] = {'x': x, 'y': y, 'event': {'cls': 'terrains', 'id': 'ground', 'noPass': false, 'trigger': 'checkBlock'}}; + + blocks[index].enable = false; +} + +core.prototype.moveBlock = function(x,y,steps,time,disappear,callback) { + time = time || 500; + + clearInterval(core.interval.tipAnimate); + core.saveCanvas('data'); + core.clearMap('data', 0, 0, 416, 416); + + var block = core.getBlock(x,y,core.status.floorId,false); + if (block==null) {// 不存在 + if (core.isset(callback)) callback(); return; } - // 否则,则存在自定义事件。简单的将该点的enable置为false - blocks[index].enable = false; + + // 需要删除该块 + core.removeBlock(x,y); + + core.clearMap('ui', 0, 0, 416, 416); + core.setAlpha('ui', 1.0); + + block=block.block; + blockIcon = core.material.icons[block.event.cls][block.event.id]; + blockImage = core.material.images[block.event.cls]; + + // 绘制data层 + var opacityVal = 1; + core.setOpacity('data', opacityVal); + core.canvas.data.drawImage(blockImage, 0, blockIcon * 32, 32, 32, block.x * 32, block.y * 32, 32, 32); + + // 要运行的轨迹:将steps展开 + var moveSteps=[]; + steps.forEach(function (e) { + if (typeof e=="string") { + moveSteps.push(e); + } + else { + if (!core.isset(e.value)) { + moveSteps.push(e.direction) + } + else { + for (var i=0;i=1 || opacityVal<=0) { + clearInterval(animate); + core.loadCanvas('data'); + core.clearMap('data', 0, 0, 416, 416); + core.setOpacity('data', 1); + if (core.isset(callback)) callback(); + } + }, time/10); +} + +// 显示一个事件 +core.prototype.addBlock = function(x,y,floodId) { + floodId = floodId || core.status.floorId; + var block = core.getBlock(x,y,floodId,false); + if (block==null) return; // 不存在 + block=block.block; + // 本身是禁用事件,启用之 + if (core.isset(block.enable) && !block.enable) { + block.enable = true; + // 在本层,添加动画 + if (floodId == core.status.floorId && core.isset(block.event)) { + blockIcon = core.material.icons[block.event.cls][block.event.id]; + blockImage = core.material.images[block.event.cls]; + core.canvas.event.drawImage(core.material.images[block.event.cls], 0, blockIcon * 32, 32, 32, block.x * 32, block.y * 32, 32, 32); + core.addGlobalAnimate(block.event.animate, block.x * 32, block.y * 32, blockIcon, blockImage); + core.setGlobalAnimate(core.values.animateSpeed); + } + } } core.prototype.removeBlock = function (x, y, floorId) { @@ -1758,52 +1837,17 @@ core.prototype.removeBlock = function (x, y, floorId) { // 删除Index core.removeBlockById(index, floorId); - - /* - var mapBlocks = core.status.maps[floorId].blocks; - var blockIcon; - for (var b = 0; b < mapBlocks.length; b++) { - if (mapBlocks[b].x == x && mapBlocks[b].y == y) { - core.rmGlobalAnimate(x, y); - for (var m = 0; m < map.length; m++) { - if (!core.isset(mapBlocks[b][map[m]])) { - continue; - } - blockIcon = core.material.icons[mapBlocks[b][map[m]].cls][mapBlocks[b][map[m]].id]; - core.canvas[map[m]].clearRect(x * 32, y * 32, 32, 32); - // delete core.status.thisMap.blocks[b][map[m]]; - } - core.status.thisMap.blocks.splice(b, 1); - break; - } - } - */ + core.updateFg(); } core.prototype.removeBlockByIds = function (floorId, ids) { ids.sort(function (a,b) {return b-a}).forEach(function (id) { - // core.status.maps[floorId].blocks.splice(id, 1); core.removeBlockById(id, floorId); }); } core.prototype.noPass = function (x, y) { - if (x > 12 || y > 12 || x < 0 || y < 0) { - return true; - } - return core.noPassExists(x,y); - /* - if (x > 12 || y > 12 || x < 0 || y < 0) { - return true; - } - var mapBlocks = core.status.thisMap.blocks; - var noPass; - for (var b = 0; b < mapBlocks.length; b++) { - if (mapBlocks[b].x == x && mapBlocks[b].y == y) { - return noPass = (mapBlocks[b].event && mapBlocks[b].event.noPass) || (mapBlocks[b].bg && mapBlocks[b].bg.noPass); - } - } - */ + return x<0 || x>12 || y<0 || y>12 || core.noPassExists(x,y); } core.prototype.trigger = function (x, y) { @@ -1820,8 +1864,8 @@ core.prototype.trigger = function (x, y) { // 转换楼层能否穿透 if (trigger=='changeFloor' && (core.status.autoHeroMove || core.status.autoStep0 && (!core.isset(data.floorId) || data.floorId==core.status.floorId)) { + core.animateBlock(data.loc[0],data.loc[1],'show', data.time, function () { + core.addBlock(data.loc[0],data.loc[1],data.floorId); + core.events.doAction(); + }); + } + else { + core.addBlock(data.loc[0],data.loc[1],data.floorId) + this.doAction(); + } + break; case "hide": // 消失 - core.removeBlock(x, y); + var toX=x, toY=y, toId=core.status.floorId; + if (core.isset(data.loc)) { + toX=data.loc[0]; toY=data.loc[1]; + } + if (core.isset(data.floorId)) toId=data.floorId; + core.removeBlock(toX,toY,toId) + if (core.isset(data.time) && data.time>0 && toId==core.status.floorId) { + core.animateBlock(toX,toY,'hide',data.time, function () { + core.events.doAction(); + }); + } + else this.doAction(); + break; + case "move": // 移动事件 + core.moveBlock(x,y,data.steps,data.time,data.disappear,function() { + core.events.doAction(); + }) + break; + case "changeFloor": // 楼层转换 + core.changeFloor(data.floorId||core.status.floorId, null, {"x": data.loc[0], "y": data.loc[1]}, function() { + core.lockControl(); + core.events.doAction(); + }); + break; + case "changePos": // 直接更换勇士位置,不切换楼层 + core.clearMap('hero', 0, 0, 416, 416); + core.setHeroLoc('x', data.loc[0]); + core.setHeroLoc('y', data.loc[1]); + core.drawHero(core.getHeroLoc('direction'), core.getHeroLoc('x'), core.getHeroLoc('y'), 'stop'); + this.doAction(); + break; + case "openDoor": // 开一个门,包括暗墙 + var floorId=data.floorId || core.status.floorId; + var block=core.getBlock(data.loc[0], data.loc[1], floorId); + if (block!=null) { + if (floorId==core.status.floorId) + core.openDoor(block.block.event.id, block.block.x, block.block.y, false, function() { + core.events.doAction(); + }) + else { + core.removeBlock(block.block.x,block.block.y,floorId); + this.doAction(); + } + break; + } + this.doAction(); + break; + case "openShop": // 打开一个全局商店 + core.events.openShop(data.id); + break; + case "battle": // 强制战斗 + core.battle(data.id,null,null,true,function() { + core.events.doAction(); + }) + break; + case "trigger": // 触发另一个事件;当前事件会被立刻结束。需要另一个地点的事件是有效的 + var toX=data.loc[0], toY=data.loc[1], toId=data.floorId; + var block=core.getBlock(toX, toY, toId); + if (block!=null) { + block = block.block; + if (core.isset(block.event) && block.event.trigger=='action') { + // 触发 + core.status.event = {'id': 'action', 'data': { + 'list': core.clone(block.event.data), 'x': block.x, 'y': block.y, 'callback': core.status.event.data.callback + }} + } + } + this.doAction(); + break; + case "playSound": + var name=data.name.split("."); + if (name.length==2) + core.playSound(name[0],name[1]); + this.doAction(); + break; + case "setValue": + try { + var value=core.calValue(data.value); + // 属性 + if (data.name.indexOf("status:")==0) { + value=parseInt(value); + core.setStatus(data.name.substring(7), value); + } + // 道具 + if (data.name.indexOf("item:")==0) { + value=parseInt(value); + var itemId=data.name.substring(5); + if (value>core.itemCount(itemId)) // 效果 + core.getItem(itemId,value-core.itemCount(itemId)); + else core.setItem(itemId, value); + } + // flag + if (data.name.indexOf("flag:")==0) { + core.setFlag(data.name.substring(5), value); + } + } + catch (e) {console.log(e)} + core.updateStatusBar(); + this.doAction(); + break; + case "if": // 条件判断 + if (core.calValue(data.condition)) + core.events.insertAction(data.true) + else + core.events.insertAction(data.false) + this.doAction(); + break; + case "choices": // 提供选项 + core.ui.drawChoices(data.text, data.choices); + break; + case "win": + core.events.win(data.reason); + break; + case "lose": + core.events.lose(data.reason); + break; + case "function": + if (core.isset(data.function)) + data.function(); + this.doAction(); + break; + case "update": + core.updateStatusBar(); this.doAction(); break; case "sleep": // 等待多少毫秒 setTimeout(function () { core.events.doAction(); - }, data.data); + }, data.time); + break; + case "revisit": // 立刻重新执行该事件 + var block=core.getBlock(x,y); // 重新获得事件 + if (block!=null) { + block = block.block; + if (core.isset(block.event) && block.event.trigger=='action') { + core.status.event.data.list = core.clone(block.event.data); + } + } + this.doAction(); break; case "exit": // 立刻结束事件 core.status.event.data.list = []; @@ -188,7 +365,51 @@ events.prototype.doAction = function() { return; } +////// 往当前事件列表之前添加一个或多个事件 ////// +events.prototype.insertAction = function (action) { + core.unshift(core.status.event.data.list, action) +} + +////// 打开商店 ////// +events.prototype.openShop = function(shopId, needVisited) { + var shop = core.status.shops[shopId]; + shop.times = shop.times || 0; + shop.visited = shop.visited || false; + if (needVisited && !shop.visited) { + if (shop.times==0) core.drawTip("该商店尚未开启"); + else core.drawTip("该商店已失效"); + return; + } + shop.visited = true; + + core.ui.closePanel(); + core.lockControl(); + core.status.event = {'id': 'shop', 'data': {'id': shopId, 'shop': shop}}; + // 拼词 + var content = "\t["+shop.name+","+shop.icon+"]"; + var times = shop.times, need=eval(shop.need); + if (need<0) need="若干"; + var use=shop.use=="experience"?"经验":"金币"; + content = content+"勇敢的武士啊,给我"+need+"\n"+use+",你就可以:" + var choices = []; + for (var i=0;i= 5 && x <= 7) { + var topIndex = 6 - parseInt((choices.length - 1) / 2); + if (y>=topIndex && y= 5 && x <= 7) { - if (y >= 5 && y <= 8) { - if (y >= 5 + core.status.event.data.choices.length) return; - + var topIndex = 6 - parseInt(choices.length / 2); + if (y>=topIndex && y= 5 && x <= 7) { - if (y >= 5 && y <= 8) { - if (y >= 5 + data.choices.length) return; - - var choice = data.choices[y - 5]; - if (core.isset(choice.need)) { - var able = true; - choice.need.split(';').forEach(function (e) { - var ones = e.split(','); - var type = ones[0], key = ones[1], value = ones[2]; - if (type == 'status') { - if (core.getStatus(key)=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"}, // 增加黄钥匙 + // 然后会继续执行下面的setValue来增加商人访问次数 + ], + "false": [ + "\t[老人,woman]你的金钱不足!", + {"type": "revisit"} // 直接重新访问;不执行下面的setValue来增加访问次数 + ] + } + ]}, + {"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\"} 可以写自定义的\nJS脚本。\n本塔支持的所有主要API会在doc文档内给出。", + "\t[老人,womanMagician]例如这个例子:即将弹出一个输入窗口,然后\n会将你的输入结果直接加到你的攻击力上。", + {"type": "function", "function": function() { // 自己写JS脚本并执行 + var value = prompt("请输入你要加攻击力的数值:"); // 弹出一个输入框让用户输入数据 + if (value!=null) { + value=parseInt(value); + if (value>0) { // 检查 + core.setStatus("atk", core.getStatus("atk")+value); + // core.updateStatusBar(); // 和下面的 {"type": "update"} 等价,立即更新状态栏和地图显伤 + core.drawTip("操作成功,攻击+"+value); // 左上角气泡提示 + core.events.insertAction([ // 往当前事件列表前插入两条事件 + {"type": "update"}, // 更新状态栏和地图显伤 + "操作成功,攻击+"+value // 对话框提示 + ]); + } + } + }}, + "\t[老人,womanMagician]具体可参见样板中本事件的写法。" ] - }; + }, + "changeFloor": { // 楼层转换事件;该事件不能和上面的events有冲突(同位置点),否则会被覆盖 + "4,12": {"floorId": "sample0", "loc": [6,0]} // 由于楼下有多个上楼梯,所以需指定位置而不是简单地写"stair": "upFloor" + }, + "afterBattle": { // 战斗后可能触发的事件列表 + "9,6": [ // 初级卫兵1 + {"type": "setValue", "name": "flag:door", "value": "flag:door+1"}, // 将"door"这个自定义flag加一 + {"type": "if", "condition": "flag:door==2", // 一个条件判断事件,条件是"door"这个flag值等于2 + "true": [ // 如果条件成立:打开机关门 + {"type": "openDoor", "loc": [10,5]} + ], + "false": [] // 如果条件不成立则无事件触发 + }, + ], + "11,6": [ // 初级卫兵2;注意由于打怪顺序问题,可能都得写一遍。 + {"type": "setValue", "name": "flag:door", "value": "flag:door+1"}, // 将"door"这个自定义flag加一 + {"type": "if", "condition": "flag:door==2", // 一个条件判断事件,条件是"door"这个flag值等于2 + "true": [ // 如果条件成立:打开机关门 + {"type": "openDoor", "loc": [10,5]} + ], + "false": [] // 如果条件不成立则无事件触发 + }, + ], + }, + "afterGetItem": { // 获得道具后可能触发的事件列表 + + }, + "afterOpenDoor": { // 开完门后可能触发的事件列表 + + }, + "checkBlock": [ + /****** 领域、夹击检查事件 ******/ + // 所有可能的领域、夹击点均需要在这里给出,否则将不会触发检查事件 + // 另外,如果该点已经存在events事件或changeFloor事件(即上面有相同点位置定义),则会被覆盖 + // afterBattle, afterGetItem, afterOpenDoor则不受影响(仍能正常工作)。 + // 所以 |****** 强烈要求可能的夹击、领域点不要存在自定义事件!! ******| + ] + } -main.floors.sample1 = new sample1(); diff --git a/libs/maps.js b/libs/maps.js index 0d174b99..0a6b15e3 100644 --- a/libs/maps.js +++ b/libs/maps.js @@ -8,7 +8,6 @@ maps.prototype.loadFloor = function (floorId, map) { content['name'] = floor.name; content['title'] = floor.title; content['canFlyTo'] = floor.canFlyTo; - content['firstArrive'] = floor.firstArrive; if (!core.isset(map)) map=floor.map; var blocks = []; for (var i = 0; i < 13; i++) { @@ -36,6 +35,9 @@ maps.prototype.loadFloor = function (floorId, map) { } } this.addEvent(block,j,i,floor.events[j+","+i]) + this.addChangeFloor(block,j,i,floor.changeFloor[j+","+i]); + if (floor.checkBlock.indexOf(j+","+i)>=0) + this.addEvent(block,j,i,{"trigger":"checkBlock"}); if (core.isset(block.event)) blocks.push(block); } } @@ -57,6 +59,7 @@ maps.prototype.getBlock = function (x, y, id) { enable = true; } } + id=parseInt(id); var tmp = {'x': x, 'y': y, 'id': id}; if (enable!=null) tmp.enable = enable; @@ -232,9 +235,11 @@ maps.prototype.addEvent = function (block, x, y, event) { else if (event instanceof Array) { event = {"data": event}; } + if (!core.isset(event.data)) + event.data = []; // 覆盖enable - if (!core.isset(block.event.enable) && core.isset(event.enable)) { + if (!core.isset(block.enable) && core.isset(event.enable)) { block.enable=event.enable; } // 覆盖trigger @@ -250,6 +255,11 @@ maps.prototype.addEvent = function (block, x, y, event) { } } +maps.prototype.addChangeFloor = function (block, x, y, event) { + if (!core.isset(event)) return; + this.addEvent(block, x, y, {"trigger": "changeFloor", "data": event}); +} + maps.prototype.initMaps = function (floorIds) { var maps = {}; for (var i=0;i', 270, top+height-13, '#CCCCCC', '13px Verdana'); } +// 绘制选项事件 +ui.prototype.drawChoices = function(content, choices) { + + var background = core.canvas.ui.createPattern(core.material.ground, "repeat"); + + core.clearMap('ui', 0, 0, 416, 416); + core.setAlpha('ui', 1); + core.setFillStyle('ui', background); + + // Step 1: 计算长宽高 + var length = choices.length; + var left=85, width = 416-2*left; // 宽度 + // 高度 + var height = 32*(length+2), bottom = 208+height/2; + if (length%2==0) bottom+=16; + var choice_top = bottom-height+56; + + var id=null, name=null, image=null, icon=null; + if (core.isset(content)) { + // 获得name, image, icon + if (content.indexOf("\t[")==0) { + var index = content.indexOf("]"); + if (index>=0) { + var str=content.substring(2, index); + content=content.substring(index+1); + var ss=str.split(","); + if (ss.length==1) { + // id + id=ss[0]; + // monster + if (id!='hero') { + var enemys = core.material.enemys[id]; + if (core.isset(enemys)) { + name = core.material.enemys[id].name; + image = core.material.images.enemys; + icon = core.material.icons.enemys[id]; + } + else { + name=id; + id='npc'; + image=null; + icon=null; + } + } + } + else { + id='npc'; + name=ss[0]; + image=core.material.images.npcs; + icon=core.material.icons.npcs[ss[1]]; + } + } + } + content = core.replaceText(content); + + // content部分高度 + var cheight=0; + // 如果含有标题,标题高度 + if (name!=null) cheight+=25; + cheight += content.split('\n').length*20; + height+=cheight; + } + var top = bottom-height; + + core.fillRect('ui', left, top, width, height, background); + core.strokeRect('ui', left - 1, top - 1, width + 1, height + 1, '#FFFFFF', 2); + + // 如果有内容 + if (core.isset(content)) { + + var content_left = left + 15, content_top = top + 35; + + if (core.isset(id)) { + core.canvas.ui.textAlign = "center"; + + content_top = top+55; + var title_offset = left+width/2; + // 动画 + if (id=='hero' || core.isset(icon)) { + core.strokeRect('ui', left + 15 - 1, top + 30 - 1, 34, 34, '#DDDDDD', 2); + content_left = left+60; + title_offset += 22; + } + + if (id == 'hero') { + core.fillText('ui', core.status.hero.name, title_offset, top + 27, '#FFD700', 'bold 19px Verdana'); + core.clearMap('ui', left + 15, top + 30, 32, 32); + core.fillRect('ui', left + 15, top + 30, 32, 32, background); + var heroIcon = core.material.icons.heros[core.status.hero.id]['down']; + core.canvas.ui.drawImage(core.material.images.heros, heroIcon.stop * 32, heroIcon.loc *32, 32, 32, left+15, top+30, 32, 32); + } + else { + core.fillText('ui', name, title_offset, top + 27, '#FFD700', 'bold 19px Verdana'); + if (core.isset(icon)) { + core.status.boxAnimateObjs = []; + core.status.boxAnimateObjs.push({ + 'bgx': left + 15, 'bgy': top + 30, 'bgsize': 32, + 'image': image, 'x': left + 15, 'y': top + 30, 'icon': icon + }); + core.setBoxAnimate(); + } + } + } + + core.canvas.ui.textAlign = "left"; + var contents=content.split("\n"); + for (var i=0;i