diff --git a/_server/editor.js b/_server/editor.js index e19309cd..39187c45 100644 --- a/_server/editor.js +++ b/_server/editor.js @@ -49,7 +49,7 @@ editor.prototype.idsInit = function(maps, icons){ editor.indexs = []; var MAX_NUM = 400; var getInfoById = function(id){ - var block = maps.getBlock(0, 0, id); + var block = maps.initBlock(0, 0, id); if(hasOwnProp(block, 'event')){ return block; } diff --git a/libs/actions.js b/libs/actions.js new file mode 100644 index 00000000..ad767903 --- /dev/null +++ b/libs/actions.js @@ -0,0 +1,1909 @@ +/* +actions.js:用户交互的事件的处理 +键盘、鼠标、触摸屏事件相关 + */ + +function actions() { + this.init(); +} + +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.holdingKeys))core.status.holdingKeys=[]; + var isArrow={37:true,38:true,39:true,40:true}[e.keyCode] + if(isArrow && !core.status.lockControl){ + for(var ii =0;iimax){ + index=ii; + max=directionDistance[ii]; + } + } + pos=[{'x':0,'y':1},{'x':-1,'y':0},{'x':0,'y':-1},{'x':1,'y':0},false][index] + if(pos){ + pos.x+=pos0.x; + pos.y+=pos0.y; + core.status.stepPostfix.push(pos); + core.fillPosWithPoint(pos); + } +} + +////// 当点击(触摸)事件放开时 ////// +actions.prototype.onup = function () { + if (core.isset(core.status.replay)&&core.status.replay.replaying) return; + + clearTimeout(core.timeout.onDownTimeout); + core.timeout.onDownTimeout = null; + clearInterval(core.interval.onDownInterval); + core.interval.onDownInterval = null; + + // core.status.holdingPath=0; + if(core.status.stepPostfix.length>0){ + var stepPostfix = []; + var direction={'0':{'1':'down','-1':'up'},'-1':{'0':'left'},'1':{'0':'right'}}; + for(var ii=1;ii=1000) { + core.waitHeroToStop(function () { + // 绘制快捷键 + core.ui.drawKeyBoard(); + }); + } + else { + //posx,posy是寻路的目标点,stepPostfix是后续的移动 + this.onclick(posx,posy,stepPostfix); + } + core.status.downTime=null; + } +} + +////// 获得点击事件相对左上角的坐标(0到12之间) ////// +actions.prototype.getClickLoc = function (x, y) { + + var statusBar = {'x': 0, 'y': 0}; + var size = 32; + size = size * core.domStyle.scale; + + switch (core.domStyle.screenMode) {// 这里的3是指statusBar和游戏画布之间的白线宽度 + case 'vertical': + statusBar.x = 0; + statusBar.y = core.dom.statusBar.offsetHeight + 3; + break; + case 'horizontal': + case 'bigScreen': + statusBar.x = core.dom.statusBar.offsetWidth + 3; + statusBar.y = 0; + break; + } + + var left = core.dom.gameGroup.offsetLeft + statusBar.x; + var top = core.dom.gameGroup.offsetTop + statusBar.y; + var loc={'x': x - left, 'y': y - top, 'size': size}; + return loc; +} + +////// 具体点击屏幕上(x,y)点时,执行的操作 ////// +actions.prototype.onclick = function (x, y, stepPostfix) { + if (core.isset(core.status.replay)&&core.status.replay.replaying) return; + // console.log("Click: (" + x + "," + y + ")"); + + stepPostfix=stepPostfix||[]; + + // 非游戏屏幕内 + if (x<0 || y<0 || x>12 || y>12) return; + + // 中心对称飞行器 + if (core.status.usingCenterFly) { + if (x!=12-core.getHeroLoc('x') || y!=12-core.getHeroLoc('y')) { + core.clearMap('ui', (12-core.getHeroLoc('x'))*32,(12-core.getHeroLoc('y'))*32,32,32); + } else { + if (core.canUseItem('centerFly')) { + core.useItem('centerFly'); + core.clearMap('ui', core.getHeroLoc('x')*32,core.getHeroLoc('y')*32,32,32); + return; + } + else { + core.drawTip('当前不能使用中心对称飞行器'); + core.clearMap('ui', (12-core.getHeroLoc('x'))*32,(12-core.getHeroLoc('y'))*32,32,32); + } + } + core.status.usingCenterFly= false; + } + + // 寻路 + if (!core.status.lockControl) { + core.setAutomaticRoute(x, y, stepPostfix); + return; + } + + // 怪物手册 + if (core.status.event.id == 'book') { + this.clickBook(x,y); + return; + } + + // 怪物详细信息 + if (core.status.event.id == 'book-detail') { + this.clickBookDetail(x,y); + return; + } + + // 楼层飞行器 + if (core.status.event.id == 'fly') { + this.clickFly(x,y); + return; + } + + // 查看地图 + if (core.status.event.id == 'viewMaps') { + this.clickViewMaps(x,y); + return; + } + + // 开关 + if (core.status.event.id == 'switchs') { + this.clickSwitchs(x,y); + return; + } + + // 设置 + if (core.status.event.id == 'settings') { + this.clickSettings(x,y); + return; + } + + // 商店 + if (core.status.event.id == 'shop') { + this.clickShop(x,y); + return; + } + + // 快捷商店 + if (core.status.event.id == 'selectShop') { + this.clickQuickShop(x,y); + return; + } + + // 工具栏 + if (core.status.event.id == 'toolbox') { + this.clickToolbox(x,y); + return; + } + + // 存读档 + if (core.status.event.id == 'save' || core.status.event.id == 'load') { + this.clickSL(x,y); + return; + } + + // 选项 + if (core.status.event.id == 'confirmBox') { + this.clickConfirmBox(x,y); + return; + } + + if (core.status.event.id == 'keyBoard') { + this.clickKeyBoard(x,y); + return; + } + + // 关于 + if (core.status.event.id == 'about') { + this.clickAbout(x,y); + return; + } + + if (core.status.event.id == 'action') { + this.clickAction(x,y); + return; + } + + // 纯文本 + if (core.status.event.id == 'text') { + core.drawText(); + return; + } + + // 同步存档 + if (core.status.event.id == 'syncSave') { + this.clickSyncSave(x,y); + return; + } + + if (core.status.event.id == 'syncSelect') { + this.clickSyncSelect(x,y); + return; + } + + if (core.status.event.id == 'localSaveSelect') { + this.clickLocalSaveSelect(x,y); + return; + } + + if (core.status.event.id == 'cursor') { + this.clickCursor(x,y); + return; + } + +} + +////// 滑动鼠标滚轮时的操作 ////// +actions.prototype.onmousewheel = function (direct) { + if (core.isset(core.status.replay)&&core.status.replay.replaying) return; + // 向下滚动是 -1 ,向上是 1 + + // 楼层飞行器 + if (core.status.lockControl && core.status.event.id == 'fly') { + if (direct==1) core.ui.drawFly(core.status.event.data+1); + if (direct==-1) core.ui.drawFly(core.status.event.data-1); + return; + } + + // 怪物手册 + if (core.status.lockControl && core.status.event.id == 'book') { + if (direct==1) core.ui.drawBook(core.status.event.data - 6); + if (direct==-1) core.ui.drawBook(core.status.event.data + 6); + return; + } + + // 存读档 + if (core.status.lockControl && (core.status.event.id == 'save' || core.status.event.id == 'load')) { + if (direct==1) core.ui.drawSLPanel(core.status.event.data - 10); + if (direct==-1) core.ui.drawSLPanel(core.status.event.data + 10); + return; + } + + // 浏览地图 + 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); + return; + } +} + +/////////////////// 在某个界面时的按键点击效果 /////////////////// + +////// 长按 ////// +actions.prototype.longClick = function () { + if (!core.isPlaying()) return false; + if (core.status.event.id=='text') { + core.drawText(); + return true; + } + if (core.status.event.id=='action' && core.status.event.data.type=='text') { + core.doAction(); + return true; + } + return false; +} + +////// 按下Ctrl键时(快捷跳过对话) ////// +actions.prototype.keyDownCtrl = function () { + if (core.status.event.id=='text') { + core.drawText(); + return; + } + if (core.status.event.id=='action' && core.status.event.data.type=='text') { + core.doAction(); + return; + } +} + +////// 点击确认框时 ////// +actions.prototype.clickConfirmBox = function (x,y) { + if ((x == 4 || x == 5) && y == 7 && core.isset(core.status.event.data.yes)) + core.status.event.data.yes(); + if ((x == 7 || x == 8) && y == 7 && core.isset(core.status.event.data.no)) + core.status.event.data.no(); +} + +////// 键盘操作确认框时 ////// +actions.prototype.keyUpConfirmBox = function (keycode) { + if (keycode==37) { + core.status.event.selection=0; + core.ui.drawConfirmBox(core.status.event.ui, core.status.event.data.yes, core.status.event.data.no); + } + + if (keycode==39) { + core.status.event.selection=1; + core.ui.drawConfirmBox(core.status.event.ui, core.status.event.data.yes, core.status.event.data.no); + } + + if (keycode==13 || keycode==32 || keycode==67) { + if (core.status.event.selection==0 && core.isset(core.status.event.data.yes)) { + core.status.event.selection=null; + core.status.event.data.yes(); + } + if (core.status.event.selection==1 && core.isset(core.status.event.data.no)) { + core.status.event.selection=null; + core.status.event.data.no(); + } + } +} + +////// 自定义事件时的点击操作 ////// +actions.prototype.clickAction = function (x,y) { + + if (core.status.event.data.type=='text') { + // 文字 + core.doAction(); + return; + } + if (core.status.event.data.type=='choices') { + // 选项 + var data = core.status.event.data.current; + var choices = data.choices; + if (choices.length==0) return; + if (x >= 5 && x <= 7) { + var topIndex = 6 - parseInt((choices.length - 1) / 2); + if (y>=topIndex && y0) { + if (keycode==38) { + core.status.event.selection--; + core.ui.drawChoices(core.status.event.ui.text, core.status.event.ui.choices); + } + if (keycode==40) { + core.status.event.selection++; + core.ui.drawChoices(core.status.event.ui.text, core.status.event.ui.choices); + } + } + } +} + +////// 自定义事件时,放开某个键的操作 ////// +actions.prototype.keyUpAction = function (keycode) { + if (core.status.event.data.type=='text' && (keycode==13 || keycode==32 || keycode==67)) { + core.doAction(); + return; + } + if (core.status.event.data.type=='choices') { + var data = core.status.event.data.current; + var choices = data.choices; + if (choices.length>0) { + if (keycode==13 || keycode==32 || keycode==67) { + core.status.route.push("choices:"+core.status.event.selection); + core.insertAction(choices[core.status.event.selection].action); + core.doAction(); + } + } + } +} + +////// 怪物手册界面的点击操作 ////// +actions.prototype.clickBook = function(x,y) { + // 上一页 + if ((x == 3 || x == 4) && y == 12) { + core.ui.drawBook(core.status.event.data - 6); + return; + } + // 下一页 + if ((x == 8 || x == 9) && y == 12) { + core.ui.drawBook(core.status.event.data + 6); + return; + } + // 返回 + if (x>=10 && x<=12 && y==12) { + if (core.status.event.selection==null) + core.ui.closePanel(); + else { + core.status.boxAnimateObjs = []; + core.ui.drawMaps(core.status.event.selection); + } + return; + } + // 怪物信息 + var data = core.status.event.data; + if (core.isset(data) && y<12) { + var page=parseInt(data/6); + var index=6*page+parseInt(y/2); + core.ui.drawBook(index); + core.ui.drawBookDetail(index); + } + return; +} + +////// 怪物手册界面时,按下某个键的操作 ////// +actions.prototype.keyDownBook = function (keycode) { + if (keycode==37) core.ui.drawBook(core.status.event.data-6); + if (keycode==38) core.ui.drawBook(core.status.event.data-1); + if (keycode==39) core.ui.drawBook(core.status.event.data+6); + if (keycode==40) core.ui.drawBook(core.status.event.data+1); + if (keycode==33) core.ui.drawBook(core.status.event.data-6); + if (keycode==34) core.ui.drawBook(core.status.event.data+6); + return; +} + +////// 怪物手册界面时,放开某个键的操作 ////// +actions.prototype.keyUpBook = function (keycode) { + if (keycode==27 || keycode==88) { + if (core.status.event.selection==null) + core.ui.closePanel(); + else { + core.status.boxAnimateObjs = []; + core.ui.drawMaps(core.status.event.selection); + } + return; + } + if (keycode==13 || keycode==32 || keycode==67) { + var data=core.status.event.data; + if (core.isset(data)) { + this.clickBook(6, 2*(data%6)); + } + return; + } +} + +////// 怪物手册属性显示界面时的点击操作 ////// +actions.prototype.clickBookDetail = function () { + core.clearMap('data', 0, 0, 416, 416); + core.status.event.id = 'book'; +} + +////// 楼层传送器界面时的点击操作 ////// +actions.prototype.clickFly = function(x,y) { + if ((x==10 || x==11) && y==9) core.ui.drawFly(core.status.event.data-1); + if ((x==10 || x==11) && y==5) core.ui.drawFly(core.status.event.data+1); + if (x>=5 && x<=7 && y==12) core.ui.closePanel(); + if (x>=0 && x<=9 && y>=3 && y<=11) { + var index=core.status.hero.flyRange.indexOf(core.status.floorId); + var stair=core.status.event.data=8) { + core.ui.drawMaps(core.status.event.data-1); + } + else { + core.clearMap('data', 0, 0, 416, 416); + core.setOpacity('data', 1); + core.ui.closePanel(); + } +} + +////// 查看地图界面时,按下某个键的操作 ////// +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); + return; +} + +////// 查看地图界面时,放开某个键的操作 ////// +actions.prototype.keyUpViewMaps = function (keycode) { + if (keycode==27 || keycode==13 || keycode==32 || keycode==67) { + core.clearMap('data', 0, 0, 416, 416); + core.setOpacity('data', 1); + core.ui.closePanel(); + } + if (keycode==88) { + core.openBook(false); + } + return; +} + +////// 商店界面时的点击操作 ////// +actions.prototype.clickShop = function(x,y) { + var shop = core.status.event.data.shop; + var choices = shop.choices; + if (x >= 5 && x <= 7) { + var topIndex = 6 - parseInt(choices.length / 2); + if (y>=topIndex && y eval(use)) { + core.drawTip("你的"+use_text+"不足"); + return false; + } + + core.status.event.data.actions.push(y-topIndex); + + eval(use+'-='+need); + core.setStatus('money', money); + core.setStatus('experience', experience); + + // 更新属性 + choice.effect.split(";").forEach(function (t) { + core.doEffect(t); + }); + core.updateStatusBar(); + shop.times++; + core.events.openShop(core.status.event.data.id); + } + // 离开 + else if (y==topIndex+choices.length) { + if (core.status.event.data.actions.length>0) { + core.status.route.push("shop:"+core.status.event.data.id+":"+core.status.event.data.actions.join("")); + } + + core.status.event.data.actions = []; + core.status.boxAnimateObjs = []; + if (core.status.event.data.fromList) + core.ui.drawQuickShop(); + else core.ui.closePanel(); + } + else return false; + } + return true; +} + +////// 商店界面时,按下某个键的操作 ////// +actions.prototype.keyDownShop = function (keycode) { + if (keycode==38) { + core.status.event.selection--; + core.ui.drawChoices(core.status.event.ui.text, core.status.event.ui.choices); + } + if (keycode==40) { + core.status.event.selection++; + core.ui.drawChoices(core.status.event.ui.text, core.status.event.ui.choices); + } +} + +////// 商店界面时,放开某个键的操作 ////// +actions.prototype.keyUpShop = function (keycode) { + if (keycode==27 || keycode==88) { + if (core.status.event.data.actions.length>0) { + core.status.route.push("shop:"+core.status.event.data.id+":"+core.status.event.data.actions.join("")); + } + + core.status.event.data.actions = []; + + core.status.boxAnimateObjs = []; + + if (core.status.event.data.fromList) + core.ui.drawQuickShop(); + else + core.ui.closePanel(); + return; + } + var shop = core.status.event.data.shop; + var choices = shop.choices; + if (keycode==13 || keycode==32 || keycode==67) { + var topIndex = 6 - parseInt(choices.length / 2); + this.clickShop(6, topIndex+core.status.event.selection); + } + return; +} + +////// 快捷商店界面时的点击操作 ////// +actions.prototype.clickQuickShop = function(x, y) { + var shopList = core.status.shops, keys = Object.keys(shopList); + if (x >= 5 && x <= 7) { + var topIndex = 6 - parseInt(keys.length / 2); + if (y>=topIndex && y=10 && x<=12 && y==12) { + core.ui.closePanel(); + return; + } + if (x>=10 && x<=12 && y<=1) { + if (!core.isset(core.status.event.data)) return; + if (!core.flags.enableDeleteItem) { + core.drawTip("不支持删除道具!"); + return; + } + core.removeItem(core.status.event.data); + core.status.event.data = null; + core.ui.drawToolbox(); + return; + } + + var index=0; + if (y==4||y==5||y==9||y==10) index=parseInt(x/2); + else index=6+parseInt(x/2); + if (y>=9) index+=100; + this.clickToolboxIndex(index); +} + +////// 选择工具栏界面中某个Index后的操作 ////// +actions.prototype.clickToolboxIndex = function(index) { + var items = null; + var ii=index; + if (ii<100) + items = Object.keys(core.status.hero.items.tools).sort(); + else { + ii-=100; + items = Object.keys(core.status.hero.items.constants).sort(); + } + if (items==null) return; + if (ii>=items.length) return; + var itemId=items[ii]; + if (itemId==core.status.event.data) { + core.events.useItem(itemId); + } + else { + core.ui.drawToolbox(index); + } +} + +////// 工具栏界面时,按下某个键的操作 ////// +actions.prototype.keyDownToolbox = function (keycode) { + if (!core.isset(core.status.event.data)) return; + + var tools = Object.keys(core.status.hero.items.tools).sort(); + var constants = Object.keys(core.status.hero.items.constants).sort(); + var index=core.status.event.selection; + + if (keycode==37) { // left + if ((index>0 && index<100) || index>100) { + this.clickToolboxIndex(index-1); + return; + } + if (index==100 && tools.length>0) { + this.clickToolboxIndex(tools.length-1); + return; + } + } + if (keycode==38) { // up + if ((index>5 && index<100) || index>105) { + this.clickToolboxIndex(index-6); + return; + } + if (index>=100 && index<=105) { + if (tools.length>6) { + this.clickToolboxIndex(Math.min(tools.length-1, index-100+6)); + } + else if (tools.length>0) { + this.clickToolboxIndex(Math.min(tools.length-1, index-100)); + } + return; + } + } + if (keycode==39) { // right + if ((index=100 && index0) { + this.clickToolboxIndex(100); + return; + } + } + if (keycode==40) { // down + if (index<=5) { + if (tools.length>6) { + this.clickToolboxIndex(Math.min(tools.length-1, index+6)); + } + else if (constants.length>0) { + this.clickToolboxIndex(100+Math.min(constants.length-1, index)); + } + return; + } + if (index>5 && index<100 && constants.length>0) { + this.clickToolboxIndex(100+Math.min(constants.length-1, index-6)); + return; + } + if (index>=100 && index<=105 && constants.length>6) { + this.clickToolboxIndex(Math.min(100+constants.length-1, index+6)); + return; + } + } +} + +////// 工具栏界面时,放开某个键的操作 ////// +actions.prototype.keyUpToolbox = function (keycode) { + if (keycode==84 || keycode==27 || keycode==88) { + core.ui.closePanel(); + return; + } + if (!core.isset(core.status.event.data)) return; + + if (keycode==13 || keycode==32 || keycode==67) { + this.clickToolboxIndex(core.status.event.selection); + return; + } + + if (keycode==46) { // delete + if (!core.isset(core.status.event.data)) return; + if (!core.flags.enableDeleteItem) { + core.drawTip("不支持删除道具!"); + return; + } + core.removeItem(core.status.event.data); + core.status.event.data = null; + core.ui.drawToolbox(); + return; + } + +} + +////// 存读档界面时的点击操作 ////// +actions.prototype.clickSL = function(x,y) { + + var index=core.status.event.data; + var page = parseInt(index/10), offset=index%10; + + // 上一页 + if ((x == 3 || x == 4) && y == 12) { + core.ui.drawSLPanel(10*(page-1)+offset); + } + // 下一页 + if ((x == 8 || x == 9) && y == 12) { + core.ui.drawSLPanel(10*(page+1)+offset); + } + // 返回 + if (x>=10 && x<=12 && y==12) { + core.ui.closePanel(); + if (!core.isPlaying()) { + core.showStartAnimate(); + } + return; + } + + var index=6*page+1; + if (y>=1 && y<=4) { + if (x>=1 && x<=3) core.doSL("autoSave", core.status.event.id); + if (x>=5 && x<=7) core.doSL(5*page+1, core.status.event.id); + if (x>=9 && x<=11) core.doSL(5*page+2, core.status.event.id); + } + if (y>=7 && y<=10) { + if (x>=1 && x<=3) core.doSL(5*page+3, core.status.event.id); + if (x>=5 && x<=7) core.doSL(5*page+4, core.status.event.id); + if (x>=9 && x<=11) core.doSL(5*page+5, core.status.event.id); + } +} + +////// 存读档界面时,按下某个键的操作 ////// +actions.prototype.keyDownSL = function(keycode) { + + var index=core.status.event.data; + var page = parseInt(index/10), offset=index%10; + + if (keycode==37) { // left + if (offset==0) { + core.ui.drawSLPanel(10*(page-1) + 5); + } + else { + core.ui.drawSLPanel(index - 1); + } + return; + } + if (keycode==38) { // up + if (offset<3) { + core.ui.drawSLPanel(10*(page-1) + offset + 3); + } + else { + core.ui.drawSLPanel(index - 3); + } + return; + } + if (keycode==39) { // right + if (offset==5) { + core.ui.drawSLPanel(10*(page+1)+1); + } + else { + core.ui.drawSLPanel(index + 1); + } + return; + } + if (keycode==40) { // down + if (offset>=3) { + core.ui.drawSLPanel(10*(page+1) + offset - 3); + } + else { + core.ui.drawSLPanel(index + 3); + } + return; + } + if (keycode==33) { // PAGEUP + core.ui.drawSLPanel(10*(page-1) + offset); + return; + } + if (keycode==34) { // PAGEDOWN + core.ui.drawSLPanel(10*(page+1) + offset); + return; + } +} + +////// 存读档界面时,放开某个键的操作 ////// +actions.prototype.keyUpSL = function (keycode) { + + var index=core.status.event.data; + var page = parseInt(index/10), offset=index%10; + + if (keycode==27 || keycode==88 || (core.status.event.id == 'save' && keycode==83) || (core.status.event.id == 'load' && keycode==68)) { + core.ui.closePanel(); + if (!core.isPlaying()) { + core.showStartAnimate(); + } + return; + } + if (keycode==13 || keycode==32 || keycode==67) { + if (offset==0) { + core.doSL("autoSave", core.status.event.id); + } + else { + core.doSL(5*page+offset, core.status.event.id); + } + return; + } +} + +////// 系统设置界面时的点击操作 ////// +actions.prototype.clickSwitchs = 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 && y7) return; + var choices = core.status.event.ui.choices; + var topIndex = 6 - parseInt((choices.length - 1) / 2); + if (y>=topIndex && y0) { + text+="\n当前MAX为"+ending.max+",最早由 "+(ending.username||"匿名")+" 于"+core.formatDate(new Date(1000*ending.timestamp))+"打出。"; + } + }) + }) + core.drawText(text); + } + } + else { + core.drawText("出错啦!\n无法拉取统计信息。\n错误原因:HTTP "+xhr.status); + } + }; + xhr.ontimeout = function() { + core.drawText("出错啦!\n无法拉取统计信息。\n错误原因:Timeout"); + } + xhr.onerror = function() { + core.drawText("出错啦!\n无法拉取统计信息。\n错误原因:XHR Error"); + } + xhr.send(formData); + break; + case 6: + core.ui.drawHelp(); + break; + case 7: + core.ui.drawAbout(); + break; + case 8: + core.ui.closePanel(); + break; + } + } + return; +} + +////// 系统菜单栏界面时,按下某个键的操作 ////// +actions.prototype.keyDownSettings = function (keycode) { + if (keycode==38) { + core.status.event.selection--; + core.ui.drawChoices(core.status.event.ui.text, core.status.event.ui.choices); + } + if (keycode==40) { + core.status.event.selection++; + core.ui.drawChoices(core.status.event.ui.text, core.status.event.ui.choices); + } +} + +////// 系统菜单栏界面时,放开某个键的操作 ////// +actions.prototype.keyUpSettings = function (keycode) { + if (keycode==27 || keycode==88) { + core.ui.closePanel(); + return; + } + var choices = core.status.event.ui.choices; + if (keycode==13 || keycode==32 || keycode==67) { + var topIndex = 6 - parseInt((choices.length - 1) / 2); + this.clickSettings(6, topIndex+core.status.event.selection); + } +} + +////// 同步存档界面时的点击操作 ////// +actions.prototype.clickSyncSave = 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;i--) { + if (core.getLocalStorage("save"+i, null)==null) + index=i; + else break; + } + core.setLocalStorage("save"+index, data); + core.drawText("同步成功!\n单存档已覆盖至存档"+index); + } + }, function () { + + }); + break; + case 4: + core.download(core.firstData.name+"_"+core.formatDate2(new Date())+".h5route", JSON.stringify({ + 'name': core.firstData.name, + 'hard': core.status.hard, + 'route': core.encodeRoute(core.status.route) + })); + break; + case 5: + core.status.event.selection=1; + core.ui.drawConfirmBox("你确定要清空所有存档吗?", function() { + localStorage.clear(); + core.drawText("\t[操作成功]你的所有存档已被清空。"); + }, function() { + core.status.event.selection=5; + core.ui.drawSyncSave(); + }) + break; + case 6: + core.status.event.selection=3; + core.ui.drawSettings(); + break; + + } + } + return; +} + +////// 同步存档界面时,按下某个键的操作 ////// +actions.prototype.keyDownSyncSave = function (keycode) { + if (keycode==38) { + core.status.event.selection--; + core.ui.drawChoices(core.status.event.ui.text, core.status.event.ui.choices); + } + if (keycode==40) { + core.status.event.selection++; + core.ui.drawChoices(core.status.event.ui.text, core.status.event.ui.choices); + } +} + +////// 同步存档界面时,放开某个键的操作 ////// +actions.prototype.keyUpSyncSave = function (keycode) { + if (keycode==27 || keycode==88) { + core.status.event.selection=2; + core.ui.drawSettings(); + return; + } + var choices = core.status.event.ui.choices; + if (keycode==13 || keycode==32 || keycode==67) { + var topIndex = 6 - parseInt((choices.length - 1) / 2); + this.clickSyncSave(6, topIndex+core.status.event.selection); + } +} + +////// 同步存档选择界面时的点击操作 ////// +actions.prototype.clickSyncSelect = 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 && y7) return; + var choices = core.status.event.ui.choices; + + var topIndex = 6 - parseInt((choices.length - 1) / 2); + + var saves=null; + + if (y>=topIndex && y=1;i--) { + saves=core.getLocalStorage("save"+i, null); + if (core.isset(saves)) { + break; + } + } + break; + case 2: + break; + } + } + if (core.isset(saves)) { + var content = { + "name": core.firstData.name, + "version": core.firstData.version, + "data": saves + } + core.download(core.firstData.name+"_"+core.formatDate2(new Date())+".h5save", JSON.stringify(content)); + } + core.status.event.selection=2; + core.ui.drawSyncSave(); +} + +////// 存档下载界面时,按下某个键的操作 ////// +actions.prototype.keyDownLocalSaveSelect = function (keycode) { + if (keycode==38) { + core.status.event.selection--; + core.ui.drawChoices(core.status.event.ui.text, core.status.event.ui.choices); + } + if (keycode==40) { + core.status.event.selection++; + core.ui.drawChoices(core.status.event.ui.text, core.status.event.ui.choices); + } +} + +////// 存档下载界面时,放开某个键的操作 ////// +actions.prototype.keyUpLocalSaveSelect = function (keycode) { + if (keycode==27 || keycode==88) { + core.status.event.selection=0; + core.ui.drawSettings(); + return; + } + var choices = core.status.event.ui.choices; + if (keycode==13 || keycode==32 || keycode==67) { + var topIndex = 6 - parseInt((choices.length - 1) / 2); + this.clickLocalSaveSelect(6, topIndex+core.status.event.selection); + } +} + +////// “虚拟键盘”界面时的点击操作 ////// +actions.prototype.clickKeyBoard = function (x, y) { + if (y==3 && x>=1 && x<=11) { + core.ui.closePanel(); + core.keyUp(112+x-1); // F1-F12: 112-122 + } + if (y==4 && x>=1 && x<=10) { + core.ui.closePanel(); + core.keyUp(x==10?48:48+x); // 1-9: 49-57; 0: 48 + } + // 字母 + var lines = [ + ["Q","W","E","R","T","Y","U","I","O","P"], + ["A","S","D","F","G","H","J","K","L"], + ["Z","X","C","V","B","N","M"], + ]; + if (y==5 && x>=1 && x<=10) { + core.ui.closePanel(); + core.keyUp(lines[0][x-1].charCodeAt(0)); + } + if (y==6 && x>=1 && x<=9) { + core.ui.closePanel(); + core.keyUp(lines[1][x-1].charCodeAt(0)); + } + if (y==7 && x>=1 && x<=7) { + core.ui.closePanel(); + core.keyUp(lines[2][x-1].charCodeAt(0)); + } + if (y==8 && x>=1 && x<=11) { + core.ui.closePanel(); + if (x==1) core.keyUp(189); // - + if (x==2) core.keyUp(187); // = + if (x==3) core.keyUp(219); // [ + if (x==4) core.keyUp(221); // ] + if (x==5) core.keyUp(220); // \ + if (x==6) core.keyUp(186); // ; + if (x==7) core.keyUp(222); // ' + if (x==8) core.keyUp(188); // , + if (x==9) core.keyUp(190); // . + if (x==10) core.keyUp(191); // / + if (x==11) core.keyUp(192); // ` + } + if (y==9 && x>=1 && x<=10) { + core.ui.closePanel(); + if (x==1) core.keyUp(27); // ESC + if (x==2) core.keyUp(9); // TAB + if (x==3) core.keyUp(20); // CAPS + if (x==4) core.keyUp(16); // SHIFT + if (x==5) core.keyUp(17); // CTRL + if (x==6) core.keyUp(18); // ALT + if (x==7) core.keyUp(32); // SPACE + if (x==8) core.keyUp(8); // BACKSPACE + if (x==9) core.keyUp(13); // ENTER + if (x==10) core.keyUp(46); // DEL + } + if (y==10 && x>=9 && x<=11) + core.ui.closePanel(); +} + +////// 光标界面时的点击操作 ////// +actions.prototype.clickCursor = function (x,y) { + + if (x==core.status.automaticRoute.cursorX && y==core.status.automaticRoute.cursorY) { + core.ui.closePanel(); + core.onclick(x,y,[]); + return; + } + core.status.automaticRoute.cursorX=x; + core.status.automaticRoute.cursorY=y; + core.ui.drawCursor(); +} + +////// 光标界面时,按下某个键的操作 ////// +actions.prototype.keyDownCursor = function (keycode) { + if (keycode==37) { // left + core.status.automaticRoute.cursorX--; + core.ui.drawCursor(); + return; + } + if (keycode==38) { // up + core.status.automaticRoute.cursorY--; + core.ui.drawCursor(); + return; + } + if (keycode==39) { // right + core.status.automaticRoute.cursorX++; + core.ui.drawCursor(); + return; + } + if (keycode==40) { // down + core.status.automaticRoute.cursorY++; + core.ui.drawCursor(); + return; + } +} + +////// 光标界面时,放开某个键的操作 ////// +actions.prototype.keyUpCursor = function (keycode) { + if (keycode==27 || keycode==88) { + core.ui.closePanel(); + return; + } + if (keycode==13 || keycode==32 || keycode==67 || keycode==69) { + core.ui.closePanel(); + core.onclick(core.status.automaticRoute.cursorX, core.status.automaticRoute.cursorY, []); + return; + } +} + +////// “关于”界面时的点击操作 ////// +actions.prototype.clickAbout = function () { + if (core.isPlaying()) + core.ui.closePanel(); + else + core.restart(); +} diff --git a/libs/control.js b/libs/control.js new file mode 100644 index 00000000..7beac62f --- /dev/null +++ b/libs/control.js @@ -0,0 +1,2482 @@ +/* +control.js:游戏主要逻辑控制 +主要负责status相关内容,以及各种变量获取/存储 +寻路算法和人物行走也在此文件内 + */ + +function control() { + this.init(); +} + +control.prototype.init = function () { + +} + +////// 设置requestAnimationFrame ////// +control.prototype.setRequestAnimationFrame = function () { + + (function() { + var lastTime = 0; + var vendors = ['webkit', 'moz']; + for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) { + window.requestAnimationFrame = window[vendors[x] + 'RequestAnimationFrame']; + window.cancelAnimationFrame = window[vendors[x] + 'CancelAnimationFrame'] || // Webkit中此取消方法的名字变了 + window[vendors[x] + 'CancelRequestAnimationFrame']; + } + + if (!window.requestAnimationFrame) { + window.requestAnimationFrame = function(callback, element) { + var currTime = new Date().getTime(); + var timeToCall = Math.max(0, 16.7 - (currTime - lastTime)); + var id = window.setTimeout(function() { + callback(currTime + timeToCall); + }, timeToCall); + lastTime = currTime + timeToCall; + return id; + }; + } + if (!window.cancelAnimationFrame) { + window.cancelAnimationFrame = function(id) { + clearTimeout(id); + }; + } + }()); + + core.animateFrame.speed = core.values.animateSpeed; + core.animateFrame.background = core.canvas.ui.createPattern(core.material.ground, "repeat"); + + var scan = { + 'up': {'x': 0, 'y': -1}, + 'left': {'x': -1, 'y': 0}, + 'down': {'x': 0, 'y': 1}, + 'right': {'x': 1, 'y': 0} + }; + + var draw = function(timestamp) { + + core.animateFrame.twoTime = core.animateFrame.twoTime||timestamp; + core.animateFrame.fourTime = core.animateFrame.fourTime||timestamp; + core.animateFrame.boxTime = core.animateFrame.boxTime||timestamp; + core.animateFrame.moveTime = core.animateFrame.moveTime||timestamp; + core.animateFrame.weather.time = core.animateFrame.weather.time||timestamp; + + // Global Animate + if (core.animateFrame.globalAnimate && core.isPlaying()) { + + if (timestamp-core.animateFrame.twoTime>core.animateFrame.speed && core.isset(core.status.twoAnimateObjs)) { + + for (var a = 0; a < core.status.twoAnimateObjs.length; a++) { + var obj = core.status.twoAnimateObjs[a]; + obj.status = (obj.status+1)%2; + core.canvas.event.clearRect(obj.x, obj.y, 32, 32); + core.canvas.event.drawImage(obj.image, obj.status * 32, obj.loc * 32, 32, 32, obj.x, obj.y, 32, 32); + } + + core.animateFrame.twoTime = timestamp; + } + + if (timestamp-core.animateFrame.fourTime>core.animateFrame.speed/2 && core.isset(core.status.fourAnimateObjs)) { + for (var a = 0; a < core.status.fourAnimateObjs.length; a++) { + var obj=core.status.fourAnimateObjs[a]; + obj.status = (obj.status+1)%4; + core.canvas.event.clearRect(obj.x, obj.y, 32, 32); + core.canvas.event.drawImage(obj.image, obj.status * 32, obj.loc * 32, 32, 32, obj.x, obj.y, 32, 32); + } + // fourtime = timestamp % fourDelta; + core.animateFrame.fourTime = timestamp; + } + + } + + // Box + if (timestamp-core.animateFrame.boxTime>core.animateFrame.speed && core.isset(core.status.boxAnimateObjs) && core.status.boxAnimateObjs.length>0) { + core.drawBoxAnimate(); + core.animateFrame.boxTime = timestamp; + } + + // Hero move + if (timestamp-core.animateFrame.moveTime>16 && core.isset(core.status.heroMoving) && core.status.heroMoving>0) { + var x=core.getHeroLoc('x'), y=core.getHeroLoc('y'), direction = core.getHeroLoc('direction'); + if (core.status.heroMoving<=4) { + core.drawHero(direction, x, y, 'leftFoot', 4*core.status.heroMoving*scan[direction].x, 4*core.status.heroMoving*scan[direction].y); + } + else if (core.status.heroMoving<=8) { + core.drawHero(direction, x, y, 'rightFoot', 4*core.status.heroMoving*scan[direction].x, 4*core.status.heroMoving*scan[direction].y); + } + core.animateFrame.moveTime = timestamp; + } + + // weather + if (core.isPlaying() && timestamp-core.animateFrame.weather.time>30) { + if (core.animateFrame.weather.type == 'rain' && core.animateFrame.weather.level > 0) { + + core.clearMap('weather', 0, 0, 416, 416); + + core.canvas.weather.strokeStyle = 'rgba(174,194,224,0.8)'; + core.canvas.weather.lineWidth = 1; + core.canvas.weather.lineCap = 'round'; + + core.animateFrame.weather.nodes.forEach(function (p) { + core.canvas.weather.beginPath(); + core.canvas.weather.moveTo(p.x, p.y); + core.canvas.weather.lineTo(p.x + p.l * p.xs, p.y + p.l * p.ys); + core.canvas.weather.stroke(); + + p.x += p.xs; + p.y += p.ys; + if (p.x > 416 || p.y > 416) { + p.x = Math.random() * 416; + p.y = -10; + } + + }) + + core.canvas.weather.fill(); + + } + else if (core.animateFrame.weather.type == 'snow' && core.animateFrame.weather.level > 0) { + + core.clearMap('weather', 0, 0, 416, 416); + + core.canvas.weather.fillStyle = "rgba(255, 255, 255, 0.8)"; + core.canvas.weather.beginPath(); + + if (!core.isset(core.animateFrame.weather.data)) + core.animateFrame.weather.data = 0; + core.animateFrame.weather.data += 0.01; + + var angle = core.animateFrame.weather.data; + core.animateFrame.weather.nodes.forEach(function (p) { + core.canvas.weather.moveTo(p.x, p.y); + core.canvas.weather.arc(p.x, p.y, p.r, 0, Math.PI * 2, true); + + // update + p.x += Math.sin(angle) * 2; + p.y += Math.cos(angle + p.d) + 1 + p.r / 2; + + if (p.x > 416 + 5 || p.x < -5 || p.y > 416) { + if (Math.random() > 1 / 3) { + p.x = Math.random() * 416; + p.y = -10; + } + else { + if (Math.sin(angle) > 0) { + p.x = -5; + p.y = Math.random() * 416; + } + else { + p.x = 416 + 5; + p.y = Math.random() * 416; + } + } + } + + }) + + core.canvas.weather.fill(); + + } + core.animateFrame.weather.time = timestamp; + + } + window.requestAnimationFrame(draw); + } + window.requestAnimationFrame(draw); +} + +////// 显示游戏开始界面 ////// +control.prototype.showStartAnimate = function (callback) { + core.dom.startPanel.style.opacity=1; + core.dom.startPanel.style.display="block"; + core.dom.startTop.style.opacity=1; + core.dom.startTop.style.display="block"; + core.dom.startButtonGroup.style.display = 'none'; + core.dom.startButtons.style.display = 'block'; + core.dom.levelChooseButtons.style.display = 'none'; + core.dom.curtain.style.background = "#000000"; + core.dom.curtain.style.opacity = 0; + core.status.played = false; + core.clearStatus(); + core.clearMap('all'); + + var opacityVal = 1; + var startAnimate = window.setInterval(function () { + opacityVal -= 0.03; + if (opacityVal < 0) { + clearInterval(startAnimate); + core.dom.startTop.style.display = 'none'; + // core.playGame(); + core.dom.startButtonGroup.style.display = 'block'; + if (core.isset(callback)) callback(); + } + core.dom.startTop.style.opacity = opacityVal; + }, 20); +} + +////// 隐藏游戏开始界面 ////// +control.prototype.hideStartAnimate = function (callback) { + var opacityVal = 1; + var startAnimate = window.setInterval(function () { + opacityVal -= 0.03; + if (opacityVal < 0) { + clearInterval(startAnimate); + core.dom.startPanel.style.display = 'none'; + if (core.isset(callback)) callback(); + } + core.dom.startPanel.style.opacity = opacityVal; + }, 20); +} + +////// 游戏是否已经开始 ////// +control.prototype.isPlaying = function() { + return core.isset(core.status.played) && core.status.played; +} + +////// 清除游戏状态和数据 ////// +control.prototype.clearStatus = function() { + // 停止各个Timeout和Interval + for (var i in core.timeout) { + clearTimeout(core.timeout[i]); + core.timeout[i] = null; + } + for (var i in core.interval) { + clearInterval(core.interval[i]); + core.interval[i] = null; + } + core.status = {}; + core.clearStatusBar(); + core.resize(main.dom.body.clientWidth, main.dom.body.clientHeight); +} + +////// 重置游戏状态和初始数据 ////// +control.prototype.resetStatus = function(hero, hard, floorId, route, maps) { + + this.clearStatus(); + + // 初始化status + core.status = core.clone(core.initStatus); + core.status.played = true; + // 初始化maps + core.status.floorId = floorId; + core.status.maps = core.clone(maps); + // 初始化怪物 + core.material.enemys = core.clone(core.enemys.getEnemys()); + // 初始化人物属性 + core.status.hero = core.clone(hero); + core.status.hard = hard; + // 初始化路线 + if (core.isset(route)) + core.status.route = route; + // 保存的Index + core.status.saveIndex = core.getLocalStorage('saveIndex2', 1); + +} + +////// 开始游戏 ////// +control.prototype.startGame = function (hard, callback) { + console.log('开始游戏'); + + this.resetStatus(core.firstData.hero, hard, core.firstData.floorId, null, core.initStatus.maps); + + core.changeFloor(core.status.floorId, null, core.firstData.hero.loc, null, function() { + if (core.isset(callback)) callback(); + }); + + setTimeout(function () { + // Upload + var formData = new FormData(); + formData.append('type', 'people'); + formData.append('name', core.firstData.name); + formData.append('version', core.firstData.version); + formData.append('platform', core.platform.isPC?"PC":core.platform.isAndroid?"Android":core.platform.isIOS?"iOS":""); + formData.append('hard', hard); + formData.append('hardCode', core.getFlag('hard', 0)); + + core.utils.http("POST", "/games/upload.php", formData); + }) + +} + +////// 重新开始游戏;此函数将回到标题页面 ////// +control.prototype.restart = function() { + this.showStartAnimate(); +} + + + + + + +/////////////////////// 寻路算法 & 人物行走控制 /////////////////////// + +////// 清除自动寻路路线 ////// +control.prototype.clearAutomaticRouteNode = function (x, y) { + if (core.status.event.id==null) + core.canvas.ui.clearRect(x * 32 + 5, y * 32 + 5, 27, 27); +} + +////// 停止自动寻路操作 ////// +control.prototype.stopAutomaticRoute = function () { + if (!core.status.played) { + return; + } + core.status.automaticRoute.autoHeroMove = false; + core.status.automaticRoute.autoStep = 0; + core.status.automaticRoute.destStep = 0; + core.status.automaticRoute.movedStep = 0; + core.status.automaticRoute.autoStepRoutes = []; + core.status.automaticRoute.destX=null; + core.status.automaticRoute.destY=null; + core.status.automaticRoute.lastDirection = null; + core.stopHero(); + if (core.status.automaticRoute.moveStepBeforeStop.length==0) + core.canvas.ui.clearRect(0, 0, 416, 416); +} + +////// 继续剩下的自动寻路操作 ////// +control.prototype.continueAutomaticRoute = function () { + // 此函数只应由events.afterOpenDoor和events.afterBattle调用 + var moveStep = core.status.automaticRoute.moveStepBeforeStop; + //core.status.automaticRoute.moveStepBeforeStop = []; + if(moveStep.length===0 || (moveStep.length===1 && moveStep[0].step===1)) { + core.status.automaticRoute.moveStepBeforeStop = []; + } + else { + core.setAutoHeroMove(moveStep); + } +} + +////// 清空剩下的自动寻路列表 ////// +control.prototype.clearContinueAutomaticRoute = function () { + core.canvas.ui.clearRect(0, 0, 416, 416); + core.status.automaticRoute.moveStepBeforeStop=[]; +} + +////// 设置自动寻路路线 ////// +control.prototype.setAutomaticRoute = function (destX, destY, stepPostfix) { + if (!core.status.played || core.status.lockControl) { + return; + } + // 正在寻路中 + if (core.status.automaticRoute.autoHeroMove) { + var lastX = core.status.automaticRoute.destX, lastY=core.status.automaticRoute.destY; + core.stopAutomaticRoute(); + if (lastX==destX && lastY==destY) { + core.status.automaticRoute.moveDirectly = true; + setTimeout(function () { + if (core.status.automaticRoute.moveDirectly && core.status.heroMoving==0) { + if (core.canMoveDirectly(destX, destY)) { + 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.status.route.push("move:"+destX+":"+destY); + } + } + core.status.automaticRoute.moveDirectly = false; + }, 100); + } + return; + } + if (destX == core.status.hero.loc.x && destY == core.status.hero.loc.y && stepPostfix.length==0) { + if (core.timeout.turnHeroTimeout==null) { + core.timeout.turnHeroTimeout = setTimeout(function() { + core.turnHero(); + clearTimeout(core.timeout.turnHeroTimeout); + core.timeout.turnHeroTimeout = null; + }, 250); + } + else { + clearTimeout(core.timeout.turnHeroTimeout); + core.timeout.turnHeroTimeout = null; + core.getNextItem(); + } + return; + } + var step = 0; + var tempStep = null; + var moveStep; + if (!(moveStep = core.automaticRoute(destX, destY))) { + if (destX == core.status.hero.loc.x && destY == core.status.hero.loc.y){ + moveStep=[]; + } else { + core.canvas.ui.clearRect(0, 0, 416, 416); + return; + } + } + moveStep=moveStep.concat(stepPostfix); + core.status.automaticRoute.destX=destX; + core.status.automaticRoute.destY=destY; + core.canvas.ui.save(); + core.canvas.ui.clearRect(0, 0, 416, 416); + core.canvas.ui.fillStyle = '#bfbfbf'; + core.canvas.ui.strokeStyle = '#bfbfbf'; + core.canvas.ui.lineWidth = 8; + for (var m = 0; m < moveStep.length; m++) { + if (tempStep == null) { + step++; + tempStep = moveStep[m].direction; + } + else if (tempStep == moveStep[m].direction) { + step++; + } + else { + //core.status.automaticRoutingTemp.moveStep.push({'direction': tempStep, 'step': step}); + core.status.automaticRoute.autoStepRoutes.push({'direction': tempStep, 'step': step}); + step = 1; + tempStep = moveStep[m].direction; + } + if (m == moveStep.length - 1) { + // core.status.automaticRoutingTemp.moveStep.push({'direction': tempStep, 'step': step}); + core.status.automaticRoute.autoStepRoutes.push({'direction': tempStep, 'step': step}); + core.canvas.ui.fillRect(moveStep[m].x * 32 + 10, moveStep[m].y * 32 + 10, 12, 12); + } + else { + core.canvas.ui.beginPath(); + if (core.isset(moveStep[m + 1]) && tempStep != moveStep[m + 1].direction) { + if (tempStep == 'up' && moveStep[m + 1].direction == 'left' || tempStep == 'right' && moveStep[m + 1].direction == 'down') { + core.canvas.ui.moveTo(moveStep[m].x * 32 + 5, moveStep[m].y * 32 + 16); + core.canvas.ui.lineTo(moveStep[m].x * 32 + 16, moveStep[m].y * 32 + 16); + core.canvas.ui.lineTo(moveStep[m].x * 32 + 16, moveStep[m].y * 32 + 27); + } + else if (tempStep == 'up' && moveStep[m + 1].direction == 'right' || tempStep == 'left' && moveStep[m + 1].direction == 'down') { + core.canvas.ui.moveTo(moveStep[m].x * 32 + 27, moveStep[m].y * 32 + 16); + core.canvas.ui.lineTo(moveStep[m].x * 32 + 16, moveStep[m].y * 32 + 16); + core.canvas.ui.lineTo(moveStep[m].x * 32 + 16, moveStep[m].y * 32 + 27); + } + else if (tempStep == 'left' && moveStep[m + 1].direction == 'up' || tempStep == 'down' && moveStep[m + 1].direction == 'right') { + core.canvas.ui.moveTo(moveStep[m].x * 32 + 27, moveStep[m].y * 32 + 16); + core.canvas.ui.lineTo(moveStep[m].x * 32 + 16, moveStep[m].y * 32 + 16); + core.canvas.ui.lineTo(moveStep[m].x * 32 + 16, moveStep[m].y * 32 + 5); + } + else if (tempStep == 'right' && moveStep[m + 1].direction == 'up' || tempStep == 'down' && moveStep[m + 1].direction == 'left') { + core.canvas.ui.moveTo(moveStep[m].x * 32 + 5, moveStep[m].y * 32 + 16); + core.canvas.ui.lineTo(moveStep[m].x * 32 + 16, moveStep[m].y * 32 + 16); + core.canvas.ui.lineTo(moveStep[m].x * 32 + 16, moveStep[m].y * 32 + 5); + } + core.canvas.ui.stroke(); + continue; + } + switch (tempStep) { + case 'up': + case 'down': + core.canvas.ui.beginPath(); + core.canvas.ui.moveTo(moveStep[m].x * 32 + 16, moveStep[m].y * 32 + 5); + core.canvas.ui.lineTo(moveStep[m].x * 32 + 16, moveStep[m].y * 32 + 27); + core.canvas.ui.stroke(); + break; + case 'left': + case 'right': + core.canvas.ui.beginPath(); + core.canvas.ui.moveTo(moveStep[m].x * 32 + 5, moveStep[m].y * 32 + 16); + core.canvas.ui.lineTo(moveStep[m].x * 32 + 27, moveStep[m].y * 32 + 16); + core.canvas.ui.stroke(); + break; + } + } + } + core.canvas.ui.restore(); + + // 立刻移动 + core.setAutoHeroMove(); + +} + +////// 自动寻路算法,找寻最优路径 ////// +control.prototype.automaticRoute = function (destX, destY) { + var startX = core.getHeroLoc('x'); + var startY = core.getHeroLoc('y'); + var scan = { + 'up': {'x': 0, 'y': -1}, + 'left': {'x': -1, 'y': 0}, + 'down': {'x': 0, 'y': 1}, + 'right': {'x': 1, 'y': 0} + }; + var queue = []; + var nowDeep = 0; + var route = []; + var ans = [] + + if (destX == startX && destY == startY) return false; + queue.push(13 * startX + startY); + queue.push(-1); + route[13 * startX + startY] = ''; + + while (queue.length != 1) { + var f = queue.shift(); + if (f===-1) {nowDeep+=1;queue.push(-1);continue;} + var deep = ~~(f/169); + if (deep!==nowDeep) {queue.push(f);continue;} + f=f%169; + var nowX = parseInt(f / 13), nowY = f % 13; + var nowIsArrow = false, nowId, nowBlock = core.getBlock(nowX,nowY); + for (var direction in scan) { + if (!core.canMoveHero(nowX, nowY, direction)) + continue; + + var nx = nowX + scan[direction].x; + var ny = nowY + scan[direction].y; + + if (nx<0 || nx>12 || ny<0 || ny>12) continue; + + var nid = 13 * nx + ny; + + if (core.isset(route[nid])) continue; + + var deepAdd=1; + + var nextId, nextBlock = core.getBlock(nx,ny); + if (nextBlock!=null){ + nextId = nextBlock.block.event.id; + // 绕过亮灯(因为只有一次通行机会很宝贵) + if(nextId == "light") deepAdd=100; + // 绕过路障 + if (nextId.substring(nextId.length-3)=="Net") deepAdd=core.values.lavaDamage; + // 绕过血瓶 + if (!core.flags.potionWhileRouting && nextId.substring(nextId.length-6)=="Potion") deepAdd=20; + // 绕过传送点 + if (nextBlock.block.event.trigger == 'changeFloor') deepAdd = 10; + } + if (core.status.checkBlock.damage[nid]>0) + deepAdd = core.status.checkBlock.damage[nid]; + + if (nx == destX && ny == destY) { + route[nid] = direction; + break; + } + if (core.noPassExists(nx, ny)) + continue; + + route[nid] = direction; + queue.push(169*(nowDeep+deepAdd)+nid); + } + if (core.isset(route[13 * destX + destY])) break; + } + + if (!core.isset(route[13 * destX + destY])) { + return false; + } + + var nowX = destX, nowY = destY; + while (nowX != startX || nowY != startY) { + var dir = route[13 * nowX + nowY]; + ans.push({'direction': dir, 'x': nowX, 'y': nowY}); + nowX -= scan[dir].x; + nowY -= scan[dir].y; + } + + ans.reverse(); + return ans; +} + +////// 显示离散的寻路点 ////// +control.prototype.fillPosWithPoint = function (pos) { + core.fillRect('ui', pos.x*32+12,pos.y*32+12,8,8, '#bfbfbf'); +} + +////// 设置勇士的自动行走路线 ////// +control.prototype.setAutoHeroMove = function (steps) { + steps=steps||core.status.automaticRoute.autoStepRoutes; + if (steps.length == 0) { + return; + } + core.status.automaticRoute.autoStepRoutes=steps; + core.status.automaticRoute.autoHeroMove = true; + core.status.automaticRoute.autoStep = 1; + core.status.automaticRoute.destStep = steps[0].step; + core.moveHero(steps[0].direction); +} + +////// 设置行走的效果动画 ////// +control.prototype.setHeroMoveInterval = function (direction, x, y, callback) { + if (core.status.heroMoving>0) { + return; + } + core.status.heroMoving=1; + var scan = { + 'up': {'x': 0, 'y': -1}, + 'left': {'x': -1, 'y': 0}, + 'down': {'x': 0, 'y': 1}, + 'right': {'x': 1, 'y': 0} + }; + core.interval.heroMoveInterval = window.setInterval(function () { + core.status.heroMoving++; + if (core.status.heroMoving==8) { + core.setHeroLoc('x', x+scan[direction].x); + 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'); + clearInterval(core.interval.heroMoveInterval); + core.status.heroMoving = 0; + if (core.isset(callback)) callback(); + } + }, 12.5 / core.status.replay.speed); +} + +////// 实际每一步的行走过程 ////// +control.prototype.moveAction = function (callback) { + if (core.interval.openDoorAnimate!=null) return; // 开门判断 + if (core.status.heroMoving>0) return; + var scan = { + 'up': {'x': 0, 'y': -1}, + 'left': {'x': -1, 'y': 0}, + 'down': {'x': 0, 'y': 1}, + 'right': {'x': 1, 'y': 0} + }; + var direction = core.getHeroLoc('direction'); + var x = core.getHeroLoc('x'); + var y = core.getHeroLoc('y'); + var noPass = core.noPass(x + scan[direction].x, y + scan[direction].y), canMove = core.canMoveHero(); + if (noPass || !canMove) { + if (core.status.event.id!='ski') + core.status.route.push(direction); + core.status.automaticRoute.moveStepBeforeStop = []; + if (canMove) // 非箭头:触发 + core.trigger(x + scan[direction].x, y + scan[direction].y); + core.drawHero(direction, x, y, 'stop'); + + if (core.status.automaticRoute.moveStepBeforeStop.length==0) { + core.clearContinueAutomaticRoute(); + core.stopAutomaticRoute(); + } + if (core.isset(callback)) + callback(); + } + else { + core.setHeroMoveInterval(direction, x, y, function () { + if (core.status.automaticRoute.autoHeroMove) { + core.status.automaticRoute.movedStep++; + core.status.automaticRoute.lastDirection = core.getHeroLoc('direction'); + if (core.status.automaticRoute.destStep == core.status.automaticRoute.movedStep) { + if (core.status.automaticRoute.autoStep == core.status.automaticRoute.autoStepRoutes.length) { + core.clearContinueAutomaticRoute(); + core.stopAutomaticRoute(); + } + else { + core.status.automaticRoute.movedStep = 0; + core.status.automaticRoute.destStep = core.status.automaticRoute.autoStepRoutes[core.status.automaticRoute.autoStep].step; + core.setHeroLoc('direction', core.status.automaticRoute.autoStepRoutes[core.status.automaticRoute.autoStep].direction); + core.status.automaticRoute.autoStep++; + } + } + } + else if (core.status.heroStop) { + core.drawHero(core.getHeroLoc('direction'), core.getHeroLoc('x'), core.getHeroLoc('y'), 'stop'); + } + if (core.status.event.id!='ski') + core.status.route.push(direction); + core.trigger(core.getHeroLoc('x'), core.getHeroLoc('y')); + core.checkBlock(); + if (core.isset(callback)) callback(); + }); + } +} + +////// 转向 ////// +control.prototype.turnHero = function() { + if (core.status.hero.loc.direction == 'up') core.status.hero.loc.direction = 'right'; + 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.canvas.ui.clearRect(0, 0, 416, 416); + core.status.route.push("turn"); +} + +////// 让勇士开始移动 ////// +control.prototype.moveHero = function (direction, callback) { + // 如果正在移动,直接return + if (core.status.heroMoving>0) return; + if (core.isset(direction)) + core.setHeroLoc('direction', direction); + if (!core.isset(callback)) { // 如果不存在回调函数,则使用heroMoveTrigger + core.status.heroStop = false; + core.status.automaticRoute.moveDirectly = false; + + var doAction = function () { + if (!core.status.heroStop) { + core.moveAction(); + setTimeout(doAction, 50); + } + else { + core.stopHero(); + } + } + doAction(); + } + else { // 否则,只向某个方向移动一步,然后调用callback + core.moveAction(function () { + callback(); + }) + } +} + +/////// 使用事件让勇士移动。这个函数将不会触发任何事件 ////// +control.prototype.eventMoveHero = function(steps, time, callback) { + + time = time || 100; + + core.clearMap('ui', 0, 0, 416, 416); + core.setAlpha('ui', 1.0); + + // 要运行的轨迹:将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;i12 || ny<0 || ny>12) continue; + if (!zoneSquare && Math.abs(dx)+Math.abs(dy)>range) continue; + core.status.checkBlock.damage[13*nx+ny]+=enemy.value; + } + } + } + // 存在阻击 + if (core.enemys.hasSpecial(enemy.special, 18)) { + for (var dx=-1;dx<=1;dx++) { + for (var dy=-1;dy<=1;dy++) { + if (dx==0 && dy==0) continue; + var nx=x+dx, ny=y+dy; + if (nx<0 || nx>12 || ny<0 || ny>12 || Math.abs(dx)+Math.abs(dy)>1) continue; + core.status.checkBlock.damage[13*nx+ny]+=enemy.value; + } + } + } + } + } + } + + + // Step3: 更新夹击点坐标,并将夹击伤害加入到damage中 + core.status.checkBlock.betweenAttack = []; // 记录(x,y)点是否有夹击 + for (var x=0;x<13;x++) { + for (var y=0;y<13;y++) { + var has=false; + if (x>0 && x<12) { + var id1=core.status.checkBlock.map[13*(x-1)+y], + id2=core.status.checkBlock.map[13*(x+1)+y]; + if (core.isset(id1) && core.isset(id2) && id1==id2) { + var enemy = core.enemys.getEnemys(id1); + if (core.enemys.hasSpecial(enemy.special, 16)) { + has = true; + } + } + } + if (y>0 && y<12) { + var id1=core.status.checkBlock.map[13*x+y-1], + id2=core.status.checkBlock.map[13*x+y+1]; + if (core.isset(id1) && core.isset(id2) && id1==id2) { + var enemy = core.enemys.getEnemys(id1); + if (core.enemys.hasSpecial(enemy.special, 16)) { + has = true; + } + } + } + // 存在夹击 + if (has) { + core.status.checkBlock.betweenAttack[13*x+y]=true; + var leftHp = core.status.hero.hp - core.status.checkBlock.damage[13*x+y]; + if (leftHp>1) + core.status.checkBlock.damage[13*x+y] += parseInt((leftHp+(core.flags.betweenAttackCeil?0:1))/2); + } + } + } +} + +////// 检查并执行领域、夹击、阻击事件 ////// +control.prototype.checkBlock = function () { + var x=core.getHeroLoc('x'), y=core.getHeroLoc('y'); + var damage = core.status.checkBlock.damage[13*x+y]; + if (damage>0) { + core.status.hero.hp -= damage; + + // 检查阻击事件 + var snipe = []; + var scan = { + 'up': {'x': 0, 'y': -1}, + 'left': {'x': -1, 'y': 0}, + 'down': {'x': 0, 'y': 1}, + 'right': {'x': 1, 'y': 0} + } + for (var direction in scan) { + var nx = x+scan[direction].x, ny=y+scan[direction].y; + if (nx<0 || nx>12 || ny<0 || ny>12) continue; + var id=core.status.checkBlock.map[13*nx+ny]; + if (core.isset(id)) { + var enemy = core.enemys.getEnemys(id); + if (core.isset(enemy) && core.enemys.hasSpecial(enemy.special, 18)) { + snipe.push({'direction': direction, 'x': nx, 'y': ny}); + } + } + } + + if (core.status.checkBlock.betweenAttack[13*x+y] && damage>0) { + core.drawTip('受到夹击,生命变成一半'); + } + // 阻击 + else if (snipe.length>0 && damage>0) { + core.drawTip('受到阻击伤害'+damage+'点'); + } + else if (damage>0) { + core.drawTip('受到领域伤害'+damage+'点'); + } + + core.playSound('zone.ogg'); + core.drawAnimate("zone", x, y); + + if (core.status.hero.hp<=0) { + core.status.hero.hp=0; + core.updateStatusBar(); + core.events.lose('zone'); + return; + } + snipe = snipe.filter(function (t) { + var x=t.x, y=t.y, direction = t.direction; + var nx = x+scan[direction].x, ny=y+scan[direction].y; + + return nx>=0 && nx<=12 && ny>=0 && ny<=12 && core.getBlock(nx, ny, core.status.floorId, false)==null; + }); + core.updateStatusBar(); + if (snipe.length>0) + core.snipe(snipe); + } +} + +////// 阻击事件(动画效果) ////// +control.prototype.snipe = function (snipes) { + + var scan = { + 'up': {'x': 0, 'y': -1}, + 'left': {'x': -1, 'y': 0}, + 'down': {'x': 0, 'y': 1}, + 'right': {'x': 1, 'y': 0} + }; + + snipes.forEach(function (snipe) { + var x=snipe.x, y=snipe.y, direction = snipe.direction; + snipe.nx = x+scan[snipe.direction].x; + snipe.ny = y+scan[snipe.direction].y; + + core.removeGlobalAnimate(x, y); + + var block = core.getBlock(x,y).block; + + snipe.blockIcon = core.material.icons[block.event.cls][block.event.id]; + snipe.blockImage = core.material.images[block.event.cls]; + var damage = core.enemys.getDamage(block.event.id); + + var color = "#000000"; + if (damage <= 0) color = '#00FF00'; + else if (damage < core.status.hero.hp / 3) color = '#FFFFFF'; + else if (damage < core.status.hero.hp * 2 / 3) color = '#FFFF00'; + else if (damage < core.status.hero.hp) color = '#FF7F00'; + else color = '#FF0000'; + + if (damage >= 999999999) damage = "???"; + else if (damage > 100000) damage = (damage / 10000).toFixed(1) + "w"; + + snipe.damage = damage; + snipe.color = color; + snipe.block = core.clone(block); + }) + + var finishSnipe = function () { + snipes.forEach(function (t) { + core.removeBlock(t.x, t.y); + var nBlock = core.clone(t.block); + nBlock.x = t.nx; nBlock.y = t.ny; + core.status.thisMap.blocks.push(nBlock); + core.addGlobalAnimate(2, 32*t.nx, 32*t.ny, t.blockIcon, t.blockImage); + core.canvas.event.drawImage(t.blockImage, 0, t.blockIcon*32, 32, 32, 32*t.nx, 32*t.ny, 32, 32); + }); + core.syncGlobalAnimate(); + core.updateStatusBar(); + return; + } + + if (core.status.replay.replaying) { + finishSnipe(); + } + else { + core.waitHeroToStop(function() { + + core.lockControl(); + + var time = 500, step = 0; + + var animateValue = 2; + var animateCurrent = 0; + var animateTime = 0; + + core.canvas.fg.textAlign = 'left'; + + var animate=window.setInterval(function() { + + step++; + animateTime += time / 16; + if (animateTime >= core.values.animateSpeed * 2 / animateValue) { + animateCurrent++; + animateTime = 0; + if (animateCurrent>=animateValue) animateCurrent=0; + } + + snipes.forEach(function (snipe) { + var x=snipe.x, y=snipe.y, direction = snipe.direction; + + var nowX=32*x+scan[direction].x*2*step, nowY=32*y+scan[direction].y*2*step; + + // 清空上一次 + core.clearMap('event', nowX-2*scan[direction].x, nowY-2*scan[direction].y, 32, 32); + core.clearMap('fg', nowX-2*scan[direction].x, nowY-2*scan[direction].y, 32, 32); + + core.canvas.event.drawImage(snipe.blockImage, animateCurrent*32, snipe.blockIcon*32, 32, 32, nowX, nowY, 32, 32); + + if (core.hasItem('book')) { + // drawFG + core.setFillStyle('fg', '#000000'); + core.canvas.fg.fillText(snipe.damage, nowX + 2, nowY + 30); + core.canvas.fg.fillText(snipe.damage, nowX, nowY + 30); + core.canvas.fg.fillText(snipe.damage, nowX + 2, nowY + 32); + core.canvas.fg.fillText(snipe.damage, nowX, nowY + 32); + + core.setFillStyle('fg', snipe.color); + core.canvas.fg.fillText(snipe.damage, nowX + 1, nowY + 31); + } + + }) + + if (step==16) { // 移动完毕 + clearInterval(animate); + finishSnipe(); + // 不存在自定义事件 + if (core.status.event.id==null) + core.unLockControl(); + } + }, time/16); + }); + } +} + +////// 更改天气效果 ////// +control.prototype.setWeather = function (type, level) { + + // 非雨雪 + if (type!='rain' && type!='snow') { + core.clearMap('weather', 0, 0, 416, 416) + core.animateFrame.weather.type = null; + core.animateFrame.weather.level = 0; + core.animateFrame.weather.nodes = []; + return; + } + + level = parseInt(level); + + // 当前天气:则忽略 + if (type==core.animateFrame.weather.type && + (!core.isset(level) || 20*level==core.animateFrame.weather.level)) { + return; + } + + if (!core.isset(level)) level=5; + if (level<1) level=1; if (level>10) level=10; + level *= 20; + + core.clearMap('weather', 0, 0, 416, 416) + core.animateFrame.weather.type = type; + core.animateFrame.weather.level = level; + + core.animateFrame.weather.nodes = []; + + if (type == 'rain') { + for (var a=0;a1) color[3]=1; + + if (time==0) { + // 直接变色 + core.dom.curtain.style.background = core.arrayToRGB(color); + core.dom.curtain.style.opacity = color[3]; + core.status.curtainColor = color; + if (core.isset(callback)) callback(); + return; + } + + var step=0; + core.status.replay.animate=true; + var changeAnimate = setInterval(function() { + step++; + + var nowAlpha = fromColor[3]+(color[3]-fromColor[3])*step/25; + var nowR = parseInt(fromColor[0]+(color[0]-fromColor[0])*step/25); + var nowG = parseInt(fromColor[1]+(color[1]-fromColor[1])*step/25); + var nowB = parseInt(fromColor[2]+(color[2]-fromColor[2])*step/25); + core.dom.curtain.style.background = core.arrayToRGB([nowR,nowG,nowB]); + core.dom.curtain.style.opacity = nowAlpha; + + if (step>=25) { + clearInterval(changeAnimate); + core.status.curtainColor = color; + core.status.replay.animate=false; + if (core.isset(callback)) callback(); + } + }, time/25); +} + +////// 更新全地图显伤 ////// +control.prototype.updateFg = function () { + + if (!core.isset(core.status.thisMap) || !core.isset(core.status.thisMap.blocks)) return; + // 更新显伤 + var mapBlocks = core.status.thisMap.blocks; + core.clearMap('fg', 0, 0, 416, 416); + // 没有怪物手册 + if (!core.hasItem('book')) return; + core.setFont('fg', "bold 11px Arial"); + var hero_hp = core.status.hero.hp; + if (core.flags.displayEnemyDamage) { + core.canvas.fg.textAlign = 'left'; + for (var b = 0; b < mapBlocks.length; b++) { + var x = mapBlocks[b].x, y = mapBlocks[b].y; + if (core.isset(mapBlocks[b].event) && mapBlocks[b].event.cls == 'enemys' + && !(core.isset(mapBlocks[b].enable) && !mapBlocks[b].enable)) { + + // 非系统默认的战斗事件(被覆盖) + if (mapBlocks[b].event.trigger != 'battle') { + // 判断显伤 + var event = core.floors[core.status.floorId].events[x+","+y]; + if (core.isset(event) && !(event instanceof Array)) { + if (core.isset(event.displayDamage) && !event.displayDamage) + continue; + } + } + + var id = mapBlocks[b].event.id; + + var damage = core.enemys.getDamage(id); + var color = "#000000"; + if (damage <= 0) color = '#00FF00'; + else if (damage < hero_hp / 3) color = '#FFFFFF'; + else if (damage < hero_hp * 2 / 3) color = '#FFFF00'; + else if (damage < hero_hp) color = '#FF7F00'; + else color = '#FF0000'; + + if (damage >= 999999999) damage = "???"; + else if (damage > 100000) damage = (damage / 10000).toFixed(1) + "w"; + + core.setFillStyle('fg', '#000000'); + core.canvas.fg.fillText(damage, 32 * x + 2, 32 * (y + 1) - 2); + core.canvas.fg.fillText(damage, 32 * x, 32 * (y + 1) - 2); + core.canvas.fg.fillText(damage, 32 * x + 2, 32 * (y + 1)); + core.canvas.fg.fillText(damage, 32 * x, 32 * (y + 1)); + + core.setFillStyle('fg', color); + core.canvas.fg.fillText(damage, 32 * x + 1, 32 * (y + 1) - 1); + + } + } + } + // 如果是领域&夹击 + if (core.flags.displayExtraDamage) { + core.canvas.fg.textAlign = 'center'; + for (var x=0;x<13;x++) { + for (var y=0;y<13;y++) { + var damage = core.status.checkBlock.damage[13*x+y]; + if (damage>0) { + core.setFillStyle('fg', '#000000'); + core.canvas.fg.fillText(damage, 32 * x + 17, 32 * (y + 1) - 13); + core.canvas.fg.fillText(damage, 32 * x + 15, 32 * (y + 1) - 15); + core.canvas.fg.fillText(damage, 32 * x + 17, 32 * (y + 1) - 15); + core.canvas.fg.fillText(damage, 32 * x + 15, 32 * (y + 1) - 13); + + core.setFillStyle('fg', '#FF7F00'); + core.canvas.fg.fillText(damage, 32 * x + 16, 32 * (y + 1) - 14); + } + } + } + } +} + +////// 执行一个表达式的effect操作 ////// +control.prototype.doEffect = function (expression) { + // 必须使用"+=" + var arr = expression.split("+="); + if (arr.length!=2) return; + var name=arr[0], value=core.calValue(arr[1]); + if (name.indexOf("status:")==0) { + var status=name.substring(7); + core.setStatus(status, core.getStatus(status)+value); + } + else if (name.indexOf("item:")==0) { + var itemId=name.substring(5); + core.setItem(itemId, core.itemCount(itemId)+value); + } +} + +////// 作弊 ////// +control.prototype.debug = function() { + core.setStatus('hp', 999999); + core.setStatus('atk', 10000); + core.setStatus('def', 10000); + core.setStatus('mdef', 10000); + core.setStatus('money', 10000); + core.setStatus('experience', 10000); + core.setItem('yellowKey', 50); + core.setItem('blueKey', 50); + core.setItem('redKey', 50); + core.setItem('book', 1); + core.setItem('fly', 1); + for (var i in core.status.maps) + if (core.status.maps[i].canFlyTo && core.status.hero.flyRange.indexOf(i)<0) + core.status.hero.flyRange.push(i); + core.updateStatusBar(); + core.drawTip("作弊成功"); +} + +////// 开始播放 ////// +control.prototype.startReplay = function (list) { + core.status.replay.replaying=true; + core.status.replay.pausing=false; + core.status.replay.speed=1.0; + core.status.replay.toReplay = core.clone(list); + core.status.replay.totalList = core.clone(list); + core.updateStatusBar(); + core.drawTip("开始播放"); + this.replay(); + return; +} + +////// 更改播放状态 ////// +control.prototype.triggerReplay = function () { + if (core.status.replay.pausing) this.resumeReplay(); + else this.pauseReplay(); +} + +////// 暂停播放 ////// +control.prototype.pauseReplay = function () { + if (!core.status.replay.replaying) return; + core.status.replay.pausing = true; + core.updateStatusBar(); + core.drawTip("暂停播放"); +} + +////// 恢复播放 ////// +control.prototype.resumeReplay = function () { + if (!core.status.replay.replaying) return; + core.status.replay.pausing = false; + core.updateStatusBar(); + core.drawTip("恢复播放"); + core.replay(); +} + +////// 加速播放 ////// +control.prototype.forwardReplay = function () { + if (!core.status.replay.replaying) return; + core.status.replay.speed = parseInt(10*core.status.replay.speed + 1)/10; + if (core.status.replay.speed>2.5) core.status.replay.speed=2.5; + core.drawTip("x"+core.status.replay.speed+"倍"); +} + +////// 减速播放 ////// +control.prototype.rewindReplay = function () { + 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; + core.drawTip("x"+core.status.replay.speed+"倍"); +} + +////// 停止播放 ////// +control.prototype.stopReplay = function () { + if (!core.status.replay.replaying) return; + core.status.replay.toReplay = []; + core.status.replay.totalList = []; + core.status.replay.replaying=false; + core.status.replay.pausing=false; + core.status.replay.speed=1.0; + core.updateStatusBar(); + core.drawTip("停止播放并恢复游戏"); +} + +////// 回放 ////// +control.prototype.replay = function () { + + if (!core.status.replay.replaying) return; // 没有回放 + if (core.status.replay.pausing) return; // 暂停状态 + if (core.status.replay.animate) return; // 正在某段动画中 + + if (core.status.replay.toReplay.length==0) { // 回放完毕 + core.stopReplay(); + core.insertAction("录像回放完毕!"); + return; + } + + var action=core.status.replay.toReplay.shift(); + + if (action=='up' || action=='down' || action=='left' || action=='right') { + core.moveHero(action, function () { + core.replay(); + }); + return; + } + else if (action.indexOf("item:")==0) { + var itemId = action.substring(5); + if (core.canUseItem(itemId)) { + var tools = Object.keys(core.status.hero.items.tools).sort(); + var constants = Object.keys(core.status.hero.items.constants).sort(); + var index; + if ((index=tools.indexOf(itemId))>=0 || (index=constants.indexOf(itemId)+100)>=100) { + core.ui.drawToolbox(index); + setTimeout(function () { + core.ui.closePanel(); + core.useItem(itemId, function () { + core.replay(); + }); + }, 750); + } + return; + } + } + else if (action.indexOf("fly:")==0) { + var floorId=action.substring(4); + var toIndex=core.status.hero.flyRange.indexOf(floorId); + var nowIndex=core.status.hero.flyRange.indexOf(core.status.floorId); + if (core.hasItem('fly') && toIndex>=0 && nowIndex>=0) { + core.ui.drawFly(toIndex); + setTimeout(function () { + core.ui.closePanel(); + var stair=toIndex0) { + var shop=core.status.shops[shopId]; + if (core.isset(shop) && shop.visited) { // 商店可用 + var choices = shop.choices; + var topIndex = 6 - parseInt(choices.length / 2); + + core.status.event.selection = parseInt(selections.shift()); + + core.events.openShop(shopId, false); + var shopInterval = setInterval(function () { + if (!core.events.clickShop(6, topIndex+core.status.event.selection)) { + clearInterval(shopInterval); + core.stopReplay(); + core.drawTip("录像文件出错"); + return; + } + if (selections.length==0) { + clearInterval(shopInterval); + core.events.clickShop(6, topIndex+choices.length); + core.replay(); + return; + } + core.status.event.selection = parseInt(selections.shift()); + core.events.openShop(shopId, false); + + }, 750); + return; + } + } + } + else if (action=='turn') { + core.turnHero(); + core.replay(); + return; + } + else if (action=='getNext') { + if (core.flags.enableGentleClick && core.getBlock(core.nextX(), core.nextY())!=null) { + var nextX = core.nextX(), nextY = core.nextY(); + var block = core.getBlock(nextX, nextY); + if (block!=null && block.block.event.trigger=='getItem') { + core.getItem(block.block.event.id, 1, nextX, nextY); + core.status.route.push("getNext"); + core.replay(); + return; + } + } + } + else if (action.indexOf('move:')==0) { + var pos=action.substring(5).split(":"); + var x=parseInt(pos[0]), y=parseInt(pos[1]); + if (core.canMoveDirectly(x,y)) { + 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.status.route.push("move:"+x+":"+y); + core.replay(); + return; + } + } + + core.stopReplay(); + core.insertAction("录像文件出错"); + +} + +////// 判断当前能否进入某个事件 ////// +control.prototype.checkStatus = function (name, need, item) { + if (need && core.status.event.id == name) { + core.ui.closePanel(); + return false; + } + + if (need && core.status.lockControl) return false; + if (core.isset(item) && item && !core.hasItem(name)) { + core.drawTip("你没有" + core.material.items[name].name); + return false; + } + if (!core.status.heroStop) { + core.drawTip("请先停止勇士行动"); + return false; + } + + core.lockControl(); + core.status.event.id = name; + return true; +} + +////// 点击怪物手册时的打开操作 ////// +control.prototype.openBook = function (need) { + if (core.isset(core.status.replay)&&core.status.replay.replaying) return; + + // 当前是book,且从“浏览地图”打开 + if (core.status.event.id == 'book' && core.isset(core.status.event.selection)) { + core.status.boxAnimateObjs = []; + core.ui.drawMaps(core.status.event.selection); + return; + } + + // 从“浏览地图”页面打开 + if (core.status.event.id=='viewMaps') { + need=false; + core.status.event.selection = core.status.event.data; + } + + if (!core.checkStatus('book', need, true)) + return; + core.useItem('book'); +} + +////// 点击楼层传送器时的打开操作 ////// +control.prototype.useFly = function (need) { + if (core.isset(core.status.replay)&&core.status.replay.replaying) return; + if (!core.checkStatus('fly', need, true)) + return; + if (core.flags.flyNearStair && !core.nearStair()) { + core.drawTip("只有在楼梯边才能使用传送器"); + core.unLockControl(); + core.status.event.data = null; + core.status.event.id = null; + return; + } + if (!core.canUseItem('fly')) { + core.drawTip("楼层传送器好像失效了"); + core.unLockControl(); + core.status.event.data = null; + core.status.event.id = null; + return; + } + core.useItem('fly'); + return; +} + +////// 点击工具栏时的打开操作 ////// +control.prototype.openToolbox = function (need) { + if (core.isset(core.status.replay)&&core.status.replay.replaying) return; + if (!core.checkStatus('toolbox', need)) + return; + core.ui.drawToolbox(); +} + +////// 点击快捷商店按钮时的打开操作 ////// +control.prototype.openQuickShop = function (need) { + if (core.isset(core.status.replay)&&core.status.replay.replaying) return; + if (!core.checkStatus('selectShop', need)) + return; + core.ui.drawQuickShop(); +} + +////// 点击保存按钮时的打开操作 ////// +control.prototype.save = function(need) { + if (core.isset(core.status.replay)&&core.status.replay.replaying) return; + if (!core.checkStatus('save', need)) + return; + + var saveIndex = core.status.saveIndex; + var page=parseInt((saveIndex-1)/5), offset=saveIndex-5*page; + + core.ui.drawSLPanel(10*page+offset); +} + +////// 点击读取按钮时的打开操作 ////// +control.prototype.load = function (need) { + if (core.isset(core.status.replay)&&core.status.replay.replaying) return; + + var saveIndex = core.getLocalStorage('saveIndex2', 1); + var page=parseInt((saveIndex-1)/5), offset=saveIndex-5*page; + + // 游戏开始前读档 + if (!core.isPlaying()) { + core.status.event = {'id': 'load', 'data': null}; + core.status.lockControl = true; + core.dom.startPanel.style.display = 'none'; + core.ui.drawSLPanel(10*page+offset); + return; + } + + if (!core.checkStatus('load', need)) + return; + core.ui.drawSLPanel(10*page+offset); +} + +////// 点击设置按钮时的操作 ////// +control.prototype.openSettings = function (need) { + if (core.isset(core.status.replay)&&core.status.replay.replaying) return; + if (!core.checkStatus('settings', need)) + return; + core.ui.drawSettings(); +} + +////// 自动存档 ////// +control.prototype.autosave = function (removeLast) { + var x=null; + if (removeLast) + x=core.status.route.pop(); + core.saveData("autoSave"); + if (removeLast && core.isset(x)) + core.status.route.push(x); +} + +////// 实际进行存读档事件 ////// +control.prototype.doSL = function (id, type) { + if (type=='save') { + if (id=='autoSave') { + core.drawTip('不能覆盖自动存档!'); + return; + } + if (core.saveData("save"+id)) { + core.ui.closePanel(); + core.drawTip('存档成功!'); + if (id!="autoSave") { + core.status.saveIndex=id; + core.setLocalStorage('saveIndex2', core.status.saveIndex); + } + } + else { + core.drawTip('存储空间不足,请覆盖已有的存档或在菜单栏中进行清理'); + } + return; + } + else if (type=='load') { + 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("存档版本不匹配"); + if (confirm("存档版本不匹配!\n你想回放此存档的录像吗?")) { + core.dom.startPanel.style.display = 'none'; + core.resetStatus(core.firstData.hero, data.hard, core.firstData.floorId, null, core.initStatus.maps); + core.events.setInitData(data.hard); + core.changeFloor(core.status.floorId, null, core.firstData.hero.loc, null, function() { + core.startReplay(core.decodeRoute(data.route)); + }); + } + return; + } + core.ui.closePanel(); + core.loadData(data, function() { + core.drawTip("读档成功"); + if (id!="autoSave") { + core.status.saveIndex=id; + core.setLocalStorage('saveIndex2', core.status.saveIndex); + } + }); + return; + } +} + +////// 同步存档到服务器 ////// +control.prototype.syncSave = function (type) { + var saves=null; + // data + if (type=='all') { + saves=[]; + for (var i=1;i<=150;i++) { + var data = core.getLocalStorage("save"+i, null); + if (core.isset(data)) { + saves.push(data); + } + } + } + else { + for (var i=150;i>=1;i--) { + saves=core.getLocalStorage("save"+i, null); + if (core.isset(saves)) { + break; + } + } + } + if (!core.isset(saves)) { + core.drawText("没有要同步的存档"); + return; + } + core.ui.drawWaiting("正在同步,请稍后..."); + + var formData = new FormData(); + formData.append('type', 'save'); + formData.append('name', core.firstData.name); + var save_text = JSON.stringify(saves); + formData.append('data', save_text); + + core.http("POST", "/games/sync.php", formData, function (data) { + var response = JSON.parse(data); + if (response.code<0) { + core.drawText("出错啦!\n无法同步存档到服务器。\n错误原因:"+response.msg); + } + else { + core.drawText("同步成功!\n\n您的存档编号: "+response.code+"\n您的存档密码: "+response.msg+"\n\n请牢记以上两个信息(如截图等),在从服务器\n同步存档时使用。") + } + }, function (e) { + core.drawText("出错啦!\n无法同步存档到服务器。\n错误原因:"+e); + }) +} + +////// 从服务器加载存档 ////// +control.prototype.syncLoad = function () { + var id = prompt("请输入存档编号:"); + if (id==null || id=="") { + core.ui.drawSyncSave(); return; + } + var password = prompt("请输入存档密码:"); + if (password==null || password=="") { + core.ui.drawSyncSave(); return; + } + core.ui.drawWaiting("正在同步,请稍后..."); + + var formData = new FormData(); + formData.append('type', 'load'); + formData.append('name', core.firstData.name); + formData.append('id', id); + formData.append('password', password); + + core.http("POST", "/games/sync.php", formData, function (data) { + var response = JSON.parse(data); + switch (response.code) { + case 0: + // 成功 + var data=JSON.parse(response.msg); + // console.log(data); + + if (data instanceof Array) { + core.status.event.selection=1; + core.ui.drawConfirmBox("所有本地存档都将被覆盖,确认?", function () { + for (var i=1;i<=150;i++) { + if (i<=data.length) { + core.setLocalStorage("save"+i, data[i-1]); + } + else { + core.removeLocalStorage("save"+i); + } + } + core.drawText("同步成功!\n你的本地所有存档均已被覆盖。"); + }, function () { + core.status.event.selection=0; + core.ui.drawSyncSave(); + }) + } + else { + // 只覆盖单存档 + var index=150; + for (var i=150;i>=1;i--) { + if (core.getLocalStorage("save"+i, null)==null) + index=i; + else break; + } + core.setLocalStorage("save"+index, data); + core.drawText("同步成功!\n单存档已覆盖至存档"+index); + } + break; + case -1: + core.drawText("出错啦!\n存档编号"+id+"不存在!"); + break; + case -2: + core.drawText("出错啦!\n存档密码错误!"); + break; + default: + core.drawText("出错啦!\n无法从服务器同步存档。\n错误原因:"+response.msg); + break; + } + }, function (e) { + core.drawText("出错啦!\n无法从服务器同步存档。\n错误原因:"+e); + }); +} + +////// 存档到本地 ////// +control.prototype.saveData = function(dataId) { + var data = { + 'floorId': core.status.floorId, + 'hero': core.clone(core.status.hero), + 'hard': core.status.hard, + 'maps': core.maps.save(core.status.maps), + 'route': core.encodeRoute(core.status.route), + 'shops': {}, + 'version': core.firstData.version, + "time": new Date().getTime() + }; + // set shop times + for (var shop in core.status.shops) { + data.shops[shop]={ + 'times': core.status.shops[shop].times || 0, + 'visited': core.status.shops[shop].visited || false + } + } + core.events.beforeSaveData(data); + + return core.setLocalStorage(dataId, data); +} + +////// 从本地读档 ////// +control.prototype.loadData = function (data, callback) { + + core.resetStatus(data.hero, data.hard, data.floorId, core.decodeRoute(data.route), core.maps.load(data.maps)); + + // load shop times + for (var shop in core.status.shops) { + if (core.isset(data.shops[shop])) { + core.status.shops[shop].times = data.shops[shop].times; + core.status.shops[shop].visited = data.shops[shop].visited; + } + } + + core.events.afterLoadData(data); + + core.changeFloor(data.floorId, null, data.hero.loc, 0, function() { + if (core.isset(callback)) callback(); + }); +} + +////// 设置勇士属性 ////// +control.prototype.setStatus = function (statusName, statusVal) { + core.status.hero[statusName] = statusVal; +} + +////// 获得勇士属性 ////// +control.prototype.getStatus = function (statusName) { + return core.status.hero[statusName]; +} + +////// 获得某个等级的名称 ////// +control.prototype.getLvName = function () { + if (core.status.hero.lv>core.firstData.levelUp.length) return core.status.hero.lv; + return core.firstData.levelUp[core.status.hero.lv-1].name || core.status.hero.lv; +} + +////// 设置某个自定义变量或flag ////// +control.prototype.setFlag = function(flag, value) { + if (!core.isset(core.status.hero)) return; + core.status.hero.flags[flag]=value; +} + +////// 获得某个自定义变量或flag ////// +control.prototype.getFlag = function(flag, defaultValue) { + if (!core.isset(core.status.hero)) return defaultValue; + var value = core.status.hero.flags[flag]; + if (core.isset(value)) return value; + return defaultValue; +} + +////// 是否存在某个自定义变量或flag,且值为true ////// +control.prototype.hasFlag = function(flag) { + if (core.getFlag(flag)) return true; + return false; +} + +////// 锁定状态栏,常常用于事件处理 ////// +control.prototype.lockControl = function () { + core.status.lockControl = true; +} + +////// 解锁状态栏 ////// +control.prototype.unLockControl = function () { + core.status.lockControl = false; +} + +////// 播放背景音乐 ////// +control.prototype.playBgm = function (bgm) { + if (main.mode!='play')return; + // 如果不允许播放 + if (!core.musicStatus.bgmStatus) return; + // 音频不存在 + if (!core.isset(core.material.bgms[bgm])) return; + + // 延迟播放 + if (core.material.bgms[bgm] == 'loading') { + core.material.bgms[bgm] = 'starting'; + return; + } + + try { + // 如果当前正在播放,且和本BGM相同,直接忽略 + if (core.musicStatus.playingBgm == bgm && core.musicStatus.isPlaying) { + return; + } + // 如果正在播放中,暂停 + if (core.isset(core.musicStatus.playingBgm) && core.musicStatus.isPlaying) { + core.material.bgms[core.musicStatus.playingBgm].pause(); + } + // 播放当前BGM + core.musicStatus.playingBgm = bgm; + core.material.bgms[bgm].play(); + core.musicStatus.isPlaying = true; + + } + catch (e) { + console.log("无法播放BGM "+bgm); + console.log(e); + core.musicStatus.playingBgm = null; + } +} + +////// 暂停背景音乐的播放 ////// +control.prototype.pauseBgm = function () { + // 直接暂停播放 + try { + if (core.isset(core.musicStatus.playingBgm)) { + core.material.bgms[core.musicStatus.playingBgm].pause(); + } + core.musicStatus.isPlaying = false; + } + catch (e) { + console.log("无法暂停BGM "+bgm); + console.log(e); + } +} + +////// 恢复背景音乐的播放 ////// +control.prototype.resumeBgm = function () { + if (main.mode!='play')return; + // 如果不允许播放 + if (!core.musicStatus.bgmStatus) return; + + // 恢复BGM + try { + if (core.isset(core.musicStatus.playingBgm)) { + core.material.bgms[core.musicStatus.playingBgm].play(); + core.musicStatus.isPlaying = true; + } + else { + if (core.bgms.length>0) { + core.playBgm(core.bgms[0]); + core.musicStatus.isPlaying = true; + } + } + } + catch (e) { + console.log("无法恢复BGM "+bgm); + console.log(e); + } +} + +////// 播放音频 ////// +control.prototype.playSound = function (sound) { + if (main.mode!='play')return; + // 如果不允许播放 + if (!core.musicStatus.soundStatus) return; + // 音频不存在 + if (!core.isset(core.material.sounds[sound])) return; + + try { + if (core.musicStatus.audioContext != null) { + var source = core.musicStatus.audioContext.createBufferSource(); + source.buffer = core.material.sounds[sound]; + source.connect(core.musicStatus.audioContext.destination); + try { + source.start(0); + } + catch (e) { + try { + source.noteOn(0); + } + catch (ee) { + } + } + } + else { + core.material.sounds[sound].play(); + } + } + catch (eee) { + console.log("无法播放SE "+bgm); + console.log(eee); + } +} + +////// 清空状态栏 ////// +control.prototype.clearStatusBar = function() { + var statusList = ['floor', 'lv', 'hp', 'atk', 'def', 'mdef', 'money', 'experience', 'up', 'yellowKey', 'blueKey', 'redKey', 'poison', 'weak', 'curse', 'hard']; + statusList.forEach(function (e) { + core.statusBar[e].innerHTML = " "; + }); + core.statusBar.image.book.style.opacity = 0.3; + core.statusBar.image.fly.style.opacity = 0.3; +} + +////// 更新状态栏 ////// +control.prototype.updateStatusBar = function () { + + // 检查等级 + core.events.checkLvUp(); + + // 检查HP上限 + if (core.values.HPMAX>0) { + core.setStatus('hp', Math.min(core.values.HPMAX, core.getStatus('hp'))); + } + + // 更新领域、阻击、显伤 + core.updateCheckBlock(); + + var lvName = core.getLvName(); + core.statusBar.lv.innerHTML = lvName; + if (/^[+-]?\d+$/.test(lvName)) + core.statusBar.lv.style.fontStyle = 'italic'; + else core.statusBar.lv.style.fontStyle = 'normal'; + + var statusList = ['hp', 'atk', 'def', 'mdef', 'money', 'experience']; + statusList.forEach(function (item) { + core.statusBar[item].innerHTML = core.getStatus(item); + }); + // 进阶 + if (core.flags.enableLevelUp && core.status.hero.lv clientHeight && clientHeight < ADAPT_WIDTH){ + isHorizontal = true; + width = clientHeight; + } + // 各元素大小的变量声明 + var gameGroupWidth, gameGroupHeight, borderRight, + canvasWidth, canvasTop, // canvasLeft, + statusBarWidth, statusBarHeight, statusBarBorder, + statusWidth, statusHeight, statusMaxWidth,statusLabelsLH, + toolBarWidth, toolBarHeight, toolBarTop, toolBarBorder, + toolsWidth, toolsHeight,toolsMargin,toolsPMaxwidth, + fontSize, toolbarFontSize, margin; + + var count = 11; + if (!core.flags.enableFloor) count--; + if (!core.flags.enableLv) count--; + if (!core.flags.enableMDef) count--; + if (!core.flags.enableMoney) count--; + if (!core.flags.enableExperience) count--; + if (!core.flags.enableLevelUp) count--; + if (!core.flags.enableDebuff) count--; + + var statusLineHeight = BASE_LINEHEIGHT * 9 / count; + var statusLineFontSize = DEFAULT_FONT_SIZE; + if (count>9) statusLineFontSize = statusLineFontSize * 9 / count; + + var shopDisplay; + + statusBarBorder = '3px #fff solid'; + toolBarBorder = '3px #fff solid'; + var zoom = (ADAPT_WIDTH - width) / 4.22; + var aScale = 1 - zoom / 100; + + // 移动端 + if (width < CHANGE_WIDTH) { + if(width < ADAPT_WIDTH){ + + core.domStyle.scale = aScale; + canvasWidth = width; + }else{ + canvasWidth = DEFAULT_CANVAS_WIDTH; + core.domStyle.scale = 1; + } + + var scale = core.domStyle.scale + var tempWidth = DEFAULT_CANVAS_WIDTH * scale; + if(!isHorizontal){ //竖屏 + core.domStyle.screenMode = 'vertical'; + //显示快捷商店图标 + shopDisplay = 'block'; + //判断应该显示几行 + // var col = core.flags.enableMDef || core.flags.enableExperience || core.flags.enableDebuff ? 3 : 2; + var col = parseInt((count-1)/3)+1; + + var tempTopBarH = scale * (BASE_LINEHEIGHT * col + SPACE * 2) + 6; + var tempBotBarH = scale * (BASE_LINEHEIGHT + SPACE * 4) + 6; + + gameGroupHeight = tempWidth + tempTopBarH + tempBotBarH; + + gameGroupWidth = tempWidth + canvasTop = tempTopBarH; + // canvasLeft = 0; + toolBarWidth = statusBarWidth = canvasWidth; + statusBarHeight = tempTopBarH; + statusBarBorder = '3px #fff solid'; + + statusHeight = scale*BASE_LINEHEIGHT * .8; + statusLabelsLH = .8 * BASE_LINEHEIGHT *scale; + statusMaxWidth = scale * DEFAULT_BAR_WIDTH * .95; + toolBarHeight = tempBotBarH; + + toolBarTop = statusBarHeight + canvasWidth; + toolBarBorder = '3px #fff solid'; + toolsHeight = scale * BASE_LINEHEIGHT; + toolsPMaxwidth = scale * DEFAULT_BAR_WIDTH * .4; + borderRight = '3px #fff solid'; + + margin = scale * SPACE * 2; + toolsMargin = scale * SPACE * 4; + fontSize = DEFAULT_FONT_SIZE * scale; + toolbarFontSize = DEFAULT_FONT_SIZE * scale; + }else { //横屏 + core.domStyle.screenMode = 'horizontal'; + shopDisplay = 'none'; + gameGroupWidth = tempWidth + DEFAULT_BAR_WIDTH * scale; + gameGroupHeight = tempWidth; + canvasTop = 0; + // canvasLeft = DEFAULT_BAR_WIDTH * scale; + toolBarWidth = statusBarWidth = DEFAULT_BAR_WIDTH * scale; + statusBarHeight = scale * statusLineHeight * count + SPACE * 2; //一共有9行加上两个padding空隙 + statusBarBorder = '3px #fff solid'; + + statusHeight = scale*statusLineHeight * .8; + statusLabelsLH = .8 * statusLineHeight *scale; + toolBarHeight = canvasWidth - statusBarHeight; + toolBarTop = scale*statusLineHeight * count + SPACE * 2; + toolBarBorder = '3px #fff solid'; + toolsHeight = scale * BASE_LINEHEIGHT; + fontSize = statusLineFontSize * scale; + toolbarFontSize = DEFAULT_FONT_SIZE * scale; + borderRight = ''; + statusMaxWidth = scale * DEFAULT_BAR_WIDTH; + toolsPMaxwidth = scale * DEFAULT_BAR_WIDTH; + + margin = scale * SPACE * 2; + toolsMargin = 2 * SPACE * scale; + } + + }else { //大屏设备 pc端 + core.domStyle.scale = 1; + core.domStyle.screenMode = 'bigScreen'; + shopDisplay = 'none'; + + gameGroupWidth = DEFAULT_CANVAS_WIDTH + DEFAULT_BAR_WIDTH; + gameGroupHeight = DEFAULT_CANVAS_WIDTH; + canvasWidth = DEFAULT_CANVAS_WIDTH; + canvasTop = 0; + // canvasLeft = DEFAULT_BAR_WIDTH; + + toolBarWidth = statusBarWidth = DEFAULT_BAR_WIDTH; + statusBarHeight = statusLineHeight * count + SPACE * 2; //一共有9行 + + statusHeight = statusLineHeight * .8; + statusLabelsLH = .8 * statusLineHeight; + toolBarHeight = DEFAULT_CANVAS_WIDTH - statusBarHeight; + toolBarTop = statusLineHeight * count + SPACE * 2; + + toolsHeight = BASE_LINEHEIGHT; + borderRight = ''; + fontSize = statusLineFontSize; + toolbarFontSize = DEFAULT_FONT_SIZE; + statusMaxWidth = DEFAULT_BAR_WIDTH; + toolsPMaxwidth = DEFAULT_BAR_WIDTH * .9; + margin = SPACE * 2; + toolsMargin = 2 * SPACE; + } + + var unit = 'px' + core.domStyle.styles = [ + { + id: 'gameGroup', + rules:{ + width: gameGroupWidth + unit, + height: gameGroupHeight + unit, + top: (clientHeight-gameGroupHeight)/2 + unit, + left: (clientWidth-gameGroupWidth)/2 + unit, + } + }, + { + className: 'gameCanvas', + rules:{ + width: canvasWidth + unit, + height: canvasWidth + unit, + top: canvasTop + unit, + right: 0, + border: '3px #fff solid', + } + }, + { + id: 'curtain', + rules: { + width: (canvasWidth - SPACE*2) + unit, + height:(canvasWidth - SPACE*2) + unit, + top: (canvasTop + SPACE) + unit, + right: SPACE + unit, + } + }, + { + id: 'floorMsgGroup', + rules:{ + width: (canvasWidth - SPACE*2) + unit, + height: (gameGroupHeight - SPACE*2) + unit, + top: SPACE + unit, + right: SPACE + unit, + } + }, + { + id: 'statusBar', + rules:{ + width: statusBarWidth + unit, + height: statusBarHeight + unit, + top: 0, + left: 0, + padding: SPACE + unit, + + borderTop: statusBarBorder, + borderLeft: statusBarBorder, + borderRight: borderRight, + fontSize: fontSize + unit + } + }, + { + className: 'status', + rules:{ + width: '100%', + maxWidth: statusMaxWidth + unit, + height: statusHeight + unit, + margin: margin/2 + unit + } + }, + { + className: 'statusLabels', + rules:{ + marginLeft: margin + unit, + lineHeight: statusLabelsLH + unit, + } + }, + { + id: 'toolBar', + rules:{ + width: toolBarWidth + unit, + height: toolBarHeight + unit, + top: toolBarTop +unit, + left: 0, + padding: SPACE + unit, + borderBottom: toolBarBorder, + borderLeft: toolBarBorder, + borderRight: borderRight, + fontSize: toolbarFontSize + unit + } + }, + { + className: 'tools', + rules:{ + height: toolsHeight + unit, + maxWidth: toolsPMaxwidth + unit, + marginLeft: toolsMargin + unit, + marginTop: margin + unit, + } + }, + { + imgId: 'shop', + rules:{ + display: shopDisplay + } + }, + { + id: 'floorCol', + rules: { + display: core.flags.enableFloor ? 'block': 'none' + } + }, + { + id: 'lvCol', + rules: { + display: core.flags.enableLv ? 'block': 'none' + } + }, + { + id: 'mdefCol', + rules: { + display: core.flags.enableMDef ? 'block': 'none' + } + }, + { + id: 'moneyCol', + rules: { + display: core.flags.enableMoney ? 'block': 'none' + } + }, + { + id: 'expCol', + rules: { + display: core.flags.enableExperience ? 'block': 'none' + } + }, + { + id: 'upCol', + rules: { + display: core.flags.enableLevelUp ? 'block': 'none' + } + }, + { + 'id': 'debuffCol', + rules: { + display: core.flags.enableDebuff ? 'block': 'none' + } + }, + { + id: 'hard', + rules: { + lineHeight: toolsHeight + unit + } + } + ] + core.domRenderer(); +} + +////// 渲染DOM ////// +control.prototype.domRenderer = function(){ + + core.dom.statusBar.style.display = 'block'; + core.dom.toolBar.style.display = 'block'; + + var styles = core.domStyle.styles; + + for(var i=0; icore.animateFrame.speed && core.isset(core.status.twoAnimateObjs)) { - - for (var a = 0; a < core.status.twoAnimateObjs.length; a++) { - var obj = core.status.twoAnimateObjs[a]; - obj.status = (obj.status+1)%2; - core.canvas.event.clearRect(obj.x, obj.y, 32, 32); - core.canvas.event.drawImage(obj.image, obj.status * 32, obj.loc * 32, 32, 32, obj.x, obj.y, 32, 32); - } - - core.animateFrame.twoTime = timestamp; - } - - if (timestamp-core.animateFrame.fourTime>core.animateFrame.speed/2 && core.isset(core.status.fourAnimateObjs)) { - for (var a = 0; a < core.status.fourAnimateObjs.length; a++) { - var obj=core.status.fourAnimateObjs[a]; - obj.status = (obj.status+1)%4; - core.canvas.event.clearRect(obj.x, obj.y, 32, 32); - core.canvas.event.drawImage(obj.image, obj.status * 32, obj.loc * 32, 32, 32, obj.x, obj.y, 32, 32); - } - // fourtime = timestamp % fourDelta; - core.animateFrame.fourTime = timestamp; - } - - } - - // Box - if (timestamp-core.animateFrame.boxTime>core.animateFrame.speed && core.isset(core.status.boxAnimateObjs) && core.status.boxAnimateObjs.length>0) { - core.drawBoxAnimate(); - core.animateFrame.boxTime = timestamp; - } - - // Hero move - if (timestamp-core.animateFrame.moveTime>16 && core.isset(core.status.heroMoving) && core.status.heroMoving>0) { - var x=core.getHeroLoc('x'), y=core.getHeroLoc('y'), direction = core.getHeroLoc('direction'); - if (core.status.heroMoving<=4) { - core.drawHero(direction, x, y, 'leftFoot', 4*core.status.heroMoving*scan[direction].x, 4*core.status.heroMoving*scan[direction].y); - } - else if (core.status.heroMoving<=8) { - core.drawHero(direction, x, y, 'rightFoot', 4*core.status.heroMoving*scan[direction].x, 4*core.status.heroMoving*scan[direction].y); - } - core.animateFrame.moveTime = timestamp; - } - - // weather - if (core.isPlaying() && timestamp-core.animateFrame.weather.time>30) { - if (core.animateFrame.weather.type == 'rain' && core.animateFrame.weather.level > 0) { - - core.clearMap('weather', 0, 0, 416, 416); - - core.canvas.weather.strokeStyle = 'rgba(174,194,224,0.8)'; - core.canvas.weather.lineWidth = 1; - core.canvas.weather.lineCap = 'round'; - - core.animateFrame.weather.nodes.forEach(function (p) { - core.canvas.weather.beginPath(); - core.canvas.weather.moveTo(p.x, p.y); - core.canvas.weather.lineTo(p.x + p.l * p.xs, p.y + p.l * p.ys); - core.canvas.weather.stroke(); - - p.x += p.xs; - p.y += p.ys; - if (p.x > 416 || p.y > 416) { - p.x = Math.random() * 416; - p.y = -10; - } - - }) - - core.canvas.weather.fill(); - - } - else if (core.animateFrame.weather.type == 'snow' && core.animateFrame.weather.level > 0) { - - core.clearMap('weather', 0, 0, 416, 416); - - core.canvas.weather.fillStyle = "rgba(255, 255, 255, 0.8)"; - core.canvas.weather.beginPath(); - - if (!core.isset(core.animateFrame.weather.data)) - core.animateFrame.weather.data = 0; - core.animateFrame.weather.data += 0.01; - - var angle = core.animateFrame.weather.data; - core.animateFrame.weather.nodes.forEach(function (p) { - core.canvas.weather.moveTo(p.x, p.y); - core.canvas.weather.arc(p.x, p.y, p.r, 0, Math.PI * 2, true); - - // update - p.x += Math.sin(angle) * 2; - p.y += Math.cos(angle + p.d) + 1 + p.r / 2; - - if (p.x > 416 + 5 || p.x < -5 || p.y > 416) { - if (Math.random() > 1 / 3) { - p.x = Math.random() * 416; - p.y = -10; - } - else { - if (Math.sin(angle) > 0) { - p.x = -5; - p.y = Math.random() * 416; - } - else { - p.x = 416 + 5; - p.y = Math.random() * 416; - } - } - } - - }) - - core.canvas.weather.fill(); - - } - core.animateFrame.weather.time = timestamp; - - } - window.requestAnimationFrame(draw); - } - window.requestAnimationFrame(draw); + core.control.setRequestAnimationFrame(); } ////// 显示游戏开始界面 ////// core.prototype.showStartAnimate = function (callback) { - core.dom.startPanel.style.opacity=1; - core.dom.startPanel.style.display="block"; - core.dom.startTop.style.opacity=1; - core.dom.startTop.style.display="block"; - core.dom.startButtonGroup.style.display = 'none'; - core.dom.startButtons.style.display = 'block'; - core.dom.levelChooseButtons.style.display = 'none'; - core.dom.curtain.style.background = "#000000"; - core.dom.curtain.style.opacity = 0; - core.status.played = false; - core.clearStatus(); - core.clearMap('all'); - - var opacityVal = 1; - var startAnimate = window.setInterval(function () { - opacityVal -= 0.03; - if (opacityVal < 0) { - clearInterval(startAnimate); - core.dom.startTop.style.display = 'none'; - // core.playGame(); - core.dom.startButtonGroup.style.display = 'block'; - if (core.isset(callback)) callback(); - } - core.dom.startTop.style.opacity = opacityVal; - }, 20); + core.control.showStartAnimate(callback); } ////// 隐藏游戏开始界面 ////// core.prototype.hideStartAnimate = function (callback) { - var opacityVal = 1; - var startAnimate = window.setInterval(function () { - opacityVal -= 0.03; - if (opacityVal < 0) { - clearInterval(startAnimate); - core.dom.startPanel.style.display = 'none'; - if (core.isset(callback)) callback(); - } - core.dom.startPanel.style.opacity = opacityVal; - }, 20); -} - -////// 设置加载进度条进度 ////// -core.prototype.setStartProgressVal = function (val) { - core.dom.startTopProgress.style.width = val + '%'; -} - -////// 设置加载进度条提示文字 ////// -core.prototype.setStartLoadTipText = function (text) { - core.dom.startTopLoadTips.innerHTML = text; -} - -////// 加载图片和音频 ////// -core.prototype.loader = function (callback) { - var loadedImageNum = 0, allImageNum = 0, allSoundNum = 0; - allImageNum = core.images.length; - for (var key in core.sounds) { - allSoundNum += core.sounds[key].length; - } - for (var i = 0; i < core.images.length; i++) { - core.loadImage(core.images[i], function (imgName, image) { - core.setStartLoadTipText('正在加载图片 ' + imgName + "..."); - core.material.images[imgName] = image; - loadedImageNum++; - core.setStartLoadTipText(imgName + ' 加载完毕...'); - core.setStartProgressVal(loadedImageNum * (100 / allImageNum)); - if (loadedImageNum == allImageNum) { - - // 加载pngs - core.material.images.pngs = {}; - if (core.pngs.length==0) { - core.loadAutotile(callback); - return; - } - for (var x=0;x0) - core.playBgm(core.bgms[0]); - - callback(); + core.control.hideStartAnimate(callback); } ////// 游戏是否已经开始 ////// core.prototype.isPlaying = function() { - if (core.isset(core.status.played) && core.status.played) - return true; - return false; + return core.control.isPlaying(); } ////// 清除游戏状态和数据 ////// core.prototype.clearStatus = function() { - // 停止各个Timeout和Interval - for (var i in core.interval) { - clearInterval(core.interval[i]); - } - core.status = {}; - core.clearStatusBar(); - core.resize(main.dom.body.clientWidth, main.dom.body.clientHeight); + core.control.clearStatus(); } ////// 重置游戏状态和初始数据 ////// core.prototype.resetStatus = function(hero, hard, floorId, route, maps) { - - // 停止各个Timeout和Interval - for (var i in core.timeout) { - clearTimeout(core.timeout[i]); - core.timeout[i] = null; - } - for (var i in core.interval) { - clearInterval(core.interval[i]); - core.interval[i] = null; - } - - // 初始化status - core.status = core.clone(core.initStatus); - core.status.played = true; - // 初始化maps - core.status.floorId = floorId; - core.status.maps = core.clone(maps); - // 初始化怪物 - core.material.enemys = core.clone(core.enemys.getEnemys()); - // 初始化人物属性 - core.status.hero = core.clone(hero); - core.status.hard = hard; - // 初始化路线 - if (core.isset(route)) - core.status.route = route; - // 保存的Index - core.status.saveIndex = core.getLocalStorage('saveIndex2', 1); - - core.resize(main.dom.body.clientWidth, main.dom.body.clientHeight); + core.control.resetStatus(hero, hard, floorId, route, maps) } ////// 开始游戏 ////// core.prototype.startGame = function (hard, callback) { - console.log('开始游戏'); - - core.resetStatus(core.firstData.hero, hard, core.firstData.floorId, null, core.initStatus.maps); - - core.changeFloor(core.status.floorId, null, core.firstData.hero.loc, null, function() { - if (core.isset(callback)) callback(); - }); - - - setTimeout(function () { - // Upload - var formData = new FormData(); - formData.append('type', 'people'); - formData.append('name', core.firstData.name); - formData.append('version', core.firstData.version); - formData.append('platform', core.platform.isPC?"PC":core.platform.isAndroid?"Android":core.platform.isIOS?"iOS":""); - formData.append('hard', hard); - formData.append('hardCode', core.getFlag('hard', 0)); - - var xhr = new XMLHttpRequest(); - xhr.open("POST", "/games/upload.php"); - xhr.send(formData); - - }) - + core.control.startGame(hard, callback); } ////// 重新开始游戏;此函数将回到标题页面 ////// core.prototype.restart = function() { - core.showStartAnimate(); + core.control.restart(); } /////////// 系统事件相关 END /////////// - - /////////// 键盘、鼠标事件相关 /////////// ////// 按下某个键时 ////// core.prototype.onkeyDown = function(e) { - if (core.isset(core.status.replay)&&core.status.replay.replaying) 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){ - for(var ii =0;iimax){ - index=ii; - max=directionDistance[ii]; - } - } - pos=[{'x':0,'y':1},{'x':-1,'y':0},{'x':0,'y':-1},{'x':1,'y':0},false][index] - if(pos){ - pos.x+=pos0.x; - pos.y+=pos0.y; - core.status.stepPostfix.push(pos); - core.fillPosWithPoint(pos); - } + return core.actions.onmove(x,y); } ////// 当点击(触摸)事件放开时 ////// core.prototype.onup = function () { - if (core.isset(core.status.replay)&&core.status.replay.replaying) return; - - clearTimeout(core.timeout.onDownTimeout); - core.timeout.onDownTimeout = null; - clearInterval(core.interval.onDownInterval); - core.interval.onDownInterval = null; - - // core.status.holdingPath=0; - if(core.status.stepPostfix.length>0){ - var stepPostfix = []; - var direction={'0':{'1':'down','-1':'up'},'-1':{'0':'left'},'1':{'0':'right'}}; - for(var ii=1;ii=1000) { - core.waitHeroToStop(function () { - // 绘制快捷键 - core.ui.drawKeyBoard(); - }); - } - else { - //posx,posy是寻路的目标点,stepPostfix是后续的移动 - core.onclick(posx,posy,stepPostfix); - } - core.status.downTime=null; - } + return core.actions.onup(); } ////// 获得点击事件相对左上角的坐标(0到12之间) ////// core.prototype.getClickLoc = function (x, y) { - - var statusBar = {'x': 0, 'y': 0}; - var size = 32; - size = size * core.domStyle.scale; - - switch (core.domStyle.screenMode) {// 这里的3是指statusBar和游戏画布之间的白线宽度 - case 'vertical': - statusBar.x = 0; - statusBar.y = core.dom.statusBar.offsetHeight + 3; - break; - case 'horizontal': - case 'bigScreen': - statusBar.x = core.dom.statusBar.offsetWidth + 3; - statusBar.y = 0; - break; - } - - var left = core.dom.gameGroup.offsetLeft + statusBar.x; - var top = core.dom.gameGroup.offsetTop + statusBar.y; - var loc={'x': x - left, 'y': y - top, 'size': size}; - return loc; + return core.actions.getClickLoc(x,y); } ////// 具体点击屏幕上(x,y)点时,执行的操作 ////// core.prototype.onclick = function (x, y, stepPostfix) { - if (core.isset(core.status.replay)&&core.status.replay.replaying) return; - // console.log("Click: (" + x + "," + y + ")"); - - stepPostfix=stepPostfix||[]; - - // 非游戏屏幕内 - if (x<0 || y<0 || x>12 || y>12) return; - - // 中心对称飞行器 - if (core.status.usingCenterFly) { - if (x!=12-core.getHeroLoc('x') || y!=12-core.getHeroLoc('y')) { - core.clearMap('ui', (12-core.getHeroLoc('x'))*32,(12-core.getHeroLoc('y'))*32,32,32); - } else { - if (core.canUseItem('centerFly')) { - core.useItem('centerFly'); - core.clearMap('ui', core.getHeroLoc('x')*32,core.getHeroLoc('y')*32,32,32); - return; - } - else { - core.drawTip('当前不能使用中心对称飞行器'); - core.clearMap('ui', (12-core.getHeroLoc('x'))*32,(12-core.getHeroLoc('y'))*32,32,32); - } - } - core.status.usingCenterFly= false; - } - - // 寻路 - if (!core.status.lockControl) { - core.setAutomaticRoute(x, y, stepPostfix); - return; - } - - // 怪物手册 - if (core.status.event.id == 'book') { - core.events.clickBook(x,y); - return; - } - - // 怪物详细信息 - if (core.status.event.id == 'book-detail') { - core.events.clickBookDetail(x,y); - return; - } - - // 楼层飞行器 - if (core.status.event.id == 'fly') { - core.events.clickFly(x,y); - return; - } - - // 查看地图 - if (core.status.event.id == 'viewMaps') { - core.events.clickViewMaps(x,y); - return; - } - - // 开关 - if (core.status.event.id == 'switchs') { - core.events.clickSwitchs(x,y); - return; - } - - // 设置 - if (core.status.event.id == 'settings') { - core.events.clickSettings(x,y); - return; - } - - // 商店 - if (core.status.event.id == 'shop') { - core.events.clickShop(x,y); - return; - } - - // 快捷商店 - if (core.status.event.id == 'selectShop') { - core.events.clickQuickShop(x,y); - return; - } - - // 工具栏 - if (core.status.event.id == 'toolbox') { - core.events.clickToolbox(x,y); - return; - } - - // 存读档 - if (core.status.event.id == 'save' || core.status.event.id == 'load') { - core.events.clickSL(x,y); - return; - } - - // 选项 - if (core.status.event.id == 'confirmBox') { - core.events.clickConfirmBox(x,y); - return; - } - - if (core.status.event.id == 'keyBoard') { - core.events.clickKeyBoard(x,y); - return; - } - - // 关于 - if (core.status.event.id == 'about') { - core.events.clickAbout(x,y); - return; - } - - if (core.status.event.id == 'action') { - core.events.clickAction(x,y); - return; - } - - // 纯文本 - if (core.status.event.id == 'text') { - core.drawText(); - return; - } - - // 同步存档 - if (core.status.event.id == 'syncSave') { - core.events.clickSyncSave(x,y); - return; - } - - if (core.status.event.id == 'syncSelect') { - core.events.clickSyncSelect(x,y); - return; - } - - if (core.status.event.id == 'localSaveSelect') { - core.events.clickLocalSaveSelect(x,y); - return; - } - - if (core.status.event.id == 'cursor') { - core.events.clickCursor(x,y); - return; - } - + return core.actions.onclick(x,y,stepPostfix); } ////// 滑动鼠标滚轮时的操作 ////// core.prototype.onmousewheel = function (direct) { - if (core.isset(core.status.replay)&&core.status.replay.replaying) return; - // 向下滚动是 -1 ,向上是 1 - - // 楼层飞行器 - if (core.status.lockControl && core.status.event.id == 'fly') { - if (direct==1) core.ui.drawFly(core.status.event.data+1); - if (direct==-1) core.ui.drawFly(core.status.event.data-1); - return; - } - - // 怪物手册 - if (core.status.lockControl && core.status.event.id == 'book') { - if (direct==1) core.ui.drawBook(core.status.event.data - 6); - if (direct==-1) core.ui.drawBook(core.status.event.data + 6); - return; - } - - // 存读档 - if (core.status.lockControl && (core.status.event.id == 'save' || core.status.event.id == 'load')) { - if (direct==1) core.ui.drawSLPanel(core.status.event.data - 10); - if (direct==-1) core.ui.drawSLPanel(core.status.event.data + 10); - return; - } - - // 浏览地图 - 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); - return; - } + return core.actions.onmousewheel(direct); } /////////// 键盘、鼠标事件相关 END /////////// - - - /////////// 寻路代码相关 /////////// ////// 清除自动寻路路线 ////// core.prototype.clearAutomaticRouteNode = function (x, y) { - if (core.status.event.id==null) - core.canvas.ui.clearRect(x * 32 + 5, y * 32 + 5, 27, 27); + core.control.clearAutomaticRouteNode(x,y); } ////// 停止自动寻路操作 ////// core.prototype.stopAutomaticRoute = function () { - if (!core.status.played) { - return; - } - core.status.automaticRoute.autoHeroMove = false; - core.status.automaticRoute.autoStep = 0; - core.status.automaticRoute.destStep = 0; - core.status.automaticRoute.movedStep = 0; - core.status.automaticRoute.autoStepRoutes = []; - core.status.automaticRoute.destX=null; - core.status.automaticRoute.destY=null; - core.status.automaticRoute.lastDirection = null; - core.stopHero(); - if (core.status.automaticRoute.moveStepBeforeStop.length==0) - core.canvas.ui.clearRect(0, 0, 416, 416); + core.control.stopAutomaticRoute(); } ////// 继续剩下的自动寻路操作 ////// core.prototype.continueAutomaticRoute = function () { - // 此函数只应由events.afterOpenDoor和events.afterBattle调用 - var moveStep = core.status.automaticRoute.moveStepBeforeStop; - //core.status.automaticRoute.moveStepBeforeStop = []; - if(moveStep.length===0 || (moveStep.length===1 && moveStep[0].step===1)) { - core.status.automaticRoute.moveStepBeforeStop = []; - } - else { - core.setAutoHeroMove(moveStep); - } + core.control.continueAutomaticRoute(); } ////// 清空剩下的自动寻路列表 ////// core.prototype.clearContinueAutomaticRoute = function () { - core.canvas.ui.clearRect(0, 0, 416, 416); - core.status.automaticRoute.moveStepBeforeStop=[]; + core.control.clearContinueAutomaticRoute(); } ////// 设置自动寻路路线 ////// core.prototype.setAutomaticRoute = function (destX, destY, stepPostfix) { - if (!core.status.played || core.status.lockControl) { - return; - } - // 正在寻路中 - if (core.status.automaticRoute.autoHeroMove) { - var lastX = core.status.automaticRoute.destX, lastY=core.status.automaticRoute.destY; - core.stopAutomaticRoute(); - if (lastX==destX && lastY==destY) { - core.status.automaticRoute.moveDirectly = true; - setTimeout(function () { - if (core.status.automaticRoute.moveDirectly && core.status.heroMoving==0) { - if (core.canMoveDirectly(destX, destY)) { - 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.status.route.push("move:"+destX+":"+destY); - } - } - core.status.automaticRoute.moveDirectly = false; - }, 100); - } - return; - } - if (destX == core.status.hero.loc.x && destY == core.status.hero.loc.y && stepPostfix.length==0) { - if (core.timeout.turnHeroTimeout==null) { - core.timeout.turnHeroTimeout = setTimeout(function() { - core.turnHero(); - clearTimeout(core.timeout.turnHeroTimeout); - core.timeout.turnHeroTimeout = null; - }, 250); - } - else { - clearTimeout(core.timeout.turnHeroTimeout); - core.timeout.turnHeroTimeout = null; - core.getNextItem(); - } - return; - } - var step = 0; - var tempStep = null; - var moveStep; - if (!(moveStep = core.automaticRoute(destX, destY))) { - if (destX == core.status.hero.loc.x && destY == core.status.hero.loc.y){ - moveStep=[]; - } else { - core.canvas.ui.clearRect(0, 0, 416, 416); - return; - } - } - moveStep=moveStep.concat(stepPostfix); - core.status.automaticRoute.destX=destX; - core.status.automaticRoute.destY=destY; - core.canvas.ui.save(); - core.canvas.ui.clearRect(0, 0, 416, 416); - core.canvas.ui.fillStyle = '#bfbfbf'; - core.canvas.ui.strokeStyle = '#bfbfbf'; - core.canvas.ui.lineWidth = 8; - for (var m = 0; m < moveStep.length; m++) { - if (tempStep == null) { - step++; - tempStep = moveStep[m].direction; - } - else if (tempStep == moveStep[m].direction) { - step++; - } - else { - //core.status.automaticRoutingTemp.moveStep.push({'direction': tempStep, 'step': step}); - core.status.automaticRoute.autoStepRoutes.push({'direction': tempStep, 'step': step}); - step = 1; - tempStep = moveStep[m].direction; - } - if (m == moveStep.length - 1) { - // core.status.automaticRoutingTemp.moveStep.push({'direction': tempStep, 'step': step}); - core.status.automaticRoute.autoStepRoutes.push({'direction': tempStep, 'step': step}); - core.canvas.ui.fillRect(moveStep[m].x * 32 + 10, moveStep[m].y * 32 + 10, 12, 12); - } - else { - core.canvas.ui.beginPath(); - if (core.isset(moveStep[m + 1]) && tempStep != moveStep[m + 1].direction) { - if (tempStep == 'up' && moveStep[m + 1].direction == 'left' || tempStep == 'right' && moveStep[m + 1].direction == 'down') { - core.canvas.ui.moveTo(moveStep[m].x * 32 + 5, moveStep[m].y * 32 + 16); - core.canvas.ui.lineTo(moveStep[m].x * 32 + 16, moveStep[m].y * 32 + 16); - core.canvas.ui.lineTo(moveStep[m].x * 32 + 16, moveStep[m].y * 32 + 27); - } - else if (tempStep == 'up' && moveStep[m + 1].direction == 'right' || tempStep == 'left' && moveStep[m + 1].direction == 'down') { - core.canvas.ui.moveTo(moveStep[m].x * 32 + 27, moveStep[m].y * 32 + 16); - core.canvas.ui.lineTo(moveStep[m].x * 32 + 16, moveStep[m].y * 32 + 16); - core.canvas.ui.lineTo(moveStep[m].x * 32 + 16, moveStep[m].y * 32 + 27); - } - else if (tempStep == 'left' && moveStep[m + 1].direction == 'up' || tempStep == 'down' && moveStep[m + 1].direction == 'right') { - core.canvas.ui.moveTo(moveStep[m].x * 32 + 27, moveStep[m].y * 32 + 16); - core.canvas.ui.lineTo(moveStep[m].x * 32 + 16, moveStep[m].y * 32 + 16); - core.canvas.ui.lineTo(moveStep[m].x * 32 + 16, moveStep[m].y * 32 + 5); - } - else if (tempStep == 'right' && moveStep[m + 1].direction == 'up' || tempStep == 'down' && moveStep[m + 1].direction == 'left') { - core.canvas.ui.moveTo(moveStep[m].x * 32 + 5, moveStep[m].y * 32 + 16); - core.canvas.ui.lineTo(moveStep[m].x * 32 + 16, moveStep[m].y * 32 + 16); - core.canvas.ui.lineTo(moveStep[m].x * 32 + 16, moveStep[m].y * 32 + 5); - } - core.canvas.ui.stroke(); - continue; - } - switch (tempStep) { - case 'up': - case 'down': - core.canvas.ui.beginPath(); - core.canvas.ui.moveTo(moveStep[m].x * 32 + 16, moveStep[m].y * 32 + 5); - core.canvas.ui.lineTo(moveStep[m].x * 32 + 16, moveStep[m].y * 32 + 27); - core.canvas.ui.stroke(); - break; - case 'left': - case 'right': - core.canvas.ui.beginPath(); - core.canvas.ui.moveTo(moveStep[m].x * 32 + 5, moveStep[m].y * 32 + 16); - core.canvas.ui.lineTo(moveStep[m].x * 32 + 27, moveStep[m].y * 32 + 16); - core.canvas.ui.stroke(); - break; - } - } - } - core.canvas.ui.restore(); - - // 立刻移动 - core.setAutoHeroMove(); - + core.control.setAutomaticRoute(destX,destY,stepPostfix); } ////// 自动寻路算法,找寻最优路径 ////// core.prototype.automaticRoute = function (destX, destY) { - var startX = core.getHeroLoc('x'); - var startY = core.getHeroLoc('y'); - var scan = { - 'up': {'x': 0, 'y': -1}, - 'left': {'x': -1, 'y': 0}, - 'down': {'x': 0, 'y': 1}, - 'right': {'x': 1, 'y': 0} - }; - var queue = []; - var nowDeep = 0; - var route = []; - var ans = [] - - if (destX == startX && destY == startY) return false; - queue.push(13 * startX + startY); - queue.push(-1); - route[13 * startX + startY] = ''; - - while (queue.length != 1) { - var f = queue.shift(); - if (f===-1) {nowDeep+=1;queue.push(-1);continue;} - var deep = ~~(f/169); - if (deep!==nowDeep) {queue.push(f);continue;} - f=f%169; - var nowX = parseInt(f / 13), nowY = f % 13; - var nowIsArrow = false, nowId, nowBlock = core.getBlock(nowX,nowY); - /* - if (nowBlock!=null){ - nowId = nowBlock.block.event.id; - nowIsArrow = nowId.slice(0, 5).toLowerCase() == 'arrow'; - } - */ - for (var direction in scan) { - /* - if(nowIsArrow){ - var nowArrow = nowId.slice(5).toLowerCase(); - if (direction != nowArrow) continue; - } - */ - if (!core.canMoveHero(nowX, nowY, direction)) - continue; - - var nx = nowX + scan[direction].x; - var ny = nowY + scan[direction].y; - - if (nx<0 || nx>12 || ny<0 || ny>12) continue; - - var nid = 13 * nx + ny; - - if (core.isset(route[nid])) continue; - - var deepAdd=1; - - var nextId, nextBlock = core.getBlock(nx,ny); - if (nextBlock!=null){ - nextId = nextBlock.block.event.id; - /* - // 遇到单向箭头处理 - var isArrow = nextId.slice(0, 5).toLowerCase() == 'arrow'; - if(isArrow){ - var nextArrow = nextId.slice(5).toLowerCase(); - if ( (scan[direction].x + scan[nextArrow].x) == 0 && (scan[direction].y + scan[nextArrow].y) == 0 ) continue; - } - */ - // 绕过亮灯(因为只有一次通行机会很宝贵) - if(nextId == "light") deepAdd=100; - // 绕过路障 - if (nextId.substring(nextId.length-3)=="Net") deepAdd=core.values.lavaDamage; - // 绕过血瓶 - if (!core.flags.potionWhileRouting && nextId.substring(nextId.length-6)=="Potion") deepAdd=20; - // 绕过传送点 - if (nextBlock.block.event.trigger == 'changeFloor') deepAdd = 10; - } - if (core.status.checkBlock.damage[nid]>0) - deepAdd = core.status.checkBlock.damage[nid]; - - if (nx == destX && ny == destY) { - route[nid] = direction; - break; - } - if (core.noPassExists(nx, ny)) - continue; - - route[nid] = direction; - queue.push(169*(nowDeep+deepAdd)+nid); - } - if (core.isset(route[13 * destX + destY])) break; - } - - if (!core.isset(route[13 * destX + destY])) { - return false; - } - - var nowX = destX, nowY = destY; - while (nowX != startX || nowY != startY) { - var dir = route[13 * nowX + nowY]; - ans.push({'direction': dir, 'x': nowX, 'y': nowY}); - nowX -= scan[dir].x; - nowY -= scan[dir].y; - } - - ans.reverse(); - return ans; + return core.control.automaticRoute(destX, destY); } ////// 显示离散的寻路点 ////// core.prototype.fillPosWithPoint = function (pos) { - core.fillRect('ui', pos.x*32+12,pos.y*32+12,8,8, '#bfbfbf'); + core.control.fillPosWithPoint(pos); } -/* -////// 清除已经寻路过的部分 ////// -core.prototype.clearStepPostfix = function () { - if(core.status.mouseOutCheck >0){ - core.status.mouseOutCheck--; - window.setTimeout(core.clearStepPostfix,1000); - return; - } - core.status.holdingPath=0; - if(core.status.stepPostfix.length>0){ - core.status.stepPostfix=[]; - core.canvas.ui.clearRect(0, 0, 416,416); - core.canvas.ui.restore(); - } -} -*/ - /////////// 寻路代码相关 END /////////// @@ -1852,406 +431,82 @@ core.prototype.clearStepPostfix = function () { ////// 设置勇士的自动行走路线 ////// core.prototype.setAutoHeroMove = function (steps) { - steps=steps||core.status.automaticRoute.autoStepRoutes; - if (steps.length == 0) { - return; - } - core.status.automaticRoute.autoStepRoutes=steps; - core.status.automaticRoute.autoHeroMove = true; - core.status.automaticRoute.autoStep = 1; - core.status.automaticRoute.destStep = steps[0].step; - core.moveHero(steps[0].direction); + core.control.setAutoHeroMove(steps); } ////// 设置行走的效果动画 ////// core.prototype.setHeroMoveInterval = function (direction, x, y, callback) { - if (core.status.heroMoving>0) { - return; - } - core.status.heroMoving=1; - // core.status.heroMoving = true; - // var moveStep = 0; - var scan = { - 'up': {'x': 0, 'y': -1}, - 'left': {'x': -1, 'y': 0}, - 'down': {'x': 0, 'y': 1}, - 'right': {'x': 1, 'y': 0} - }; - core.interval.heroMoveInterval = window.setInterval(function () { - core.status.heroMoving++; - /* - if (moveStep<=4) { - core.drawHero(direction, x, y, 'leftFoot', 4*moveStep*scan[direction].x, 4*moveStep*scan[direction].y); - } - else if (moveStep<8) { - core.drawHero(direction, x, y, 'rightFoot', 4*moveStep*scan[direction].x, 4*moveStep*scan[direction].y); - } - */ - if (core.status.heroMoving==8) { - core.setHeroLoc('x', x+scan[direction].x); - 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'); - clearInterval(core.interval.heroMoveInterval); - core.status.heroMoving = 0; - if (core.isset(callback)) callback(); - } - }, 12.5 / core.status.replay.speed); + core.control.setHeroMoveInterval(direction, x, y, callback); } ////// 实际每一步的行走过程 ////// core.prototype.moveAction = function (callback) { - if (core.interval.openDoorAnimate!=null) return; // 开门判断 - if (core.status.heroMoving>0) return; - var scan = { - 'up': {'x': 0, 'y': -1}, - 'left': {'x': -1, 'y': 0}, - 'down': {'x': 0, 'y': 1}, - 'right': {'x': 1, 'y': 0} - }; - var direction = core.getHeroLoc('direction'); - var x = core.getHeroLoc('x'); - var y = core.getHeroLoc('y'); - var noPass = core.noPass(x + scan[direction].x, y + scan[direction].y), canMove = core.canMoveHero(); - if (noPass || !canMove) { - if (core.status.event.id!='ski') - core.status.route.push(direction); - core.status.automaticRoute.moveStepBeforeStop = []; - if (canMove) // 非箭头:触发 - core.trigger(x + scan[direction].x, y + scan[direction].y); - core.drawHero(direction, x, y, 'stop'); - - // core.clearContinueAutomaticRoute(); - if (core.status.automaticRoute.moveStepBeforeStop.length==0) { - core.clearContinueAutomaticRoute(); - core.stopAutomaticRoute(); - } - - /* - if (core.status.automaticRoute.autoHeroMove) { - - core.status.automaticRoute.movedStep++; - if (core.status.automaticRoute.destStep == core.status.automaticRoute.movedStep) { - core.status.automaticRoute.autoHeroMove = false; - core.status.automaticRoute.destStep = 0; - core.status.automaticRoute.movedStep = 0; - core.status.automaticRoute.moveStepBeforeStop=[]; - core.stopAutomaticRoute(); - } - } - else { - // core.status.heroStop = true; - core.stopHero(); - } - */ - if (core.isset(callback)) - callback(); - } - else { - core.setHeroMoveInterval(direction, x, y, function () { - if (core.status.automaticRoute.autoHeroMove) { - core.status.automaticRoute.movedStep++; - core.status.automaticRoute.lastDirection = core.getHeroLoc('direction'); - if (core.status.automaticRoute.destStep == core.status.automaticRoute.movedStep) { - if (core.status.automaticRoute.autoStep == core.status.automaticRoute.autoStepRoutes.length) { - core.clearContinueAutomaticRoute(); - core.stopAutomaticRoute(); - } - else { - core.status.automaticRoute.movedStep = 0; - core.status.automaticRoute.destStep = core.status.automaticRoute.autoStepRoutes[core.status.automaticRoute.autoStep].step; - core.setHeroLoc('direction', core.status.automaticRoute.autoStepRoutes[core.status.automaticRoute.autoStep].direction); - core.status.automaticRoute.autoStep++; - } - } - } - else if (core.status.heroStop) { - core.drawHero(core.getHeroLoc('direction'), core.getHeroLoc('x'), core.getHeroLoc('y'), 'stop'); - } - if (core.status.event.id!='ski') - core.status.route.push(direction); - core.trigger(core.getHeroLoc('x'), core.getHeroLoc('y')); - core.checkBlock(); - if (core.isset(callback)) callback(); - }); - } + core.control.moveAction(callback); } ////// 转向 ////// core.prototype.turnHero = function() { - if (core.status.hero.loc.direction == 'up') core.status.hero.loc.direction = 'right'; - 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.canvas.ui.clearRect(0, 0, 416, 416); - core.status.route.push("turn"); + core.control.turnHero(); } ////// 勇士能否前往某方向 ////// core.prototype.canMoveHero = function(x,y,direction,floorId) { - if (!core.isset(x)) x=core.getHeroLoc('x'); - if (!core.isset(y)) y=core.getHeroLoc('y'); - if (!core.isset(direction)) direction=core.getHeroLoc('direction'); - if (!core.isset(floorId)) floorId=core.status.floorId; - - // 检查当前块的cannotMove - if (core.isset(core.floors[floorId].cannotMove)) { - var cannotMove = core.floors[floorId].cannotMove[x+","+y]; - if (core.isset(cannotMove) && cannotMove instanceof Array && cannotMove.indexOf(direction)>=0) - return false; - } - - var nowBlock = core.getBlock(x,y,floorId); - if (nowBlock!=null){ - nowId = nowBlock.block.event.id; - var nowIsArrow = nowId.slice(0, 5).toLowerCase() == 'arrow'; - if(nowIsArrow){ - var nowArrow = nowId.slice(5).toLowerCase(); - if (direction != nowArrow) { - return false; - } - } - } - var scan = { - 'up': {'x': 0, 'y': -1}, - 'left': {'x': -1, 'y': 0}, - 'down': {'x': 0, 'y': 1}, - 'right': {'x': 1, 'y': 0} - }; - var nextBlock = core.getBlock(x+scan[direction].x,y+scan[direction].y,floorId); - if (nextBlock!=null){ - nextId = nextBlock.block.event.id; - // 遇到单向箭头处理 - var isArrow = nextId.slice(0, 5).toLowerCase() == 'arrow'; - if(isArrow){ - var nextArrow = nextId.slice(5).toLowerCase(); - if ( (scan[direction].x + scan[nextArrow].x) == 0 && (scan[direction].y + scan[nextArrow].y) == 0 ) { - return false; - } - } - } - return true; + return core.maps.canMoveHero(x,y,direction,floorId); } ////// 能否瞬间移动 ////// core.prototype.canMoveDirectly = function (destX,destY) { - if (!core.flags.enableMoveDirectly) return false; - - // 中毒状态:不能 - if (core.hasFlag('poison')) return false; - - var fromX = core.getHeroLoc('x'), fromY = core.getHeroLoc('y'); - if (fromX==destX&&fromY==destY) return false; - - if (core.getBlock(fromX,fromY)!=null||core.status.checkBlock.damage[13*fromX+fromY]>0) - return false; - - // BFS - var visited=[], queue=[]; - visited[13*fromX+fromY]=true; - queue.push(13*fromX+fromY); - - var directions = [[-1,0],[1,0],[0,1],[0,-1]]; - while (queue.length>0) { - var now=queue.shift(), nowX=parseInt(now/13), nowY=now%13; - - for (var dir in directions) { - var nx=nowX+directions[dir][0], ny=nowY+directions[dir][1]; - if (nx<0||nx>=13||ny<0||ny>=13||visited[13*nx+ny]||core.getBlock(nx,ny)!=null||core.status.checkBlock.damage[13*nx+ny]>0) continue; - if (nx==destX&&ny==destY) return true; - visited[13*nx+ny]=true; - queue.push(13*nx+ny); - } - } - return false; + return core.maps.canMoveDirectly(destX, destY); } ////// 让勇士开始移动 ////// core.prototype.moveHero = function (direction, callback) { - // 如果正在移动,直接return - if (core.status.heroMoving>0) return; - if (core.isset(direction)) - core.setHeroLoc('direction', direction); - if (!core.isset(callback)) { // 如果不存在回调函数,则使用heroMoveTrigger - core.status.heroStop = false; - core.status.automaticRoute.moveDirectly = false; - - var doAction = function () { - if (!core.status.heroStop) { - core.moveAction(); - setTimeout(doAction, 50); - } - else { - core.stopHero(); - } - } - doAction(); - } - else { // 否则,只向某个方向移动一步,然后调用callback - core.moveAction(function () { - callback(); - }) - } + core.control.moveHero(direction, callback); } /////// 使用事件让勇士移动。这个函数将不会触发任何事件 ////// core.prototype.eventMoveHero = function(steps, time, callback) { - - time = time || 100; - - core.clearMap('ui', 0, 0, 416, 416); - core.setAlpha('ui', 1.0); - - // 要运行的轨迹:将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)core.status.automaticRoute.moveStepBeforeStop[0].step-=core.status.automaticRoute.movedStep; - } - - core.stopAutomaticRoute(); - var speed=30; - if (needKey) { - var key = id.replace("Door", "Key"); - if (!core.hasItem(key)) { - if (key != "specialKey") - core.drawTip("你没有" + core.material.items[key].name); - else core.drawTip("无法开启此门"); - core.clearContinueAutomaticRoute(); - return; - } - core.autosave(true); - core.removeItem(key); - } - - // open - core.playSound("door.ogg"); - var state = 0; - var doorId = id; - if (!(doorId.substring(doorId.length-4)=="Door")) { - doorId=doorId+"Door"; - speed=100; - } - var door = core.material.icons.animates[doorId]; - core.status.replay.animate=true; - core.interval.openDoorAnimate = window.setInterval(function () { - state++; - if (state == 4) { - clearInterval(core.interval.openDoorAnimate); - core.interval.openDoorAnimate=null; - core.removeBlock(x, y); - core.status.replay.animate=false; - core.events.afterOpenDoor(id,x,y,callback); - return; - } - 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); - }, speed) + core.events.openDoor(id, x, y, needKey, callback); } ////// 战斗 ////// core.prototype.battle = function (id, x, y, force, callback) { - if (core.status.automaticRoute.moveStepBeforeStop.length==0) { - core.status.automaticRoute.moveStepBeforeStop=core.status.automaticRoute.autoStepRoutes.slice(core.status.automaticRoute.autoStep-1,core.status.automaticRoute.autoStepRoutes.length); - if (core.status.automaticRoute.moveStepBeforeStop.length>=1)core.status.automaticRoute.moveStepBeforeStop[0].step-=core.status.automaticRoute.movedStep; - } - core.stopHero(); - core.stopAutomaticRoute(); - - var damage = core.enemys.getDamage(id); - // 非强制战斗 - if (damage >= core.status.hero.hp && !force) { - core.drawTip("你打不过此怪物!"); - core.clearContinueAutomaticRoute(); - return; - } - - if (!core.isset(core.status.event.id)) // 自动存档 - core.autosave(true); - - if (core.flags.battleAnimate&&!core.status.replay.replaying) { - core.waitHeroToStop(function() { - core.ui.drawBattleAnimate(id, function() { - core.afterBattle(id, x, y, callback); - }); - }); - } - else { - - if (core.flags.equipment && core.getFlag('sword', 'sword0')!='sword0') { - core.playSound('zone.ogg'); - core.drawAnimate('sword', x, y); - } - else { - core.playSound('attack.ogg'); - core.drawAnimate('hand', x, y); - } - - core.afterBattle(id, x, y, callback); - } + core.events.battle(id,x,y,force,callback); } ////// 战斗完毕 ////// core.prototype.afterBattle = function(id, x, y, callback) { - core.status.hero.hp -= core.enemys.getDamage(id); - if (core.status.hero.hp<=0) { - core.status.hero.hp=0; - core.updateStatusBar(); - core.events.lose('battle'); - return; - } - var money = core.material.enemys[id].money; - if (core.hasItem('coin')) money *= 2; - if (core.hasFlag('curse')) money=0; - core.status.hero.money += money; - var experience = core.material.enemys[id].experience; - if (core.hasFlag('curse')) experience=0; - core.status.hero.experience += experience; - if (core.isset(x) && core.isset(y)) { - core.removeBlock(x, y); - core.canvas.event.clearRect(32 * x, 32 * y, 32, 32); - } - // core.updateStatusBar(); - var hint = "打败 " + core.material.enemys[id].name; - if (core.flags.enableMoney) - hint += ",金币+" + money; - if (core.flags.enableExperience) - hint += ",经验+" + experience; - core.drawTip(hint); - - // 打完怪物,触发事件 - core.events.afterBattle(id,x,y,callback); - + core.events.afterBattle(id, x, y, callback); } ////// 触发(x,y)点的事件 ////// core.prototype.trigger = function (x, y) { - 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 && !(core.isset(mapBlocks[b].enable) && !mapBlocks[b].enable)) { // 启用事件 - noPass = mapBlocks[b].event && mapBlocks[b].event.noPass; - if (noPass) { - core.clearAutomaticRouteNode(x, y); - } - if (core.isset(mapBlocks[b].event) && core.isset(mapBlocks[b].event.trigger)) { - var trigger = mapBlocks[b].event.trigger; - - // 转换楼层能否穿透 - if (trigger=='changeFloor' && !noPass) { - var canCross = core.flags.portalWithoutTrigger; - if (core.isset(mapBlocks[b].event.data) && core.isset(mapBlocks[b].event.data.portalWithoutTrigger)) - canCross=mapBlocks[b].event.data.portalWithoutTrigger; - if (canCross) { - if (core.status.replay.replaying) { - if (core.status.replay.toReplay[0]=='no') { - core.status.replay.toReplay.shift(); - core.status.route.push("no"); - continue; - } - } - else if (core.status.automaticRoute.autoHeroMove || core.status.automaticRoute.autoStepcore.floorIds.indexOf(core.status.floorId)) - core.status.hero.flyRange.push(floorId); - else - core.status.hero.flyRange.unshift(floorId); - } - - window.setTimeout(function () { - - 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'; - else core.statusBar.floor.style.fontStyle = 'normal'; - - // 更改BGM - if (core.isset(core.floors[floorId].bgm)) { - core.playBgm(core.floors[floorId].bgm); - } - - // 不存在事件时,更改画面色调 - if (core.status.event.id == null) { - // 默认画面色调 - if (core.isset(core.floors[floorId].color)) { - var color = core.floors[floorId].color; - - // 直接变色 - core.dom.curtain.style.background = core.arrayToRGB(color); - if (core.isset(color[3])) - core.dom.curtain.style.opacity = color[3]; - else core.dom.curtain.style.opacity=1; - core.status.curtainColor = color; - } - else { - core.dom.curtain.style.background = "#000000"; - core.dom.curtain.style.opacity = 0; - } - } - - // 更改天气 - if (core.isset(core.floors[floorId].weather)) { - core.setWeather(core.floors[floorId].weather[0], core.floors[floorId].weather[1]) - } - else core.setWeather(); - - core.drawMap(floorId, function () { - setTimeout(function() { - if (core.isset(heroLoc.direction)) - 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.updateStatusBar(); - - var changed = function () { - core.unLockControl(); - core.status.replay.animate=false; - core.events.afterChangeFloor(floorId); - if (core.isset(callback)) callback(); - } - if (displayAnimate) { - core.mapChangeAnimate('hide', time/4, function () { - changed(); - }); - } - else { - changed(); - } - }, 25) - }); - } - core.playSound('floor.mp3'); - if (displayAnimate) { - core.mapChangeAnimate('show', time/2, function () { - changing(); - }); - } - else { - changing(); - } - }, 25); -} - -////// 地图切换动画效果 ////// -core.prototype.mapChangeAnimate = function (mode, time, callback) { - if (mode == 'show') { - core.show(core.dom.floorMsgGroup, time, function () { - callback(); - }); - } - else { - core.hide(core.dom.floorMsgGroup, time, function () { - callback(); - }); - } + core.events.changeFloor(floorId, stair, heroLoc, time, callback); } ////// 清除地图 ////// core.prototype.clearMap = function (map, x, y, width, height) { - if (map == 'all') { - for (var m in core.canvas) { - core.canvas[m].clearRect(0, 0, 416, 416); - } - } - else { - core.canvas[map].clearRect(x, y, width, height); - } + core.ui.clearMap(map, x, y, width, height); } ////// 在某个canvas上绘制一段文字 ////// core.prototype.fillText = function (map, text, x, y, style, font) { - if (core.isset(style)) { - core.setFillStyle(map, style); - } - if (core.isset(font)) { - core.setFont(map, font); - } - core.canvas[map].fillText(text, x, y); + core.ui.fillText(map, text, x, y, style, font); } ////// 在某个canvas上绘制一个矩形 ////// core.prototype.fillRect = function (map, x, y, width, height, style) { - if (core.isset(style)) { - core.setFillStyle(map, style); - } - core.canvas[map].fillRect(x, y, width, height); + core.ui.fillRect(map, x, y, width, height, style) } ////// 在某个canvas上绘制一个矩形的边框 ////// core.prototype.strokeRect = function (map, x, y, width, height, style, lineWidth) { - if (core.isset(style)) { - core.setStrokeStyle(map, style); - } - if (core.isset(lineWidth)) { - core.setLineWidth(map, lineWidth); - } - core.canvas[map].strokeRect(x, y, width, height); + core.ui.strokeRect(map, x, y, width, height, style, lineWidth) } ////// 在某个canvas上绘制一条线 ////// core.prototype.drawLine = function (map, x1, y1, x2, y2, style, lineWidth) { - if (core.isset(style)) { - core.setStrokeStyle(map, style); - } - if (core.isset(lineWidth)) { - core.setLineWidth(map, lineWidth); - } - core.canvas[map].beginPath(); - core.canvas[map].moveTo(x1, y1); - core.canvas[map].lineTo(x2, y2); - core.canvas[map].closePath(); - core.canvas[map].stroke(); + core.ui.drawLine(map, x1, y1, x2, y2, style, lineWidth); } ////// 设置某个canvas的文字字体 ////// core.prototype.setFont = function (map, font) { - core.canvas[map].font = font; + core.ui.setFont(map, font); } ////// 设置某个canvas的线宽度 ////// core.prototype.setLineWidth = function (map, lineWidth) { - if (map == 'all') { - for (var m in core.canvas) { - core.canvas[m].lineWidth = lineWidth; - } - } - core.canvas[map].lineWidth = lineWidth; + core.ui.setLineWidth(map, lineWidth); } ////// 保存某个canvas状态 ////// core.prototype.saveCanvas = function (map) { - core.canvas[map].save(); + core.ui.saveCanvas(map); } ////// 加载某个canvas状态 ////// core.prototype.loadCanvas = function (map) { - core.canvas[map].restore(); + core.ui.loadCanvas(map); } ////// 设置某个canvas边框属性 ////// core.prototype.setStrokeStyle = function (map, style) { - if (map == 'all') { - for (var m in core.canvas) { - core.canvas[m].strokeStyle = style; - } - } - else { - core.canvas[map].strokeStyle = style; - } + core.ui.setStrokeStyle(map, style); } ////// 设置某个canvas的alpha值 ////// core.prototype.setAlpha = function (map, alpha) { - if (map == 'all') { - for (var m in core.canvas) { - core.canvas[m].globalAlpha = alpha; - } - } - else core.canvas[map].globalAlpha = alpha; + core.ui.setAlpha(map, alpha); } ////// 设置某个canvas的透明度 ////// core.prototype.setOpacity = function (map, opacity) { - if (map == 'all') { - for (var m in core.canvas) { - core.canvas[m].canvas.style.opacity = opacity; - } - } - else core.canvas[map].canvas.style.opacity = opacity; + core.ui.setOpacity(map, opacity); } ////// 设置某个canvas的绘制属性(如颜色等) ////// core.prototype.setFillStyle = function (map, style) { - if (map == 'all') { - for (var m in core.canvas) { - core.canvas[m].fillStyle = style; - } - } - else { - core.canvas[map].fillStyle = style; - } + core.ui.setFillStyle(map, style); } ////// 绘制某张地图 ////// core.prototype.drawMap = function (mapName, callback) { - core.clearMap('all'); - core.removeGlobalAnimate(null, null, true); - var drawBg = function(){ - var groundId = core.floors[mapName].defaultGround || "ground"; - var blockIcon = core.material.icons.terrains[groundId]; - var blockImage = core.material.images.terrains; - for (var x = 0; x < 13; x++) { - for (var y = 0; y < 13; y++) { - core.canvas.bg.drawImage(blockImage, 0, blockIcon * 32, 32, 32, x * 32, y * 32, 32, 32); - } - } - // 如果存在png - if (core.isset(core.floors[mapName].png)) { - - var x=0, y=0, size=416; - - var png = core.floors[mapName].png; - - var ratio = size/416; - - if (typeof png == 'string') { - if (core.isset(core.material.images.pngs[png])) { - core.canvas.bg.drawImage(core.material.images.pngs[png], x, y, size, size); - } - } - else if (png instanceof Array) { - png.forEach(function (t) { - if (t.length!=3) return; - var dx=parseInt(t[0]), dy=parseInt(t[1]), p=t[2]; - if (core.isset(dx) && core.isset(dy) && core.isset(core.material.images.pngs[p])) { - dx*=32; dy*=32; - var image = core.material.images.pngs[p]; - core.canvas.bg.drawImage(image, x+dx*ratio, y+dy*ratio, Math.min(size-dx*ratio, ratio*image.width), Math.min(size-dy*ratio, ratio*image.height)); - } - }) - } - } - } - if (main.mode=='editor'){ - main.editor.drawMapBg = function(){ - core.clearMap('bg', 0, 0, 416, 416); - drawBg(); - } - } else { - drawBg(); - } - - core.status.floorId = mapName; - core.status.thisMap = core.status.maps[mapName]; - var drawEvent = function(){ - var mapData = core.status.maps[core.status.floorId]; - var mapBlocks = mapData.blocks; - - var mapArray = core.maps.getMapArray(mapBlocks); - for (var b = 0; b < mapBlocks.length; b++) { - // 事件启用 - var block = mapBlocks[b]; - if (core.isset(block.event) && !(core.isset(block.enable) && !block.enable)) { - if (block.event.cls == 'autotile') { - core.drawAutotile(core.canvas.event, mapArray, block, 32, 0, 0); - } - else { - if (block.event.id!='none') { - 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); - } - } - } - } - } - - if (main.mode=='editor'){ - main.editor.updateMap = function(){ - core.removeGlobalAnimate(null, null, true); - core.clearMap('event', 0, 0, 416, 416); - drawEvent(); - core.setGlobalAnimate(core.values.animateSpeed); - } - } else { - drawEvent(); - } - core.setGlobalAnimate(core.values.animateSpeed); - if (core.isset(callback)) - callback(); + core.maps.drawMap(mapName, callback); } ////// 绘制Autotile ////// core.prototype.drawAutotile = function(ctx, mapArr, block, size, left, top){ - var indexArrs = [ //16种组合的图块索引数组; // 将autotile分割成48块16*16的小块; 数组索引即对应各个小块 - // +----+----+----+----+----+----+ - [10, 9, 4, 3 ], //0 bin:0000 | 1 | 2 | 3 | 4 | 5 | 6 | - [10, 9, 4, 13], //1 bin:0001 +----+----+----+----+----+----+ - [10, 9, 18, 3 ], //2 bin:0010 | 7 | 8 | 9 | 10 | 11 | 12 | - [10, 9, 16, 15], //3 bin:0011 +----+----+----+----+----+----+ - [10, 43, 4, 3 ], //4 bin:0100 | 13 | 14 | 15 | 16 | 17 | 18 | - [10, 31, 4, 25], //5 bin:0101 +----+----+----+----+----+----+ - [10, 7, 2, 3 ], //6 bin:0110 | 19 | 20 | 21 | 22 | 23 | 24 | - [10, 31, 16, 5 ], //7 bin:0111 +----+----+----+----+----+----+ - [48, 9, 4, 3 ], //8 bin:1000 | 25 | 26 | 27 | 28 | 29 | 30 | - [ 8, 9, 4, 1 ], //9 bin:1001 +----+----+----+----+----+----+ - [36, 9, 30, 3 ], //10 bin:1010 | 31 | 32 | 33 | 34 | 35 | 36 | - [36, 9, 6, 15], //11 bin:1011 +----+----+----+----+----+----+ - [46, 45, 4, 3 ], //12 bin:1100 | 37 | 38 | 39 | 40 | 41 | 42 | - [46, 11, 4, 25], //13 bin:1101 +----+----+----+----+----+----+ - [12, 45, 30, 3 ], //14 bin:1110 | 43 | 44 | 45 | 46 | 47 | 48 | - [34, 33, 28, 27] //15 bin:1111 +----+----+----+----+----+----+ - ]; - - var drawBlockByIndex = function(ctx, dx, dy, autotileImg, index, size){ //index为autotile的图块索引1-48 - var sx = 16*((index-1)%6), sy = 16*(~~((index-1)/6)); - ctx.drawImage(autotileImg, sx, sy, 16, 16, dx, dy, size/2, size/2); - } - var getAutotileAroundId = function(currId, x, y){ - if(x<0 || y<0 || x>12 || y>12) return 1; - else return mapArr[y][x]==currId ? 1:0; - } - var checkAround = function(x, y){ // 得到周围四个32*32块(周围每块都包含当前块的1/4,不清楚的话画下图你就明白)的数组索引 - var currId = mapArr[y][x]; - var pointBlock = []; - for(var i=0; i<4; i++){ - var bsum = 0; - var offsetx = i%2, offsety = ~~(i/2); - for(var j=0; j<4; j++){ - var mx = j%2, my = ~~(j/2); - var b = getAutotileAroundId(currId, x+offsetx+mx-1, y+offsety+my-1); - bsum += b*(Math.pow(2, 3-j)); - } - pointBlock.push(bsum); - } - return pointBlock; - } - var getAutotileIndexs = function(x, y){ - var indexArr = []; - var pointBlocks = checkAround(x, y); - for(var i=0; i<4; i++){ - var arr = indexArrs[pointBlocks[i]] - indexArr.push(arr[3-i]); - } - return indexArr; - } - // 开始绘制autotile - var x = block.x, y = block.y; - var pieceIndexs = getAutotileIndexs(x, y); - - //修正四个边角的固定搭配 - if(pieceIndexs[0] == 13){ - if(pieceIndexs[1] == 16) pieceIndexs[1] = 14; - if(pieceIndexs[2] == 31) pieceIndexs[2] = 19; - } - if(pieceIndexs[1] == 18){ - if(pieceIndexs[0] == 15) pieceIndexs[0] = 17; - if(pieceIndexs[3] == 36) pieceIndexs[3] = 24; - } - if(pieceIndexs[2] == 43){ - if(pieceIndexs[0] == 25) pieceIndexs[0] = 37; - if(pieceIndexs[3] == 46) pieceIndexs[3] = 44; - } - if(pieceIndexs[3] == 48){ - if(pieceIndexs[1] == 30) pieceIndexs[1] = 42; - if(pieceIndexs[2] == 45) pieceIndexs[2] = 47; - } - for(var i=0; i<4; i++){ - var index = pieceIndexs[i]; - var dx = x*size + size/2*(i%2), dy = y*size + size/2*(~~(i/2)); - drawBlockByIndex(ctx, dx+left, dy+top, core.material.images['autotile'][block.event.id], index, size); - } + core.maps.drawAutotile(ctx, mapArr, block, size, left, top); } ////// 某个点是否不可通行 ////// 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; + return core.maps.noPassExists(x,y,floorId); } ////// 某个点是否在区域内且不可通行 ////// core.prototype.noPass = function (x, y) { - return x<0 || x>12 || y<0 || y>12 || core.noPassExists(x,y); + return core.maps.noPass(x,y); } ////// 某个点是否存在NPC ////// 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'; + return core.maps.npcExists(x, y, 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' && (core.isset(id)?block.block.event.id==id:true); + return core.maps.terrainExists(x, y, id, floorId); } ////// 某个点是否存在楼梯 ////// 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'); + return core.maps.stairExists(x, y, floorId); } ////// 当前位置是否在楼梯边 ////// 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); + return core.maps.nearStair(); } ////// 某个点是否存在(指定的)怪物 ////// 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' && (core.isset(id)?block.block.event.id==id:true); + return core.maps.enemyExists(x, y, id, floorId); } ////// 获得某个点的block ////// core.prototype.getBlock = function (x, y, floorId, needEnable) { - 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= core.values.animateSpeed * 2 / animateValue) { - animateCurrent++; - animateTime = 0; - if (animateCurrent>=animateValue) animateCurrent=0; - } - - // 已经移动完毕,消失 - if (moveSteps.length==0) { - if (immediateHide) opacityVal=0; - else opacityVal -= 0.06; - core.setOpacity('animate', opacityVal); - core.clearMap('animate', nowX, nowY, 32, 32); - core.canvas.animate.drawImage(blockImage, animateCurrent * 32, blockIcon * 32, 32, 32, nowX, nowY, 32, 32); - if (opacityVal<=0) { - clearInterval(animate); - core.loadCanvas('animate'); - core.clearMap('animate', 0, 0, 416, 416); - core.setOpacity('animate', 1); - core.status.replay.animate=false; - if (core.isset(callback)) callback(); - } - } - else { - // 移动中 - step++; - nowX+=scan[moveSteps[0]].x*2; - nowY+=scan[moveSteps[0]].y*2; - core.clearMap('animate', nowX-32, nowY-32, 96, 96); - // 绘制 - core.canvas.animate.drawImage(blockImage, animateCurrent * 32, blockIcon * 32, 32, 32, nowX, nowY, 32, 32); - if (step==16) { - // 该移动完毕,继续 - step=0; - moveSteps.shift(); - } - } - }, time / 16 / core.status.replay.speed); + core.maps.moveBlock(x,y,steps,time,immediateHide,callback) } ////// 显示/隐藏某个块时的动画效果 ////// core.prototype.animateBlock = function (loc,type,time,callback) { - if (type!='hide') type='show'; - - //clearInterval(core.interval.tipAnimate); - core.saveCanvas('animate'); - core.clearMap('animate', 0, 0, 416, 416); - - if (typeof loc[0] == 'number' && typeof loc[1] == 'number') - loc = [loc]; - - var list = []; - loc.forEach(function (t) { - var block = core.getBlock(t[0],t[1],core.status.floorId,false); - if (block==null) return; - block=block.block; - list.push({ - 'x': t[0], 'y': t[1], - 'blockIcon': core.material.icons[block.event.cls][block.event.id], - 'blockImage': core.material.images[block.event.cls] - }) - }) - - if (list.length==0) { - if (core.isset(callback)) callback(); - return; - } - - core.status.replay.animate=true; - var draw = function () { - list.forEach(function (t) { - core.canvas.animate.drawImage(t.blockImage, 0, t.blockIcon * 32, 32, 32, t.x * 32, t.y * 32, 32, 32); - }) - } - - var opacityVal = 0; - if (type=='hide') opacityVal=1; - - core.setOpacity('animate', opacityVal); - draw(); - - var animate = window.setInterval(function () { - if (type=='show') opacityVal += 0.1; - else opacityVal -= 0.1; - core.setOpacity('animate', opacityVal); - core.clearMap('animate',0,0,416,416); - - // core.canvas.animate.drawImage(blockImage, 0, blockIcon * 32, 32, 32, block.x * 32, block.y * 32, 32, 32); - draw(); - if (opacityVal >=1 || opacityVal<=0) { - clearInterval(animate); - core.loadCanvas('animate'); - core.clearMap('animate', 0, 0, 416, 416); - core.setOpacity('animate', 1); - core.status.replay.animate=false; - if (core.isset(callback)) callback(); - } - }, time / 10 / core.status.replay.speed); + core.maps.animateBlock(loc,type,time,callback) } ////// 将某个块从禁用变成启用状态 ////// core.prototype.showBlock = 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.syncGlobalAnimate(); - } - core.updateStatusBar(); - } + core.maps.showBlock(x,y,floodId); } ////// 将某个块从启用变成禁用状态 ////// core.prototype.removeBlock = function (x, y, floorId) { - floorId = floorId || core.status.floorId; - - var block = core.getBlock(x,y,floorId,false); - if (block==null) return; // 不存在 - - var index=block.index; - - // 删除动画,清除地图 - if (floorId==core.status.floorId) { - core.removeGlobalAnimate(x, y); - core.canvas.event.clearRect(x * 32, y * 32, 32, 32); - } - - // 删除Index - core.removeBlockById(index, floorId); - core.updateFg(); + core.maps.removeBlock(x,y,floorId); } ////// 根据block的索引删除该块 ////// core.prototype.removeBlockById = function (index, floorId) { - - var blocks = core.status.maps[floorId].blocks; - var x=blocks[index].x, y=blocks[index].y; - - // 检查该点是否存在事件 - 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; - } - blocks[index].enable = false; + core.maps.removeBlockById(index, floorId); } ////// 一次性删除多个block ////// core.prototype.removeBlockByIds = function (floorId, ids) { - ids.sort(function (a,b) {return b-a}).forEach(function (id) { - core.removeBlockById(id, floorId); - }); + core.maps.removeBlockByIds(floorId, ids); } ////// 添加一个全局动画 ////// core.prototype.addGlobalAnimate = function (animateMore, x, y, loc, image) { - if (main.mode=='editor' && main.editor.disableGlobalAnimate) return; - if (animateMore == 2) { - core.status.twoAnimateObjs.push({ - 'x': x, - 'y': y, - 'status': 0, - 'loc': loc, - 'image': image - }); - } - else if (animateMore == 4) { - core.status.fourAnimateObjs.push({ - 'x': x, - 'y': y, - 'status': 0, - 'loc': loc, - 'image': image - }); - } + core.maps.addGlobalAnimate(animateMore, x, y, loc, image); } ////// 删除一个或所有全局动画 ////// core.prototype.removeGlobalAnimate = function (x, y, all) { - if (all == true) { - core.status.twoAnimateObjs = []; - core.status.fourAnimateObjs = []; - } - - if (main.mode=='editor' && main.editor.disableGlobalAnimate) return; - - for (var t = 0; t < core.status.twoAnimateObjs.length; t++) { - if (core.status.twoAnimateObjs[t].x == x * 32 && core.status.twoAnimateObjs[t].y == y * 32) { - core.status.twoAnimateObjs.splice(t, 1); - return; - } - } - for (var f = 0; f < core.status.fourAnimateObjs.length; f++) { - if (core.status.fourAnimateObjs[f].x == x * 32 && core.status.fourAnimateObjs[f].y == y * 32) { - core.status.fourAnimateObjs.splice(f, 1); - return; - } - } + core.maps.removeGlobalAnimate(x, y, all); } ////// 设置全局动画的显示效果 ////// core.prototype.setGlobalAnimate = function (speed) { - if (main.mode=='editor' && main.editor.disableGlobalAnimate) return; - /* - clearInterval(core.interval.twoAnimate); - clearInterval(core.interval.fourAnimate); - var animateClose = false; - core.interval.twoAnimate = window.setInterval(function () { - for (var a = 0; a < core.status.twoAnimateObjs.length; a++) { - var obj = core.status.twoAnimateObjs[a]; - obj.status = (obj.status+1)%2; - core.canvas.event.clearRect(obj.x, obj.y, 32, 32); - if (!animateClose) { - core.canvas.event.drawImage(obj.image, obj.status * 32, obj.loc * 32, 32, 32, obj.x, obj.y, 32, 32); - } - animateClose = false; - } - }, speed); - core.interval.fourAnimate = window.setInterval(function () { - for (var a = 0; a < core.status.fourAnimateObjs.length; a++) { - var obj=core.status.fourAnimateObjs[a]; - obj.status = (obj.status+1)%4; - core.canvas.event.clearRect(obj.x, obj.y, 32, 32); - if (!animateClose) { - core.canvas.event.drawImage(obj.image, obj.status * 32, obj.loc * 32, 32, 32, obj.x, obj.y, 32, 32); - } - animateClose = false; - } - }, speed / 2); - */ - core.syncGlobalAnimate(); - core.animateFrame.speed = speed; - core.animateFrame.globalAnimate = true; + core.maps.setGlobalAnimate(speed); } ////// 同步所有的全局动画效果 ////// core.prototype.syncGlobalAnimate = function () { - core.status.twoAnimateObjs.forEach(function (t) { - t.status=0; - }) - core.status.fourAnimateObjs.forEach(function (t) { - t.status=0; - }) + core.maps.syncGlobalAnimate(); } ////// 绘制UI层的box动画 ////// core.prototype.drawBoxAnimate = function () { - for (var a = 0; a < core.status.boxAnimateObjs.length; a++) { - var obj = core.status.boxAnimateObjs[a]; - obj.status = ((obj.status||0)+1)%2; - core.clearMap('ui', obj.bgx, obj.bgy, obj.bgsize, obj.bgsize); - core.fillRect('ui', obj.bgx, obj.bgy, obj.bgsize, obj.bgsize, core.animateFrame.background); - core.canvas.ui.drawImage(obj.image, obj.status * 32, obj.icon * 32, - 32, 32, obj.x, obj.y, 32, 32); - } + core.maps.drawBoxAnimate(); } ////// 绘制动画 ////// core.prototype.drawAnimate = function (name, x, y, callback) { - - // 正在播放录像:不显示动画 - if (core.isset(core.status.replay) && core.status.replay.replaying) { - if (core.isset(callback)) callback(); - return; - } - - // 检测动画是否存在 - if (!core.isset(core.material.animates[name]) || !core.isset(x) || !core.isset(y)) { - if (core.isset(callback)) callback(); - return; - } - - // 清空animate层 - clearInterval(core.interval.animateInterval); - core.clearMap('animate', 0, 0, 416, 416); - - // 开始绘制 - var animate = core.material.animates[name]; - var ratio = animate.ratio; - var centerX = 32*x+16, centerY = 32*y+16; - var index=0; - - var draw = function (index) { - core.clearMap('animate', 0, 0, 416, 416); - - var frame = animate.frames[index]; - frame.forEach(function (t) { - var image = animate.images[t.index]; - if (!core.isset(image)) return; - var realWidth = image.width * ratio * t.zoom / 100; - var realHeight = image.height * ratio * t.zoom / 100; - core.setAlpha('animate', t.opacity / 255); - - var cx = centerX+t.x, cy=centerY+t.y; - - if (!t.mirror && !t.angle) { - core.canvas.animate.drawImage(image, cx-realWidth/2, cy-realHeight/2, realWidth, realHeight); - } - else { - core.saveCanvas('animate'); - core.canvas.animate.translate(cx,cy); - if (t.angle) - core.canvas.animate.rotate(-t.angle*Math.PI/180); - if (t.mirror) - core.canvas.animate.scale(-1,1); - core.canvas.animate.drawImage(image, -realWidth/2, -realHeight/2, realWidth, realHeight); - core.loadCanvas('animate'); - } - }) - } - - draw(index++); - - core.interval.animateInterval = setInterval(function (t) { - if (index == animate.frames.length) { - clearInterval(core.interval.animateInterval); - core.clearMap('animate', 0, 0, 416, 416); - core.setAlpha('animate', 1); - if (core.isset(callback)) callback(); - return; - } - draw(index++); - }, 50); + core.maps.drawAnimate(name, x, y, callback); } ////// 更新领域、夹击、阻击的伤害地图 ////// core.prototype.updateCheckBlock = function() { - core.status.checkBlock = {}; - if (!core.isset(core.status.thisMap)) return; - var blocks = core.status.thisMap.blocks; - - // Step1: 更新怪物地图 - core.status.checkBlock.map = []; // 记录怪物地图 - for (var n=0;n12 || ny<0 || ny>12) continue; - if (!zoneSquare && Math.abs(dx)+Math.abs(dy)>range) continue; - core.status.checkBlock.damage[13*nx+ny]+=enemy.value; - } - } - } - // 存在阻击 - if (core.enemys.hasSpecial(enemy.special, 18)) { - for (var dx=-1;dx<=1;dx++) { - for (var dy=-1;dy<=1;dy++) { - if (dx==0 && dy==0) continue; - var nx=x+dx, ny=y+dy; - if (nx<0 || nx>12 || ny<0 || ny>12 || Math.abs(dx)+Math.abs(dy)>1) continue; - core.status.checkBlock.damage[13*nx+ny]+=enemy.value; - } - } - } - } - } - } - - - // Step3: 更新夹击点坐标,并将夹击伤害加入到damage中 - core.status.checkBlock.betweenAttack = []; // 记录(x,y)点是否有夹击 - for (var x=0;x<13;x++) { - for (var y=0;y<13;y++) { - var has=false; - if (x>0 && x<12) { - var id1=core.status.checkBlock.map[13*(x-1)+y], - id2=core.status.checkBlock.map[13*(x+1)+y]; - if (core.isset(id1) && core.isset(id2) && id1==id2) { - var enemy = core.enemys.getEnemys(id1); - if (core.enemys.hasSpecial(enemy.special, 16)) { - has = true; - } - } - } - if (y>0 && y<12) { - var id1=core.status.checkBlock.map[13*x+y-1], - id2=core.status.checkBlock.map[13*x+y+1]; - if (core.isset(id1) && core.isset(id2) && id1==id2) { - var enemy = core.enemys.getEnemys(id1); - if (core.enemys.hasSpecial(enemy.special, 16)) { - has = true; - } - } - } - // 存在夹击 - if (has) { - core.status.checkBlock.betweenAttack[13*x+y]=true; - var leftHp = core.status.hero.hp - core.status.checkBlock.damage[13*x+y]; - if (leftHp>1) - core.status.checkBlock.damage[13*x+y] += parseInt((leftHp+(core.flags.betweenAttackCeil?0:1))/2); - } - } - } + core.control.updateCheckBlock(); } ////// 检查并执行领域、夹击、阻击事件 ////// core.prototype.checkBlock = function () { - var x=core.getHeroLoc('x'), y=core.getHeroLoc('y'); - var damage = core.status.checkBlock.damage[13*x+y]; - if (damage>0) { - core.status.hero.hp -= damage; - - // 检查阻击事件 - var snipe = []; - var scan = { - 'up': {'x': 0, 'y': -1}, - 'left': {'x': -1, 'y': 0}, - 'down': {'x': 0, 'y': 1}, - 'right': {'x': 1, 'y': 0} - } - for (var direction in scan) { - var nx = x+scan[direction].x, ny=y+scan[direction].y; - if (nx<0 || nx>12 || ny<0 || ny>12) continue; - var id=core.status.checkBlock.map[13*nx+ny]; - if (core.isset(id)) { - var enemy = core.enemys.getEnemys(id); - if (core.isset(enemy) && core.enemys.hasSpecial(enemy.special, 18)) { - snipe.push({'direction': direction, 'x': nx, 'y': ny}); - } - } - } - - if (core.status.checkBlock.betweenAttack[13*x+y] && damage>0) { - core.drawTip('受到夹击,生命变成一半'); - } - // 阻击 - else if (snipe.length>0 && damage>0) { - core.drawTip('受到阻击伤害'+damage+'点'); - } - else if (damage>0) { - core.drawTip('受到领域伤害'+damage+'点'); - } - - core.playSound('zone.ogg'); - core.drawAnimate("zone", x, y); - - if (core.status.hero.hp<=0) { - core.status.hero.hp=0; - core.updateStatusBar(); - core.events.lose('zone'); - return; - } - snipe = snipe.filter(function (t) { - var x=t.x, y=t.y, direction = t.direction; - var nx = x+scan[direction].x, ny=y+scan[direction].y; - - return nx>=0 && nx<=12 && ny>=0 && ny<=12 && core.getBlock(nx, ny, core.status.floorId, false)==null; - }); - core.updateStatusBar(); - if (snipe.length>0) - core.snipe(snipe); - } + core.control.checkBlock(); } ////// 阻击事件(动画效果) ////// core.prototype.snipe = function (snipes) { - - var scan = { - 'up': {'x': 0, 'y': -1}, - 'left': {'x': -1, 'y': 0}, - 'down': {'x': 0, 'y': 1}, - 'right': {'x': 1, 'y': 0} - }; - - snipes.forEach(function (snipe) { - var x=snipe.x, y=snipe.y, direction = snipe.direction; - snipe.nx = x+scan[snipe.direction].x; - snipe.ny = y+scan[snipe.direction].y; - - core.removeGlobalAnimate(x, y); - - var block = core.getBlock(x,y).block; - - snipe.blockIcon = core.material.icons[block.event.cls][block.event.id]; - snipe.blockImage = core.material.images[block.event.cls]; - var damage = core.enemys.getDamage(block.event.id); - - var color = "#000000"; - if (damage <= 0) color = '#00FF00'; - else if (damage < core.status.hero.hp / 3) color = '#FFFFFF'; - else if (damage < core.status.hero.hp * 2 / 3) color = '#FFFF00'; - else if (damage < core.status.hero.hp) color = '#FF7F00'; - else color = '#FF0000'; - - if (damage >= 999999999) damage = "???"; - else if (damage > 100000) damage = (damage / 10000).toFixed(1) + "w"; - - snipe.damage = damage; - snipe.color = color; - snipe.block = core.clone(block); - }) - - var finishSnipe = function () { - snipes.forEach(function (t) { - core.removeBlock(t.x, t.y); - var nBlock = core.clone(t.block); - nBlock.x = t.nx; nBlock.y = t.ny; - core.status.thisMap.blocks.push(nBlock); - core.addGlobalAnimate(2, 32*t.nx, 32*t.ny, t.blockIcon, t.blockImage); - core.canvas.event.drawImage(t.blockImage, 0, t.blockIcon*32, 32, 32, 32*t.nx, 32*t.ny, 32, 32); - }); - core.syncGlobalAnimate(); - core.updateStatusBar(); - return; - } - - if (core.status.replay.replaying) { - finishSnipe(); - } - else { - core.waitHeroToStop(function() { - - core.lockControl(); - - var time = 500, step = 0; - - var animateValue = 2; - var animateCurrent = 0; - var animateTime = 0; - - core.canvas.fg.textAlign = 'left'; - - var animate=window.setInterval(function() { - - step++; - animateTime += time / 16; - if (animateTime >= core.values.animateSpeed * 2 / animateValue) { - animateCurrent++; - animateTime = 0; - if (animateCurrent>=animateValue) animateCurrent=0; - } - - snipes.forEach(function (snipe) { - var x=snipe.x, y=snipe.y, direction = snipe.direction; - - var nowX=32*x+scan[direction].x*2*step, nowY=32*y+scan[direction].y*2*step; - - // 清空上一次 - core.clearMap('event', nowX-2*scan[direction].x, nowY-2*scan[direction].y, 32, 32); - core.clearMap('fg', nowX-2*scan[direction].x, nowY-2*scan[direction].y, 32, 32); - - core.canvas.event.drawImage(snipe.blockImage, animateCurrent*32, snipe.blockIcon*32, 32, 32, nowX, nowY, 32, 32); - - if (core.hasItem('book')) { - // drawFG - core.setFillStyle('fg', '#000000'); - core.canvas.fg.fillText(snipe.damage, nowX + 2, nowY + 30); - core.canvas.fg.fillText(snipe.damage, nowX, nowY + 30); - core.canvas.fg.fillText(snipe.damage, nowX + 2, nowY + 32); - core.canvas.fg.fillText(snipe.damage, nowX, nowY + 32); - - core.setFillStyle('fg', snipe.color); - core.canvas.fg.fillText(snipe.damage, nowX + 1, nowY + 31); - } - - }) - - if (step==16) { // 移动完毕 - clearInterval(animate); - finishSnipe(); - // 不存在自定义事件 - if (core.status.event.id==null) - core.unLockControl(); - } - }, time/16); - }); - } - - + core.control.snipe(snipes); } ////// 更改天气效果 ////// core.prototype.setWeather = function (type, level) { - - // 非雨雪 - if (type!='rain' && type!='snow') { - core.clearMap('weather', 0, 0, 416, 416) - core.animateFrame.weather.type = null; - core.animateFrame.weather.level = 0; - core.animateFrame.weather.nodes = []; - return; - } - - level = parseInt(level); - - // 当前天气:则忽略 - if (type==core.animateFrame.weather.type && - (!core.isset(level) || 20*level==core.animateFrame.weather.level)) { - return; - } - - if (!core.isset(level)) level=5; - if (level<1) level=1; if (level>10) level=10; - level *= 20; - - core.clearMap('weather', 0, 0, 416, 416) - core.animateFrame.weather.type = type; - core.animateFrame.weather.level = level; - - core.animateFrame.weather.nodes = []; - - if (type == 'rain') { - for (var a=0;a1) color[3]=1; - - if (time==0) { - // 直接变色 - core.dom.curtain.style.background = core.arrayToRGB(color); - core.dom.curtain.style.opacity = color[3]; - core.status.curtainColor = color; - if (core.isset(callback)) callback(); - return; - } - - var step=0; - core.status.replay.animate=true; - var changeAnimate = setInterval(function() { - step++; - - var nowAlpha = fromColor[3]+(color[3]-fromColor[3])*step/25; - var nowR = parseInt(fromColor[0]+(color[0]-fromColor[0])*step/25); - var nowG = parseInt(fromColor[1]+(color[1]-fromColor[1])*step/25); - var nowB = parseInt(fromColor[2]+(color[2]-fromColor[2])*step/25); - core.dom.curtain.style.background = core.arrayToRGB([nowR,nowG,nowB]); - core.dom.curtain.style.opacity = nowAlpha; - - if (step>=25) { - clearInterval(changeAnimate); - core.status.curtainColor = color; - core.status.replay.animate=false; - if (core.isset(callback)) callback(); - } - }, time/25); - + core.control.setFg(color, time, callback); } ////// 更新全地图显伤 ////// core.prototype.updateFg = function () { - - if (!core.isset(core.status.thisMap) || !core.isset(core.status.thisMap.blocks)) return; - // 更新显伤 - var mapBlocks = core.status.thisMap.blocks; - core.clearMap('fg', 0, 0, 416, 416); - // 没有怪物手册 - if (!core.hasItem('book')) return; - core.setFont('fg', "bold 11px Arial"); - var hero_hp = core.status.hero.hp; - if (core.flags.displayEnemyDamage) { - core.canvas.fg.textAlign = 'left'; - for (var b = 0; b < mapBlocks.length; b++) { - var x = mapBlocks[b].x, y = mapBlocks[b].y; - if (core.isset(mapBlocks[b].event) && mapBlocks[b].event.cls == 'enemys' - && !(core.isset(mapBlocks[b].enable) && !mapBlocks[b].enable)) { - - // 非系统默认的战斗事件(被覆盖) - if (mapBlocks[b].event.trigger != 'battle') { - // 判断显伤 - var event = core.floors[core.status.floorId].events[x+","+y]; - if (core.isset(event) && !(event instanceof Array)) { - if (core.isset(event.displayDamage) && !event.displayDamage) - continue; - } - } - - var id = mapBlocks[b].event.id; - - var damage = core.enemys.getDamage(id); - var color = "#000000"; - if (damage <= 0) color = '#00FF00'; - else if (damage < hero_hp / 3) color = '#FFFFFF'; - else if (damage < hero_hp * 2 / 3) color = '#FFFF00'; - else if (damage < hero_hp) color = '#FF7F00'; - else color = '#FF0000'; - - if (damage >= 999999999) damage = "???"; - else if (damage > 100000) damage = (damage / 10000).toFixed(1) + "w"; - - core.setFillStyle('fg', '#000000'); - core.canvas.fg.fillText(damage, 32 * x + 2, 32 * (y + 1) - 2); - core.canvas.fg.fillText(damage, 32 * x, 32 * (y + 1) - 2); - core.canvas.fg.fillText(damage, 32 * x + 2, 32 * (y + 1)); - core.canvas.fg.fillText(damage, 32 * x, 32 * (y + 1)); - - core.setFillStyle('fg', color); - core.canvas.fg.fillText(damage, 32 * x + 1, 32 * (y + 1) - 1); - - } - } - } - // 如果是领域&夹击 - if (core.flags.displayExtraDamage) { - core.canvas.fg.textAlign = 'center'; - for (var x=0;x<13;x++) { - for (var y=0;y<13;y++) { - var damage = core.status.checkBlock.damage[13*x+y]; - if (damage>0) { - core.setFillStyle('fg', '#000000'); - core.canvas.fg.fillText(damage, 32 * x + 17, 32 * (y + 1) - 13); - core.canvas.fg.fillText(damage, 32 * x + 15, 32 * (y + 1) - 15); - core.canvas.fg.fillText(damage, 32 * x + 17, 32 * (y + 1) - 15); - core.canvas.fg.fillText(damage, 32 * x + 15, 32 * (y + 1) - 13); - - core.setFillStyle('fg', '#FF7F00'); - core.canvas.fg.fillText(damage, 32 * x + 16, 32 * (y + 1) - 14); - } - } - } - } + core.control.updateFg(); } ////// 获得某个物品的个数 ////// core.prototype.itemCount = function (itemId) { - if (!core.isset(itemId) || !core.isset(core.material.items[itemId])) return 0; - var itemCls = core.material.items[itemId].cls; - if (itemCls=="items") return 0; - return core.isset(core.status.hero.items[itemCls][itemId]) ? core.status.hero.items[itemCls][itemId] : 0; + return core.items.itemCount(itemId); } ////// 是否存在某个物品 ////// core.prototype.hasItem = function (itemId) { - return core.itemCount(itemId) > 0; + return core.items.hasItem(itemId); } ////// 设置某个物品的个数 ////// core.prototype.setItem = function (itemId, itemNum) { - var itemCls = core.material.items[itemId].cls; - if (itemCls == 'items') return; - if (!core.isset(core.status.hero.items[itemCls])) { - core.status.hero.items[itemCls] = {}; - } - core.status.hero.items[itemCls][itemId] = itemNum; - if (itemCls!='keys' && itemNum==0) { - delete core.status.hero.items[itemCls][itemId]; - } + core.items.setItem(itemId, itemNum); } ////// 删除某个物品 ////// core.prototype.removeItem = function (itemId) { - if (!core.hasItem(itemId)) return false; - var itemCls = core.material.items[itemId].cls; - core.status.hero.items[itemCls][itemId]--; - if (itemCls!='keys' && core.status.hero.items[itemCls][itemId]==0) { - delete core.status.hero.items[itemCls][itemId]; - } - core.updateStatusBar(); - return true; + return core.items.removeItem(itemId); } ////// 使用某个物品 ////// core.prototype.useItem = function (itemId, callback) { core.items.useItem(itemId, callback); - return; } ////// 能否使用某个物品 ////// @@ -3817,155 +777,27 @@ core.prototype.canUseItem = function (itemId) { ////// 增加某个物品的个数 ////// core.prototype.addItem = function (itemId, itemNum) { - var itemData = core.material.items[itemId]; - var itemCls = itemData.cls; - if (itemCls == 'items') return; - if (!core.isset(core.status.hero.items[itemCls])) { - core.status.hero.items[itemCls] = {}; - core.status.hero.items[itemCls][itemId] = 0; - } - else if (!core.isset(core.status.hero.items[itemCls][itemId])) { - core.status.hero.items[itemCls][itemId] = 0; - } - core.status.hero.items[itemCls][itemId] += itemNum; + core.items.addItem(itemId, itemNum); } ////// 获得面前的物品(轻按) ////// core.prototype.getNextItem = function() { - if (!core.status.heroStop || !core.flags.enableGentleClick) return; - var nextX = core.nextX(), nextY = core.nextY(); - var block = core.getBlock(nextX, nextY); - if (block==null) return; - if (block.block.event.trigger=='getItem') { - core.getItem(block.block.event.id, 1, nextX, nextY); - core.status.route.push("getNext"); - } + core.events.getNextItem(); } ////// 获得某个物品 ////// core.prototype.getItem = function (itemId, itemNum, itemX, itemY, callback) { - // core.getItemAnimate(itemId, itemNum, itemX, itemY); - core.playSound('item.ogg'); - var itemCls = core.material.items[itemId].cls; - core.items.getItemEffect(itemId, itemNum); - core.removeBlock(itemX, itemY); - var text = '获得 ' + core.material.items[itemId].name; - if (itemNum > 1) text += "x" + itemNum; - if (itemCls === 'items') text += core.items.getItemEffectTip(itemId); - core.drawTip(text, core.material.icons.items[itemId]); - core.canvas.event.clearRect(itemX * 32, itemY * 32, 32, 32); - core.updateStatusBar(); - - // 检查处理后的事件。 - var event = core.floors[core.status.floorId].afterGetItem[itemX+","+itemY]; - if (core.isset(event)) { - core.events.doEvents(event, itemX, itemY, callback); - } - else if (core.isset(callback)) callback(); + core.events.getItem(itemId, itemNum, itemX, itemY, callback); } ////// 左上角绘制一段提示 ////// core.prototype.drawTip = function (text, itemIcon) { - var textX, textY, width, height, hide = false, opacityVal = 0; - clearInterval(core.interval.tipAnimate); - core.setFont('data', "16px Arial"); - core.saveCanvas('data'); - core.setOpacity('data', 0); - core.canvas.data.textAlign = 'left'; - if (!core.isset(itemIcon)) { - textX = 16; - textY = 18; - width = textX + core.canvas.data.measureText(text).width + 16; - height = 42; - } - else { - textX = 44; - textY = 18; - width = textX + core.canvas.data.measureText(text).width + 8; - height = 42; - } - core.interval.tipAnimate = window.setInterval(function () { - if (hide) { - opacityVal -= 0.1; - } - else { - opacityVal += 0.1; - } - core.setOpacity('data', opacityVal); - core.clearMap('data', 5, 5, 400, height); - core.fillRect('data', 5, 5, width, height, '#000'); - if (core.isset(itemIcon)) { - core.canvas.data.drawImage(core.material.images.items, 0, itemIcon * 32, 32, 32, 10, 8, 32, 32); - } - core.fillText('data', text, textX + 5, textY + 15, '#fff'); - if (opacityVal > 0.6 || opacityVal < 0) { - if (hide) { - core.loadCanvas('data'); - core.clearMap('data', 5, 5, 400, height); - core.setOpacity('data', 1); - clearInterval(core.interval.tipAnimate); - return; - } - else { - if (!core.isset(core.timeout.getItemTipTimeout)) { - core.timeout.getItemTipTimeout = window.setTimeout(function () { - hide = true; - core.timeout.getItemTipTimeout = null; - }, 750); - } - opacityVal = 0.6; - core.setOpacity('data', opacityVal); - } - } - }, 30); + core.ui.drawTip(text, itemIcon); } ////// 地图中间绘制一段文字 ////// core.prototype.drawText = function (contents, callback) { - if (core.isset(contents)) { - - // 合并 - if (core.isset(core.status.event)&&core.status.event.id=='action') { - core.insertAction(contents,null,null,callback); - return; - } - - if (typeof contents == 'string') { - contents = [{'content': contents}]; - } - else if (contents instanceof Object && core.isset(contents.content)) { - contents = [contents]; - } - else if (!(contents instanceof Array)) { - core.drawTip("出错了"); - console.log(contents); - return; - } - - core.status.event = {'id': 'text', 'data': {'list': contents, 'callback': callback}}; - core.lockControl(); - - // wait the hero to stop - core.stopAutomaticRoute(); - setTimeout(function() { - core.drawText(); - }, 30); - return; - } - - if (core.status.event.data.list.length==0) { - var callback = core.status.event.data.callback; - core.ui.closePanel(false); - if (core.isset(callback)) callback(); - return; - } - - var data=core.status.event.data.list.shift(); - if (typeof data == 'string') - core.ui.drawTextBox(data); - else - core.ui.drawTextBox(data.content, data.id); - // core.drawTextBox(content); + core.ui.drawText(contents, callback); } /////////// 地图相关 END /////////// @@ -3977,996 +809,231 @@ core.prototype.drawText = function (contents, callback) { ////// 将文字中的${和}(表达式)进行替换 ////// core.prototype.replaceText = function (text) { - return text.replace(/\${([^}]+)}/g, function (word, value) { - return core.calValue(value); - }); + return core.utils.replaceText(text); } ////// 计算表达式的值 ////// core.prototype.calValue = function (value) { - value=value.replace(/status:([\w\d_]+)/g, "core.getStatus('$1')"); - value=value.replace(/item:([\w\d_]+)/g, "core.itemCount('$1')"); - value=value.replace(/flag:([\w\d_]+)/g, "core.getFlag('$1', false)"); - return eval(value); + return core.utils.calValue(value); } ////// 执行一个表达式的effect操作 ////// core.prototype.doEffect = function (expression) { - // 必须使用"+=" - var arr = expression.split("+="); - if (arr.length!=2) return; - var name=arr[0], value=core.calValue(arr[1]); - if (name.indexOf("status:")==0) { - var status=name.substring(7); - core.setStatus(status, core.getStatus(status)+value); - } - else if (name.indexOf("item:")==0) { - var itemId=name.substring(5); - core.setItem(itemId, core.itemCount(itemId)+value); - } + core.control.doEffect(expression); } ////// 字符串自动换行的分割 ////// core.prototype.splitLines = function(canvas, text, maxLength, font) { - if (core.isset(font)) core.setFont(canvas, font); - - var contents = []; - var last = 0; - for (var i=0;imaxLength) { - contents.push(text.substring(last, i)); - last=i; - } - } - } - contents.push(text.substring(last)); - return contents; + return core.utils.splitLines(canvas, text, maxLength, font); } ////// 向某个数组前插入另一个数组或元素 ////// core.prototype.unshift = function (a,b) { - if (!(a instanceof Array) || !core.isset(b)) return; - if (b instanceof Array) { - core.clone(b).reverse().forEach(function (e) { - a.unshift(e); - }); - } - else a.unshift(b); - return a; + return core.utils.unshift(a,b); } ////// 设置本地存储 ////// core.prototype.setLocalStorage = function(key, value) { - try { - localStorage.setItem(core.firstData.name + "_" + key, JSON.stringify(value)); - return true; - } - catch (e) { - console.log(e); - return false; - } + return core.utils.setLocalStorage(key, value); } ////// 获得本地存储 ////// core.prototype.getLocalStorage = function(key, defaultValue) { - var value = localStorage.getItem(core.firstData.name+"_"+key); - if (core.isset(value)) return JSON.parse(value); - return defaultValue; + return core.utils.getLocalStorage(key, defaultValue); } ////// 移除本地存储 ////// core.prototype.removeLocalStorage = function (key) { - localStorage.removeItem(core.firstData.name+"_"+key); + core.utils.removeLocalStorage(key); } ////// 深拷贝一个对象 ////// core.prototype.clone = function (data) { - if (!core.isset(data)) return data; - // date - if (data instanceof Date) { - var copy=new Date(); - copy.setTime(data.getTime()); - return copy; - } - // array - if (data instanceof Array) { - var copy=[]; - // for (var i=0;i255) nowR=255; if (nowB>255) nowB=255; if (nowG>255) nowG=255; - return "#"+((1<<24)+(nowR<<16)+(nowG<<8)+nowB).toString(16).slice(1); + return core.utils.arrayToRGB(color); } ////// 作弊 ////// core.prototype.debug = function() { - core.setStatus('hp', 999999); - core.setStatus('atk', 10000); - core.setStatus('def', 10000); - core.setStatus('mdef', 10000); - core.setStatus('money', 10000); - core.setStatus('experience', 10000); - core.setItem('yellowKey', 50); - core.setItem('blueKey', 50); - core.setItem('redKey', 50); - core.setItem('book', 1); - core.setItem('fly', 1); - for (var i in core.status.maps) - if (core.status.maps[i].canFlyTo && core.status.hero.flyRange.indexOf(i)<0) - core.status.hero.flyRange.push(i); - core.updateStatusBar(); - core.drawTip("作弊成功"); + core.control.debug(); } ////// 开始播放 ////// core.prototype.startReplay = function (list) { - core.status.replay.replaying=true; - core.status.replay.pausing=false; - core.status.replay.speed=1.0; - core.status.replay.toReplay = core.clone(list); - core.status.replay.totalList = core.clone(list); - core.updateStatusBar(); - core.drawTip("开始播放"); - this.replay(); - return; + core.control.startReplay(list); } ////// 更改播放状态 ////// core.prototype.triggerReplay = function () { - if (core.status.replay.pausing) this.resumeReplay(); - else this.pauseReplay(); + core.control.triggerReplay(); } ////// 暂停播放 ////// core.prototype.pauseReplay = function () { - if (!core.status.replay.replaying) return; - core.status.replay.pausing = true; - core.updateStatusBar(); - core.drawTip("暂停播放"); + core.control.pauseReplay(); } ////// 恢复播放 ////// core.prototype.resumeReplay = function () { - if (!core.status.replay.replaying) return; - core.status.replay.pausing = false; - core.updateStatusBar(); - core.drawTip("恢复播放"); - core.replay(); + core.control.resumeReplay(); } ////// 加速播放 ////// core.prototype.forwardReplay = function () { - if (!core.status.replay.replaying) return; - core.status.replay.speed = parseInt(10*core.status.replay.speed + 1)/10; - if (core.status.replay.speed>2.5) core.status.replay.speed=2.5; - core.drawTip("x"+core.status.replay.speed+"倍"); + core.control.forwardReplay(); } ////// 减速播放 ////// core.prototype.rewindReplay = function () { - 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; - core.drawTip("x"+core.status.replay.speed+"倍"); + core.control.rewindReplay(); } ////// 停止播放 ////// core.prototype.stopReplay = function () { - if (!core.status.replay.replaying) return; - core.status.replay.toReplay = []; - core.status.replay.totalList = []; - core.status.replay.replaying=false; - core.status.replay.pausing=false; - core.status.replay.speed=1.0; - core.updateStatusBar(); - core.drawTip("停止播放并恢复游戏"); + core.control.stopReplay(); } ////// 回放 ////// core.prototype.replay = function () { - - if (!core.status.replay.replaying) return; // 没有回放 - if (core.status.replay.pausing) return; // 暂停状态 - if (core.status.replay.animate) return; // 正在某段动画中 - - if (core.status.replay.toReplay.length==0) { // 回放完毕 - core.stopReplay(); - core.insertAction("录像回放完毕!"); - return; - } - - var action=core.status.replay.toReplay.shift(); - - if (action=='up' || action=='down' || action=='left' || action=='right') { - core.moveHero(action, function () { - core.replay(); - }); - return; - } - else if (action.indexOf("item:")==0) { - var itemId = action.substring(5); - if (core.canUseItem(itemId)) { - var tools = Object.keys(core.status.hero.items.tools).sort(); - var constants = Object.keys(core.status.hero.items.constants).sort(); - var index; - if ((index=tools.indexOf(itemId))>=0 || (index=constants.indexOf(itemId)+100)>=100) { - core.ui.drawToolbox(index); - setTimeout(function () { - core.ui.closePanel(); - core.useItem(itemId, function () { - core.replay(); - }); - }, 750); - } - return; - } - } - else if (action.indexOf("fly:")==0) { - var floorId=action.substring(4); - var toIndex=core.status.hero.flyRange.indexOf(floorId); - var nowIndex=core.status.hero.flyRange.indexOf(core.status.floorId); - if (core.hasItem('fly') && toIndex>=0 && nowIndex>=0) { - core.ui.drawFly(toIndex); - setTimeout(function () { - core.ui.closePanel(); - var stair=toIndex0) { - var shop=core.status.shops[shopId]; - if (core.isset(shop) && shop.visited) { // 商店可用 - var choices = shop.choices; - var topIndex = 6 - parseInt(choices.length / 2); - - core.status.event.selection = parseInt(selections.shift()); - - core.events.openShop(shopId, false); - var shopInterval = setInterval(function () { - if (!core.events.clickShop(6, topIndex+core.status.event.selection)) { - clearInterval(shopInterval); - core.stopReplay(); - core.drawTip("录像文件出错"); - return; - } - if (selections.length==0) { - clearInterval(shopInterval); - core.events.clickShop(6, topIndex+choices.length); - core.replay(); - return; - } - core.status.event.selection = parseInt(selections.shift()); - core.events.openShop(shopId, false); - - }, 750); - return; - } - } - } - else if (action=='turn') { - core.turnHero(); - core.replay(); - return; - } - else if (action=='getNext') { - if (core.flags.enableGentleClick && core.getBlock(core.nextX(), core.nextY())!=null) { - var nextX = core.nextX(), nextY = core.nextY(); - var block = core.getBlock(nextX, nextY); - if (block!=null && block.block.event.trigger=='getItem') { - core.getItem(block.block.event.id, 1, nextX, nextY); - core.status.route.push("getNext"); - core.replay(); - return; - } - } - } - else if (action.indexOf('move:')==0) { - var pos=action.substring(5).split(":"); - var x=parseInt(pos[0]), y=parseInt(pos[1]); - if (core.canMoveDirectly(x,y)) { - 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.status.route.push("move:"+x+":"+y); - core.replay(); - return; - } - } - - core.stopReplay(); - core.insertAction("录像文件出错"); - + core.control.replay(); } ////// 判断当前能否进入某个事件 ////// core.prototype.checkStatus = function (name, need, item) { - if (need && core.status.event.id == name) { - core.ui.closePanel(); - return false; - } - - if (need && core.status.lockControl) return false; - if (core.isset(item) && item && !core.hasItem(name)) { - core.drawTip("你没有" + core.material.items[name].name); - return false; - } - if (!core.status.heroStop) { - core.drawTip("请先停止勇士行动"); - return false; - } - - core.lockControl(); - core.status.event.id = name; - return true; + return core.control.checkStatus(name, need, item); } ////// 点击怪物手册时的打开操作 ////// core.prototype.openBook = function (need) { - if (core.isset(core.status.replay)&&core.status.replay.replaying) return; - - // 当前是book,且从“浏览地图”打开 - if (core.status.event.id == 'book' && core.isset(core.status.event.selection)) { - core.status.boxAnimateObjs = []; - core.ui.drawMaps(core.status.event.selection); - return; - } - - // 从“浏览地图”页面打开 - if (core.status.event.id=='viewMaps') { - need=false; - core.status.event.selection = core.status.event.data; - } - - if (!core.checkStatus('book', need, true)) - return; - core.useItem('book'); + core.control.openBook(need); } ////// 点击楼层传送器时的打开操作 ////// core.prototype.useFly = function (need) { - if (core.isset(core.status.replay)&&core.status.replay.replaying) return; - if (!core.checkStatus('fly', need, true)) - return; - if (core.flags.flyNearStair && !core.nearStair()) { - core.drawTip("只有在楼梯边才能使用传送器"); - core.unLockControl(); - core.status.event.data = null; - core.status.event.id = null; - return; - } - if (!core.canUseItem('fly')) { - core.drawTip("楼层传送器好像失效了"); - core.unLockControl(); - core.status.event.data = null; - core.status.event.id = null; - return; - } - core.useItem('fly'); - return; + core.control.useFly(need); } ////// 点击工具栏时的打开操作 ////// core.prototype.openToolbox = function (need) { - if (core.isset(core.status.replay)&&core.status.replay.replaying) return; - if (!core.checkStatus('toolbox', need)) - return; - core.ui.drawToolbox(); + core.control.openToolbox(need); } ////// 点击快捷商店按钮时的打开操作 ////// core.prototype.openQuickShop = function (need) { - if (core.isset(core.status.replay)&&core.status.replay.replaying) return; - if (!core.checkStatus('selectShop', need)) - return; - core.ui.drawQuickShop(); + core.control.openQuickShop(need); } ////// 点击保存按钮时的打开操作 ////// core.prototype.save = function(need) { - if (core.isset(core.status.replay)&&core.status.replay.replaying) return; - if (!core.checkStatus('save', need)) - return; - - var saveIndex = core.status.saveIndex; - var page=parseInt((saveIndex-1)/5), offset=saveIndex-5*page; - - core.ui.drawSLPanel(10*page+offset); + core.control.save(need); } ////// 点击读取按钮时的打开操作 ////// core.prototype.load = function (need) { - if (core.isset(core.status.replay)&&core.status.replay.replaying) return; - - var saveIndex = core.getLocalStorage('saveIndex2', 1); - var page=parseInt((saveIndex-1)/5), offset=saveIndex-5*page; - - // 游戏开始前读档 - if (!core.isPlaying()) { - core.status.event = {'id': 'load', 'data': null}; - core.status.lockControl = true; - core.dom.startPanel.style.display = 'none'; - core.ui.drawSLPanel(10*page+offset); - return; - } - - if (!core.checkStatus('load', need)) - return; - core.ui.drawSLPanel(10*page+offset); + core.control.load(need); } ////// 点击设置按钮时的操作 ////// core.prototype.openSettings = function (need) { - if (core.isset(core.status.replay)&&core.status.replay.replaying) return; - if (!core.checkStatus('settings', need)) - return; - core.ui.drawSettings(); + core.control.openSettings(need); } ////// 自动存档 ////// core.prototype.autosave = function (removeLast) { - var x=null; - if (removeLast) - x=core.status.route.pop(); - core.saveData("autoSave"); - if (removeLast && core.isset(x)) - core.status.route.push(x); + core.control.autosave(removeLast); } ////// 实际进行存读档事件 ////// core.prototype.doSL = function (id, type) { - if (type=='save') { - if (id=='autoSave') { - core.drawTip('不能覆盖自动存档!'); - return; - } - if (core.saveData("save"+id)) { - core.ui.closePanel(); - core.drawTip('存档成功!'); - if (id!="autoSave") { - core.status.saveIndex=id; - core.setLocalStorage('saveIndex2', core.status.saveIndex); - } - } - else { - core.drawTip('存储空间不足,请覆盖已有的存档或在菜单栏中进行清理'); - } - return; - } - else if (type=='load') { - 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("存档版本不匹配"); - if (confirm("存档版本不匹配!\n你想回放此存档的录像吗?")) { - core.dom.startPanel.style.display = 'none'; - core.resetStatus(core.firstData.hero, data.hard, core.firstData.floorId, null, core.initStatus.maps); - core.events.setInitData(data.hard); - core.changeFloor(core.status.floorId, null, core.firstData.hero.loc, null, function() { - core.startReplay(core.decodeRoute(data.route)); - }); - } - return; - } - core.ui.closePanel(); - core.loadData(data, function() { - core.drawTip("读档成功"); - if (id!="autoSave") { - core.status.saveIndex=id; - core.setLocalStorage('saveIndex2', core.status.saveIndex); - } - }); - return; - } + core.control.doSL(id, type); } ////// 同步存档到服务器 ////// core.prototype.syncSave = function (type) { - var saves=null; - // data - if (type=='all') { - saves=[]; - for (var i=1;i<=150;i++) { - var data = core.getLocalStorage("save"+i, null); - if (core.isset(data)) { - saves.push(data); - } - } - } - else { - for (var i=150;i>=1;i--) { - saves=core.getLocalStorage("save"+i, null); - if (core.isset(saves)) { - break; - } - } - } - if (!core.isset(saves)) { - core.drawText("没有要同步的存档"); - return; - } - core.ui.drawWaiting("正在同步,请稍后..."); - - var formData = new FormData(); - formData.append('type', 'save'); - formData.append('name', core.firstData.name); - var save_text = JSON.stringify(saves); - formData.append('data', save_text); - - // send - var xhr = new XMLHttpRequest(); - xhr.open("POST", "/games/sync.php"); - xhr.onload = function(e) { - if (xhr.status==200) { - // console.log("同步成功。"); - var response = JSON.parse(xhr.response); - if (response.code<0) { - core.drawText("出错啦!\n无法同步存档到服务器。\n错误原因:"+response.msg); - } - else { - core.drawText("同步成功!\n\n您的存档编号: "+response.code+"\n您的存档密码: "+response.msg+"\n\n请牢记以上两个信息(如截图等),在从服务器\n同步存档时使用。") - } - } - else { - core.drawText("出错啦!\n无法同步存档到服务器。\n错误原因:HTTP "+xhr.status); - } - }; - xhr.ontimeout = function() { - core.drawText("出错啦!\n无法同步存档到服务器。\n错误原因:Timeout"); - } - xhr.onerror = function() { - core.drawText("出错啦!\n无法同步存档到服务器。\n错误原因:XHR Error"); - } - xhr.send(formData); + core.control.syncSave(type); } ////// 从服务器加载存档 ////// core.prototype.syncLoad = function () { - var id = prompt("请输入存档编号:"); - if (id==null || id=="") { - core.ui.drawSyncSave(); return; - } - var password = prompt("请输入存档密码:"); - if (password==null || password=="") { - core.ui.drawSyncSave(); return; - } - core.ui.drawWaiting("正在同步,请稍后..."); - - var formData = new FormData(); - formData.append('type', 'load'); - formData.append('name', core.firstData.name); - formData.append('id', id); - formData.append('password', password); - - // send - var xhr = new XMLHttpRequest(); - xhr.open("POST", "/games/sync.php"); - xhr.onload = function(e) { - if (xhr.status==200) { - // console.log("同步成功。"); - var response = JSON.parse(xhr.response); - switch (response.code) { - case 0: - // 成功 - var data=JSON.parse(response.msg); - // console.log(data); - - if (data instanceof Array) { - core.status.event.selection=1; - core.ui.drawConfirmBox("所有本地存档都将被覆盖,确认?", function () { - for (var i=1;i<=150;i++) { - if (i<=data.length) { - core.setLocalStorage("save"+i, data[i-1]); - } - else { - core.removeLocalStorage("save"+i); - } - } - core.drawText("同步成功!\n你的本地所有存档均已被覆盖。"); - }, function () { - core.status.event.selection=0; - core.ui.drawSyncSave(); - }) - } - else { - // 只覆盖单存档 - var index=150; - for (var i=150;i>=1;i--) { - if (core.getLocalStorage("save"+i, null)==null) - index=i; - else break; - } - core.setLocalStorage("save"+index, data); - core.drawText("同步成功!\n单存档已覆盖至存档"+index); - } - break; - case -1: - core.drawText("出错啦!\n存档编号"+id+"不存在!"); - break; - case -2: - core.drawText("出错啦!\n存档密码错误!"); - break; - default: - core.drawText("出错啦!\n无法从服务器同步存档。\n错误原因:"+response.msg); - break; - } - } - else { - core.drawText("出错啦!\n无法从服务器同步存档。\n错误原因:HTTP "+xhr.status); - } - }; - xhr.ontimeout = function() { - core.drawText("出错啦!\n无法从服务器同步存档。\n错误原因:Timeout"); - } - xhr.onerror = function() { - core.drawText("出错啦!\n无法从服务器同步存档。\n错误原因:XHR Error"); - } - xhr.send(formData); + core.control.synvLoad(); } -/* - -////// 存档同步操作 ////// -core.prototype.syncSave = function(type) { - if (type=='save') { - core.status.event.selection=1; - core.ui.drawConfirmBox("你确定要将本地存档同步到服务器吗?", function(){ - // console.log("同步存档..."); - core.ui.drawWaiting("正在同步,请稍后..."); - - var formData = new FormData(); - formData.append('type', 'save'); - formData.append('name', core.firstData.name); - var saves = []; - for (var i=1;i<=150;i++) { - var data = core.getLocalStorage("save"+i, null); - if (core.isset(data)) { - saves.push(data); - } - } - var save_text = JSON.stringify(saves); - formData.append('data', save_text); - - // send - var xhr = new XMLHttpRequest(); - xhr.open("POST", "/games/sync.php"); - xhr.onload = function(e) { - if (xhr.status==200) { - // console.log("同步成功。"); - var response = JSON.parse(xhr.response); - if (response.code<0) { - core.drawText("出错啦!\n无法同步存档到服务器。\n错误原因:"+response.msg); - } - else { - core.drawText("同步成功!\n\n您的存档编号: "+response.code+"\n您的存档密码: "+response.msg+"\n\n请牢记以上两个信息(如截图等),在从服务器\n同步存档时使用。") - } - } - else { - core.drawText("出错啦!\n无法同步存档到服务器。\n错误原因:HTTP "+xhr.status); - } - }; - xhr.ontimeout = function() { - core.drawText("出错啦!\n无法同步存档到服务器。\n错误原因:Timeout"); - } - xhr.onerror = function() { - core.drawText("出错啦!\n无法同步存档到服务器。\n错误原因:XHR Error"); - } - xhr.send(formData); - }, function() { - core.status.event.selection=0; - core.ui.drawSyncSave(); - }) - } - else if (type=='load') { - core.status.event.selection=1; - core.ui.drawConfirmBox("你确定要从服务器加载存档吗?\n该操作将覆盖所有本地存档且不可逆!", function(){ - var id = prompt("请输入存档编号:"); - if (id==null || id=="") { - core.ui.drawSyncSave(); return; - } - var password = prompt("请输入存档密码:"); - if (password==null || password=="") { - core.ui.drawSyncSave(); return; - } - core.ui.drawWaiting("正在同步,请稍后..."); - - var formData = new FormData(); - formData.append('type', 'load'); - formData.append('name', core.firstData.name); - formData.append('id', id); - formData.append('password', password); - - // send - var xhr = new XMLHttpRequest(); - xhr.open("POST", "/games/sync.php"); - xhr.onload = function(e) { - if (xhr.status==200) { - // console.log("同步成功。"); - var response = JSON.parse(xhr.response); - switch (response.code) { - case 0: - // 成功 - var data=JSON.parse(response.msg); - // console.log(data); - for (var i=1;i<=150;i++) { - if (i<=data.length) { - core.setLocalStorage("save"+i, data[i-1]); - } - else { - core.removeLocalStorage("save"+i); - } - } - core.drawText("同步成功!\n你的本地所有存档均已被覆盖。"); - break; - case -1: - core.drawText("出错啦!\n存档编号"+id+"不存在!"); - break; - case -2: - core.drawText("出错啦!\n存档密码错误!"); - break; - default: - core.drawText("出错啦!\n无法从服务器同步存档。\n错误原因:"+response.msg); - break; - } - } - else { - core.drawText("出错啦!\n无法从服务器同步存档。\n错误原因:HTTP "+xhr.status); - } - }; - xhr.ontimeout = function() { - core.drawText("出错啦!\n无法同步存档到服务器。\n错误原因:Timeout"); - } - xhr.onerror = function() { - core.drawText("出错啦!\n无法同步存档到服务器。\n错误原因:XHR Error"); - } - xhr.send(formData); - }, function() { - core.status.event.selection=1; - core.ui.drawSyncSave(); - }) - } - -} -*/ ////// 存档到本地 ////// core.prototype.saveData = function(dataId) { - var data = { - 'floorId': core.status.floorId, - 'hero': core.clone(core.status.hero), - 'hard': core.status.hard, - 'maps': core.maps.save(core.status.maps), - 'route': core.encodeRoute(core.status.route), - 'shops': {}, - 'version': core.firstData.version, - "time": new Date().getTime() - }; - // set shop times - for (var shop in core.status.shops) { - data.shops[shop]={ - 'times': core.status.shops[shop].times || 0, - 'visited': core.status.shops[shop].visited || false - } - } - core.events.beforeSaveData(data); - - return core.setLocalStorage(dataId, data); + return core.control.saveData(dataId); } ////// 从本地读档 ////// core.prototype.loadData = function (data, callback) { - - core.resetStatus(data.hero, data.hard, data.floorId, core.decodeRoute(data.route), core.maps.load(data.maps)); - - // load shop times - for (var shop in core.status.shops) { - if (core.isset(data.shops[shop])) { - core.status.shops[shop].times = data.shops[shop].times; - core.status.shops[shop].visited = data.shops[shop].visited; - } - } - - core.events.afterLoadData(data); - - core.changeFloor(data.floorId, null, data.hero.loc, 0, function() { - if (core.isset(callback)) callback(); - }); + core.control.loadData(data, callback); } ////// 加密路线 ////// core.prototype.encodeRoute = function (route) { - var ans=""; - var lastMove = "", cnt=0; - - var items=Object.keys(core.material.items).sort(); - var shops=Object.keys(core.initStatus.shops).sort(); - route.forEach(function (t) { - if (t=='up' || t=='down' || t=='left' || t=='right') { - if (t!=lastMove && cnt>0) { - ans+=lastMove.substring(0,1).toUpperCase(); - if (cnt>1) ans+=cnt; - cnt=0; - } - lastMove=t; - cnt++; - } - else { - if (cnt>0) { - ans+=lastMove.substring(0,1).toUpperCase(); - if (cnt>1) ans+=cnt; - cnt=0; - } - if (t.indexOf('item:')==0) - ans+="I"+items.indexOf(t.substring(5)); - else if (t.indexOf('fly:')==0) - ans+="F"+core.floorIds.indexOf(t.substring(4)); - else if (t.indexOf('choices:')==0) - ans+="C"+t.substring(8); - else if (t.indexOf('shop:')==0) { - var sp=t.substring(5).split(":"); - ans+="S"+shops.indexOf(sp[0])+":"+sp[1]; - } - else if (t=='turn') - ans+='T'; - else if (t=='getNext') - ans+='G'; - else if (t.indexOf('input:')==0) - ans+="P"+t.substring(6); - else if (t=='no') - ans+='N'; - else if (t.indexOf('move:')==0) { - ans+="M"+t.substring(5); - } - } - }); - if (cnt>0) { - ans+=lastMove.substring(0,1).toUpperCase(); - if (cnt>1) ans+=cnt; - } - return ans; + return core.utils.encodeRoute(route); } ////// 解密路线 ////// core.prototype.decodeRoute = function (route) { + return core.utils.decodeRoute(route); +} - if (!core.isset(route)) return route; - - var ans=[], index=0; - - var getNumber = function (noparse) { - var num=""; - while (indexcore.firstData.levelUp.length) return core.status.hero.lv; - return core.firstData.levelUp[core.status.hero.lv-1].name || core.status.hero.lv; + return core.control.getLvName(); } ////// 设置某个自定义变量或flag ////// core.prototype.setFlag = function(flag, value) { - if (!core.isset(core.status.hero)) return; - core.status.hero.flags[flag]=value; + core.control.setFlag(flag, value); } ////// 获得某个自定义变量或flag ////// core.prototype.getFlag = function(flag, defaultValue) { - if (!core.isset(core.status.hero)) return defaultValue; - var value = core.status.hero.flags[flag]; - if (core.isset(value)) return value; - return defaultValue; + return core.control.getFlag(flag, defaultValue); } ////// 是否存在某个自定义变量或flag,且值为true ////// core.prototype.hasFlag = function(flag) { - if (core.getFlag(flag)) return true; - return false; + return core.control.hasFlag(flag); +} + +core.prototype.doAction = function() { + core.events.doAction(); } ////// 往当前事件列表之前插入一系列事件 ////// @@ -4976,754 +1043,86 @@ core.prototype.insertAction = function (list, x, y, callback) { ////// 锁定状态栏,常常用于事件处理 ////// core.prototype.lockControl = function () { - core.status.lockControl = true; + core.control.lockControl(); } ////// 解锁状态栏 ////// core.prototype.unLockControl = function () { - core.status.lockControl = false; + core.control.unLockControl(); } ////// 判断某对象是否不为undefined也不会null ////// core.prototype.isset = function (val) { - if (val == undefined || val == null || (typeof val=='number' && isNaN(val))) { - return false; - } - return true + return core.utils.isset(val); } ////// 读取一个本地文件内容 ////// core.prototype.readFile = function (success, error, readType) { - - // step 0: 不为http/https,直接不支持 - if (!core.platform.isOnline) { - alert("离线状态下不支持文件读取!"); - if (core.isset(error)) error(); - return; - } - - // Step 1: 如果不支持FileReader,直接不支持 - if (core.platform.fileReader==null) { - alert("当前浏览器不支持FileReader!"); - if (core.isset(error)) error(); - return; - } - - if (core.platform.fileInput==null) { - core.platform.fileInput = document.createElement("input"); - core.platform.fileInput.style.display = 'none'; - core.platform.fileInput.type = 'file'; - core.platform.fileInput.onchange = function () { - var files = core.platform.fileInput.files; - if (files.length==0) { - if (core.isset(core.platform.errorCallback)) - core.platform.errorCallback(); - return; - } - if(!readType)core.platform.fileReader.readAsText(core.platform.fileInput.files[0]); - else core.platform.fileReader.readAsDataURL(core.platform.fileInput.files[0]); - core.platform.fileInput.value = ''; - } - } - - core.platform.successCallback = success; - core.platform.errorCallback = error; - core.platform.fileInput.click(); + core.utils.readFile(success, error, readType); } ////// 下载文件到本地 ////// core.prototype.download = function (filename, content) { - - // Step 0: 不为http/https,直接不支持 - if (!core.platform.isOnline) { - alert("离线状态下不支持下载操作!"); - return; - } - - // Step 1: 如果是iOS平台,直接不支持 - if (core.platform.isIOS) { - alert("iOS平台下不支持下载操作!"); - return; - } - - // Step 2: 如果不是PC平台(Android),则只支持chrome - if (!core.platform.isPC) { - if (!core.platform.isChrome || core.platform.isQQ || core.platform.isWeChat) { // 检测chrome - if (core.copy(content)) { - alert("移动端只有Chrome浏览器支持直接下载文件!\n所有应下载内容已经复制到您的剪切板,请自行创建空白文件并粘贴。"); - } - else { - alert("该平台或浏览器暂不支持下载操作!"); - } - return; - } - } - - // Step 3: 如果是Safari浏览器,则提示并打开新窗口 - if (core.platform.isSafari) { - alert("你当前使用的是Safari浏览器,不支持直接下载文件。\n即将打开一个新窗口为应下载内容,请自行全选复制然后创建空白文件并粘贴。"); - var blob = new Blob([content], {type: 'text/plain;charset=utf-8'}); - var href = window.URL.createObjectURL(blob); - var opened=window.open(href, "_blank"); - // if (!opened) window.location.href=href; - window.URL.revokeObjectURL(href); - return; - } - - // Step 4: 下载 - var blob = new Blob([content], {type: 'text/plain;charset=utf-8'}); - if(window.navigator.msSaveOrOpenBlob) { - window.navigator.msSaveBlob(blob, filename); - } - else { - var href = window.URL.createObjectURL(blob); - var elem = window.document.createElement('a'); - elem.href = href; - elem.download = filename; - document.body.appendChild(elem); - elem.click(); - document.body.removeChild(elem); - window.URL.revokeObjectURL(href); - } + core.utils.download(filename, content); } ////// 复制一段内容到剪切板 ////// core.prototype.copy = function (data) { - if (!core.platform.supportCopy) return false; - - var textArea = document.createElement("textarea"); - textArea.style.position = 'fixed'; - textArea.style.top = 0; - textArea.style.left = 0; - textArea.style.width = '2em'; - textArea.style.height = '2em'; - textArea.style.padding = 0; - textArea.style.border = 'none'; - textArea.style.outline = 'none'; - textArea.style.boxShadow = 'none'; - textArea.style.background = 'transparent'; - textArea.value = data; - document.body.appendChild(textArea); - textArea.select(); - var successful = false; - try { - successful = document.execCommand('copy'); - } catch (err) { - successful = false; - } - - document.body.removeChild(textArea); - return successful; + return core.utils.copy(data); } ////// 播放背景音乐 ////// core.prototype.playBgm = function (bgm) { - if (main.mode!='play')return; - // 如果不允许播放 - if (!core.musicStatus.bgmStatus) return; - // 音频不存在 - if (!core.isset(core.material.bgms[bgm])) return; - - // 延迟播放 - if (core.material.bgms[bgm] == 'loading') { - core.material.bgms[bgm] = 'starting'; - return; - } - - try { - // 如果当前正在播放,且和本BGM相同,直接忽略 - if (core.musicStatus.playingBgm == bgm && core.musicStatus.isPlaying) { - return; - } - // 如果正在播放中,暂停 - if (core.isset(core.musicStatus.playingBgm) && core.musicStatus.isPlaying) { - core.material.bgms[core.musicStatus.playingBgm].pause(); - } - // 播放当前BGM - core.musicStatus.playingBgm = bgm; - core.material.bgms[bgm].play(); - core.musicStatus.isPlaying = true; - - } - catch (e) { - console.log("无法播放BGM "+bgm); - console.log(e); - core.musicStatus.playingBgm = null; - } + core.control.playBgm(bgm); } ////// 暂停背景音乐的播放 ////// core.prototype.pauseBgm = function () { - // 直接暂停播放 - try { - if (core.isset(core.musicStatus.playingBgm)) { - core.material.bgms[core.musicStatus.playingBgm].pause(); - } - core.musicStatus.isPlaying = false; - } - catch (e) { - console.log("无法暂停BGM "+bgm); - console.log(e); - } + core.control.pauseBgm(); } ////// 恢复背景音乐的播放 ////// core.prototype.resumeBgm = function () { - if (main.mode!='play')return; - // 如果不允许播放 - if (!core.musicStatus.bgmStatus) return; - - // 恢复BGM - try { - if (core.isset(core.musicStatus.playingBgm)) { - core.material.bgms[core.musicStatus.playingBgm].play(); - core.musicStatus.isPlaying = true; - } - else { - if (core.bgms.length>0) { - core.playBgm(core.bgms[0]); - core.musicStatus.isPlaying = true; - } - } - } - catch (e) { - console.log("无法恢复BGM "+bgm); - console.log(e); - } + core.control.resumeBgm(); } ////// 播放音频 ////// core.prototype.playSound = function (sound) { - if (main.mode!='play')return; - // 如果不允许播放 - if (!core.musicStatus.soundStatus) return; - // 音频不存在 - if (!core.isset(core.material.sounds[sound])) return; - - try { - if (core.musicStatus.audioContext != null) { - var source = core.musicStatus.audioContext.createBufferSource(); - source.buffer = core.material.sounds[sound]; - source.connect(core.musicStatus.audioContext.destination); - try { - source.start(0); - } - catch (e) { - try { - source.noteOn(0); - } - catch (ee) { - } - } - } - else { - core.material.sounds[sound].play(); - } - } - catch (eee) { - console.log("无法播放SE "+bgm); - console.log(eee); - } + core.control.playSound(sound); } ////// 动画显示某对象 ////// core.prototype.show = function (obj, speed, callback) { - if (!core.isset(speed)) { - obj.style.display = 'block'; - return; - } - obj.style.display = 'block'; - if (main.mode!='play'){ - obj.style.opacity = 1; - if (core.isset(callback)) {callback();} - return; - } - obj.style.opacity = 0; - var opacityVal = 0; - var showAnimate = window.setInterval(function () { - opacityVal += 0.03; - obj.style.opacity = opacityVal; - if (opacityVal > 1) { - clearInterval(showAnimate); - if (core.isset(callback)) { - callback(); - } - } - }, speed); + core.utils.show(obj, speed, callback); } ////// 动画使某对象消失 ////// core.prototype.hide = function (obj, speed, callback) { - if (!core.isset(speed)) { - obj.style.display = 'none'; - return; - } - if (main.mode!='play'){ - obj.style.display = 'none'; - if (core.isset(callback)) {callback();} - return; - } - var opacityVal = 1; - var hideAnimate = window.setInterval(function () { - opacityVal -= 0.03; - obj.style.opacity = opacityVal; - if (opacityVal < 0) { - obj.style.display = 'none'; - clearInterval(hideAnimate); - if (core.isset(callback)) { - callback(); - } - } - }, speed); + core.utils.hide(obj, speed, callback); } - ////// 清空状态栏 ////// core.prototype.clearStatusBar = function() { - var statusList = ['floor', 'lv', 'hp', 'atk', 'def', 'mdef', 'money', 'experience', 'up', 'yellowKey', 'blueKey', 'redKey', 'poison', 'weak', 'curse', 'hard']; - statusList.forEach(function (e) { - core.statusBar[e].innerHTML = " "; - }); - core.statusBar.image.book.style.opacity = 0.3; - core.statusBar.image.fly.style.opacity = 0.3; + core.control.clearStatusBar(); } ////// 更新状态栏 ////// core.prototype.updateStatusBar = function () { - - // 检查等级 - core.events.checkLvUp(); - - // 检查HP上限 - if (core.values.HPMAX>0) { - core.setStatus('hp', Math.min(core.values.HPMAX, core.getStatus('hp'))); - } - - // 更新领域、阻击、显伤 - core.updateCheckBlock(); - - var lvName = core.getLvName(); - core.statusBar.lv.innerHTML = lvName; - if (/^[+-]?\d+$/.test(lvName)) - core.statusBar.lv.style.fontStyle = 'italic'; - else core.statusBar.lv.style.fontStyle = 'normal'; - - var statusList = ['hp', 'atk', 'def', 'mdef', 'money', 'experience']; - statusList.forEach(function (item) { - core.statusBar[item].innerHTML = core.getStatus(item); - }); - // 进阶 - if (core.flags.enableLevelUp && core.status.hero.lv clientHeight && clientHeight < ADAPT_WIDTH){ - isHorizontal = true; - width = clientHeight; - } - // 各元素大小的变量声明 - var gameGroupWidth, gameGroupHeight, borderRight, - canvasWidth, canvasTop, // canvasLeft, - statusBarWidth, statusBarHeight, statusBarBorder, - statusWidth, statusHeight, statusMaxWidth,statusLabelsLH, - toolBarWidth, toolBarHeight, toolBarTop, toolBarBorder, - toolsWidth, toolsHeight,toolsMargin,toolsPMaxwidth, - fontSize, toolbarFontSize, margin; - - var count = 11; - if (!core.flags.enableFloor) count--; - if (!core.flags.enableLv) count--; - if (!core.flags.enableMDef) count--; - if (!core.flags.enableMoney) count--; - if (!core.flags.enableExperience) count--; - if (!core.flags.enableLevelUp) count--; - if (!core.flags.enableDebuff) count--; - - var statusLineHeight = BASE_LINEHEIGHT * 9 / count; - var statusLineFontSize = DEFAULT_FONT_SIZE; - if (count>9) statusLineFontSize = statusLineFontSize * 9 / count; - - var shopDisplay; - - statusBarBorder = '3px #fff solid'; - toolBarBorder = '3px #fff solid'; - var zoom = (ADAPT_WIDTH - width) / 4.22; - var aScale = 1 - zoom / 100; - - // 移动端 - if (width < CHANGE_WIDTH) { - if(width < ADAPT_WIDTH){ - - core.domStyle.scale = aScale; - canvasWidth = width; - }else{ - canvasWidth = DEFAULT_CANVAS_WIDTH; - core.domStyle.scale = 1; - } - - var scale = core.domStyle.scale - var tempWidth = DEFAULT_CANVAS_WIDTH * scale; - if(!isHorizontal){ //竖屏 - core.domStyle.screenMode = 'vertical'; - //显示快捷商店图标 - shopDisplay = 'block'; - //判断应该显示几行 - // var col = core.flags.enableMDef || core.flags.enableExperience || core.flags.enableDebuff ? 3 : 2; - var col = parseInt((count-1)/3)+1; - - var tempTopBarH = scale * (BASE_LINEHEIGHT * col + SPACE * 2) + 6; - var tempBotBarH = scale * (BASE_LINEHEIGHT + SPACE * 4) + 6; - - gameGroupHeight = tempWidth + tempTopBarH + tempBotBarH; - - gameGroupWidth = tempWidth - canvasTop = tempTopBarH; - // canvasLeft = 0; - toolBarWidth = statusBarWidth = canvasWidth; - statusBarHeight = tempTopBarH; - statusBarBorder = '3px #fff solid'; - - statusHeight = scale*BASE_LINEHEIGHT * .8; - statusLabelsLH = .8 * BASE_LINEHEIGHT *scale; - statusMaxWidth = scale * DEFAULT_BAR_WIDTH * .95; - toolBarHeight = tempBotBarH; - - toolBarTop = statusBarHeight + canvasWidth; - toolBarBorder = '3px #fff solid'; - toolsHeight = scale * BASE_LINEHEIGHT; - toolsPMaxwidth = scale * DEFAULT_BAR_WIDTH * .4; - borderRight = '3px #fff solid'; - - margin = scale * SPACE * 2; - toolsMargin = scale * SPACE * 4; - fontSize = DEFAULT_FONT_SIZE * scale; - toolbarFontSize = DEFAULT_FONT_SIZE * scale; - }else { //横屏 - core.domStyle.screenMode = 'horizontal'; - shopDisplay = 'none'; - gameGroupWidth = tempWidth + DEFAULT_BAR_WIDTH * scale; - gameGroupHeight = tempWidth; - canvasTop = 0; - // canvasLeft = DEFAULT_BAR_WIDTH * scale; - toolBarWidth = statusBarWidth = DEFAULT_BAR_WIDTH * scale; - statusBarHeight = scale * statusLineHeight * count + SPACE * 2; //一共有9行加上两个padding空隙 - statusBarBorder = '3px #fff solid'; - - statusHeight = scale*statusLineHeight * .8; - statusLabelsLH = .8 * statusLineHeight *scale; - toolBarHeight = canvasWidth - statusBarHeight; - toolBarTop = scale*statusLineHeight * count + SPACE * 2; - toolBarBorder = '3px #fff solid'; - toolsHeight = scale * BASE_LINEHEIGHT; - fontSize = statusLineFontSize * scale; - toolbarFontSize = DEFAULT_FONT_SIZE * scale; - borderRight = ''; - statusMaxWidth = scale * DEFAULT_BAR_WIDTH; - toolsPMaxwidth = scale * DEFAULT_BAR_WIDTH; - - margin = scale * SPACE * 2; - toolsMargin = 2 * SPACE * scale; - } - - }else { //大屏设备 pc端 - core.domStyle.scale = 1; - core.domStyle.screenMode = 'bigScreen'; - shopDisplay = 'none'; - - gameGroupWidth = DEFAULT_CANVAS_WIDTH + DEFAULT_BAR_WIDTH; - gameGroupHeight = DEFAULT_CANVAS_WIDTH; - canvasWidth = DEFAULT_CANVAS_WIDTH; - canvasTop = 0; - // canvasLeft = DEFAULT_BAR_WIDTH; - - toolBarWidth = statusBarWidth = DEFAULT_BAR_WIDTH; - statusBarHeight = statusLineHeight * count + SPACE * 2; //一共有9行 - - statusHeight = statusLineHeight * .8; - statusLabelsLH = .8 * statusLineHeight; - toolBarHeight = DEFAULT_CANVAS_WIDTH - statusBarHeight; - toolBarTop = statusLineHeight * count + SPACE * 2; - - toolsHeight = BASE_LINEHEIGHT; - borderRight = ''; - fontSize = statusLineFontSize; - toolbarFontSize = DEFAULT_FONT_SIZE; - statusMaxWidth = DEFAULT_BAR_WIDTH; - toolsPMaxwidth = DEFAULT_BAR_WIDTH * .9; - margin = SPACE * 2; - toolsMargin = 2 * SPACE; - } - - var unit = 'px' - core.domStyle.styles = [ - { - id: 'gameGroup', - rules:{ - width: gameGroupWidth + unit, - height: gameGroupHeight + unit, - top: (clientHeight-gameGroupHeight)/2 + unit, - left: (clientWidth-gameGroupWidth)/2 + unit, - } - }, - { - className: 'gameCanvas', - rules:{ - width: canvasWidth + unit, - height: canvasWidth + unit, - top: canvasTop + unit, - right: 0, - border: '3px #fff solid', - } - }, - { - id: 'curtain', - rules: { - width: (canvasWidth - SPACE*2) + unit, - height:(canvasWidth - SPACE*2) + unit, - top: (canvasTop + SPACE) + unit, - right: SPACE + unit, - } - }, - { - id: 'floorMsgGroup', - rules:{ - width: (canvasWidth - SPACE*2) + unit, - height: (gameGroupHeight - SPACE*2) + unit, - top: SPACE + unit, - right: SPACE + unit, - } - }, - { - id: 'statusBar', - rules:{ - width: statusBarWidth + unit, - height: statusBarHeight + unit, - top: 0, - left: 0, - padding: SPACE + unit, - - borderTop: statusBarBorder, - borderLeft: statusBarBorder, - borderRight: borderRight, - fontSize: fontSize + unit - } - }, - { - className: 'status', - rules:{ - width: '100%', - maxWidth: statusMaxWidth + unit, - height: statusHeight + unit, - margin: margin/2 + unit - } - }, - { - className: 'statusLabels', - rules:{ - marginLeft: margin + unit, - lineHeight: statusLabelsLH + unit, - } - }, - { - id: 'toolBar', - rules:{ - width: toolBarWidth + unit, - height: toolBarHeight + unit, - top: toolBarTop +unit, - left: 0, - padding: SPACE + unit, - borderBottom: toolBarBorder, - borderLeft: toolBarBorder, - borderRight: borderRight, - fontSize: toolbarFontSize + unit - } - }, - { - className: 'tools', - rules:{ - height: toolsHeight + unit, - maxWidth: toolsPMaxwidth + unit, - marginLeft: toolsMargin + unit, - marginTop: margin + unit, - } - }, - { - imgId: 'shop', - rules:{ - display: shopDisplay - } - }, - { - id: 'floorCol', - rules: { - display: core.flags.enableFloor ? 'block': 'none' - } - }, - { - id: 'lvCol', - rules: { - display: core.flags.enableLv ? 'block': 'none' - } - }, - { - id: 'mdefCol', - rules: { - display: core.flags.enableMDef ? 'block': 'none' - } - }, - { - id: 'moneyCol', - rules: { - display: core.flags.enableMoney ? 'block': 'none' - } - }, - { - id: 'expCol', - rules: { - display: core.flags.enableExperience ? 'block': 'none' - } - }, - { - id: 'upCol', - rules: { - display: core.flags.enableLevelUp ? 'block': 'none' - } - }, - { - 'id': 'debuffCol', - rules: { - display: core.flags.enableDebuff ? 'block': 'none' - } - }, - { - id: 'hard', - rules: { - lineHeight: toolsHeight + unit - } - } - ] - core.domRenderer(); + core.control.resize(clientWidth, clientHeight); } ////// 渲染DOM ////// core.prototype.domRenderer = function(){ - - core.dom.statusBar.style.display = 'block'; - core.dom.toolBar.style.display = 'block'; - - var styles = core.domStyle.styles; - - for(var i=0; i 1) text += "x" + itemNum; + if (itemCls === 'items') text += core.items.getItemEffectTip(itemId); + core.drawTip(text, core.material.icons.items[itemId]); + core.canvas.event.clearRect(itemX * 32, itemY * 32, 32, 32); + core.updateStatusBar(); + + // 检查处理后的事件。 + var event = core.floors[core.status.floorId].afterGetItem[itemX+","+itemY]; + if (core.isset(event)) { + core.events.doEvents(event, itemX, itemY, callback); + } + else if (core.isset(callback)) callback(); +} + +////// 开门 ////// +events.prototype.openDoor = function (id, x, y, needKey, callback) { + + if (core.interval.openDoorAnimate!=null) return; + + // 是否存在门 + if (!core.terrainExists(x, y, id)) { + if (core.isset(callback)) callback(); + return; + } + if (core.status.automaticRoute.moveStepBeforeStop.length==0) { + core.status.automaticRoute.moveStepBeforeStop=core.status.automaticRoute.autoStepRoutes.slice(core.status.automaticRoute.autoStep-1,core.status.automaticRoute.autoStepRoutes.length); + if (core.status.automaticRoute.moveStepBeforeStop.length>=1)core.status.automaticRoute.moveStepBeforeStop[0].step-=core.status.automaticRoute.movedStep; + } + + core.stopAutomaticRoute(); + var speed=30; + if (needKey) { + var key = id.replace("Door", "Key"); + if (!core.hasItem(key)) { + if (key != "specialKey") + core.drawTip("你没有" + core.material.items[key].name); + else core.drawTip("无法开启此门"); + core.clearContinueAutomaticRoute(); + return; + } + core.autosave(true); + core.removeItem(key); + } + + // open + core.playSound("door.ogg"); + var state = 0; + var doorId = id; + if (!(doorId.substring(doorId.length-4)=="Door")) { + doorId=doorId+"Door"; + speed=100; + } + var door = core.material.icons.animates[doorId]; + core.status.replay.animate=true; + core.interval.openDoorAnimate = window.setInterval(function () { + state++; + if (state == 4) { + clearInterval(core.interval.openDoorAnimate); + core.interval.openDoorAnimate=null; + core.removeBlock(x, y); + core.status.replay.animate=false; + core.events.afterOpenDoor(id,x,y,callback); + return; + } + 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); + }, speed) +} + +////// 战斗 ////// +events.prototype.battle = function (id, x, y, force, callback) { + if (core.status.automaticRoute.moveStepBeforeStop.length==0) { + core.status.automaticRoute.moveStepBeforeStop=core.status.automaticRoute.autoStepRoutes.slice(core.status.automaticRoute.autoStep-1,core.status.automaticRoute.autoStepRoutes.length); + if (core.status.automaticRoute.moveStepBeforeStop.length>=1)core.status.automaticRoute.moveStepBeforeStop[0].step-=core.status.automaticRoute.movedStep; + } + core.stopHero(); + core.stopAutomaticRoute(); + + var damage = core.enemys.getDamage(id); + // 非强制战斗 + if (damage >= core.status.hero.hp && !force) { + core.drawTip("你打不过此怪物!"); + core.clearContinueAutomaticRoute(); + return; + } + + if (!core.isset(core.status.event.id)) // 自动存档 + core.autosave(true); + + if (core.flags.battleAnimate&&!core.status.replay.replaying) { + core.waitHeroToStop(function() { + core.ui.drawBattleAnimate(id, function() { + core.events.afterBattle(id, x, y, callback); + }); + }); + } + else { + + if (core.flags.equipment && core.getFlag('sword', 'sword0')!='sword0') { + core.playSound('zone.ogg'); + core.drawAnimate('sword', x, y); + } + else { + core.playSound('attack.ogg'); + core.drawAnimate('hand', x, y); + } + + core.events.afterBattle(id, x, y, callback); + } +} + +////// 触发(x,y)点的事件 ////// +events.prototype.trigger = function (x, y) { + 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 && !(core.isset(mapBlocks[b].enable) && !mapBlocks[b].enable)) { // 启用事件 + noPass = mapBlocks[b].event && mapBlocks[b].event.noPass; + if (noPass) { + core.clearAutomaticRouteNode(x, y); + } + if (core.isset(mapBlocks[b].event) && core.isset(mapBlocks[b].event.trigger)) { + var trigger = mapBlocks[b].event.trigger; + + // 转换楼层能否穿透 + if (trigger=='changeFloor' && !noPass) { + var canCross = core.flags.portalWithoutTrigger; + if (core.isset(mapBlocks[b].event.data) && core.isset(mapBlocks[b].event.data.portalWithoutTrigger)) + canCross=mapBlocks[b].event.data.portalWithoutTrigger; + if (canCross) { + if (core.status.replay.replaying) { + if (core.status.replay.toReplay[0]=='no') { + core.status.replay.toReplay.shift(); + core.status.route.push("no"); + continue; + } + } + else if (core.status.automaticRoute.autoHeroMove || core.status.automaticRoute.autoStepcore.floorIds.indexOf(core.status.floorId)) + core.status.hero.flyRange.push(floorId); + else + core.status.hero.flyRange.unshift(floorId); + } + + window.setTimeout(function () { + + 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'; + else core.statusBar.floor.style.fontStyle = 'normal'; + + // 更改BGM + if (core.isset(core.floors[floorId].bgm)) { + core.playBgm(core.floors[floorId].bgm); + } + + // 不存在事件时,更改画面色调 + if (core.status.event.id == null) { + // 默认画面色调 + if (core.isset(core.floors[floorId].color)) { + var color = core.floors[floorId].color; + + // 直接变色 + core.dom.curtain.style.background = core.arrayToRGB(color); + if (core.isset(color[3])) + core.dom.curtain.style.opacity = color[3]; + else core.dom.curtain.style.opacity=1; + core.status.curtainColor = color; + } + else { + core.dom.curtain.style.background = "#000000"; + core.dom.curtain.style.opacity = 0; + } + } + + // 更改天气 + if (core.isset(core.floors[floorId].weather)) { + core.setWeather(core.floors[floorId].weather[0], core.floors[floorId].weather[1]) + } + else core.setWeather(); + + core.drawMap(floorId, function () { + setTimeout(function() { + if (core.isset(heroLoc.direction)) + 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.updateStatusBar(); + + var changed = function () { + core.unLockControl(); + core.status.replay.animate=false; + core.events.afterChangeFloor(floorId); + if (core.isset(callback)) callback(); + } + if (displayAnimate) { + core.hide(core.dom.floorMsgGroup, time/4, function () { + changed(); + }); + } + else { + changed(); + } + }, 25) + }); + } + core.playSound('floor.mp3'); + if (displayAnimate) { + core.show(core.dom.floorMsgGroup, time/2, function () { + changing(); + }); + } + else { + changing(); + } + }, 25); +} + ////// 打开一个全局商店 ////// events.prototype.openShop = function(shopId, needVisited) { var shop = core.status.shops[shopId]; @@ -850,12 +1133,12 @@ events.prototype.pushBox = function (data) { var blockIcon; if (block==null) { - core.status.thisMap.blocks.push(core.maps.getBlock(nx, ny, 169)); + core.status.thisMap.blocks.push(core.maps.initBlock(nx, ny, 169)); blockIcon=core.material.icons.terrains.box; } else { block.block.id=170; - block.block.event=core.maps.getBlock(null,null,170).event; + block.block.event=core.maps.initBlock(null,null,170).event; blockIcon=core.material.icons.terrains.boxed; } core.canvas.event.clearRect(nx * 32, ny * 32, 32, 32); @@ -866,7 +1149,7 @@ events.prototype.pushBox = function (data) { } else { data.id=168; - data.event=core.maps.getBlock(null,null,168).event; + data.event=core.maps.initBlock(null,null,168).event; core.canvas.event.clearRect(data.x * 32, data.y * 32, 32, 32); core.canvas.event.drawImage(core.material.images.terrains, 0, core.material.icons.terrains.flower * 32, 32, 32, data.x * 32, data.y * 32, 32, 32); } @@ -898,1237 +1181,5 @@ events.prototype.afterLoadData = eventdata.afterLoadData // function(data) -/****************************************/ -/********** 点击事件、键盘事件 ************/ -/****************************************/ - -////// 长按 ////// -events.prototype.longClick = function () { - if (core.status.event.id=='text') { - core.drawText(); - return true; - } - if (core.status.event.id=='action' && core.status.event.data.type=='text') { - this.doAction(); - return true; - } - return false; -} - -////// 按下Ctrl键时(快捷跳过对话) ////// -events.prototype.keyDownCtrl = function () { - if (core.status.event.id=='text') { - core.drawText(); - return; - } - if (core.status.event.id=='action' && core.status.event.data.type=='text') { - this.doAction(); - return; - } -} - -////// 点击确认框时 ////// -events.prototype.clickConfirmBox = function (x,y) { - if ((x == 4 || x == 5) && y == 7 && core.isset(core.status.event.data.yes)) - core.status.event.data.yes(); - if ((x == 7 || x == 8) && y == 7 && core.isset(core.status.event.data.no)) - core.status.event.data.no(); -} - -////// 键盘操作确认框时 ////// -events.prototype.keyUpConfirmBox = function (keycode) { - if (keycode==37) { - core.status.event.selection=0; - core.ui.drawConfirmBox(core.status.event.ui, core.status.event.data.yes, core.status.event.data.no); - } - - if (keycode==39) { - core.status.event.selection=1; - core.ui.drawConfirmBox(core.status.event.ui, core.status.event.data.yes, core.status.event.data.no); - } - - if (keycode==13 || keycode==32 || keycode==67) { - if (core.status.event.selection==0 && core.isset(core.status.event.data.yes)) { - core.status.event.selection=null; - core.status.event.data.yes(); - } - if (core.status.event.selection==1 && core.isset(core.status.event.data.no)) { - core.status.event.selection=null; - core.status.event.data.no(); - } - } -} - -////// 自定义事件时的点击操作 ////// -events.prototype.clickAction = function (x,y) { - - if (core.status.event.data.type=='text') { - // 文字 - this.doAction(); - return; - } - if (core.status.event.data.type=='choices') { - // 选项 - var data = core.status.event.data.current; - var choices = data.choices; - if (choices.length==0) return; - if (x >= 5 && x <= 7) { - var topIndex = 6 - parseInt((choices.length - 1) / 2); - if (y>=topIndex && y0) { - if (keycode==38) { - core.status.event.selection--; - core.ui.drawChoices(core.status.event.ui.text, core.status.event.ui.choices); - } - if (keycode==40) { - core.status.event.selection++; - core.ui.drawChoices(core.status.event.ui.text, core.status.event.ui.choices); - } - } - } -} - -////// 自定义事件时,放开某个键的操作 ////// -events.prototype.keyUpAction = function (keycode) { - if (core.status.event.data.type=='text' && (keycode==13 || keycode==32 || keycode==67)) { - this.doAction(); - return; - } - if (core.status.event.data.type=='choices') { - var data = core.status.event.data.current; - var choices = data.choices; - if (choices.length>0) { - if (keycode==13 || keycode==32 || keycode==67) { - core.status.route.push("choices:"+core.status.event.selection); - this.insertAction(choices[core.status.event.selection].action); - this.doAction(); - } - } - } -} - -////// 怪物手册界面的点击操作 ////// -events.prototype.clickBook = function(x,y) { - // 上一页 - if ((x == 3 || x == 4) && y == 12) { - core.ui.drawBook(core.status.event.data - 6); - return; - } - // 下一页 - if ((x == 8 || x == 9) && y == 12) { - core.ui.drawBook(core.status.event.data + 6); - return; - } - // 返回 - if (x>=10 && x<=12 && y==12) { - if (core.status.event.selection==null) - core.ui.closePanel(); - else { - core.status.boxAnimateObjs = []; - core.ui.drawMaps(core.status.event.selection); - } - return; - } - // 怪物信息 - var data = core.status.event.data; - if (core.isset(data) && y<12) { - var page=parseInt(data/6); - var index=6*page+parseInt(y/2); - core.ui.drawBook(index); - core.ui.drawBookDetail(index); - } - return; -} - -////// 怪物手册界面时,按下某个键的操作 ////// -events.prototype.keyDownBook = function (keycode) { - if (keycode==37) core.ui.drawBook(core.status.event.data-6); - if (keycode==38) core.ui.drawBook(core.status.event.data-1); - if (keycode==39) core.ui.drawBook(core.status.event.data+6); - if (keycode==40) core.ui.drawBook(core.status.event.data+1); - if (keycode==33) core.ui.drawBook(core.status.event.data-6); - if (keycode==34) core.ui.drawBook(core.status.event.data+6); - return; -} - -////// 怪物手册界面时,放开某个键的操作 ////// -events.prototype.keyUpBook = function (keycode) { - if (keycode==27 || keycode==88) { - if (core.status.event.selection==null) - core.ui.closePanel(); - else { - core.status.boxAnimateObjs = []; - core.ui.drawMaps(core.status.event.selection); - } - return; - } - if (keycode==13 || keycode==32 || keycode==67) { - var data=core.status.event.data; - if (core.isset(data)) { - this.clickBook(6, 2*(data%6)); - } - return; - } -} - -////// 怪物手册属性显示界面时的点击操作 ////// -events.prototype.clickBookDetail = function () { - core.clearMap('data', 0, 0, 416, 416); - core.status.event.id = 'book'; -} - -////// 楼层传送器界面时的点击操作 ////// -events.prototype.clickFly = function(x,y) { - if ((x==10 || x==11) && y==9) core.ui.drawFly(core.status.event.data-1); - if ((x==10 || x==11) && y==5) core.ui.drawFly(core.status.event.data+1); - if (x>=5 && x<=7 && y==12) core.ui.closePanel(); - if (x>=0 && x<=9 && y>=3 && y<=11) { - var index=core.status.hero.flyRange.indexOf(core.status.floorId); - var stair=core.status.event.data=8) { - core.ui.drawMaps(core.status.event.data-1); - } - else { - core.clearMap('data', 0, 0, 416, 416); - core.setOpacity('data', 1); - core.ui.closePanel(); - } -} - -////// 查看地图界面时,按下某个键的操作 ////// -events.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); - return; -} - -////// 查看地图界面时,放开某个键的操作 ////// -events.prototype.keyUpViewMaps = function (keycode) { - if (keycode==27 || keycode==13 || keycode==32 || keycode==67) { - core.clearMap('data', 0, 0, 416, 416); - core.setOpacity('data', 1); - core.ui.closePanel(); - } - if (keycode==88) { - core.openBook(false); - } - return; -} - -////// 商店界面时的点击操作 ////// -events.prototype.clickShop = function(x,y) { - var shop = core.status.event.data.shop; - var choices = shop.choices; - if (x >= 5 && x <= 7) { - var topIndex = 6 - parseInt(choices.length / 2); - if (y>=topIndex && y eval(use)) { - core.drawTip("你的"+use_text+"不足"); - return false; - } - - core.status.event.data.actions.push(y-topIndex); - - eval(use+'-='+need); - core.setStatus('money', money); - core.setStatus('experience', experience); - - // 更新属性 - choice.effect.split(";").forEach(function (t) { - core.doEffect(t); - }); - core.updateStatusBar(); - shop.times++; - this.openShop(core.status.event.data.id); - } - // 离开 - else if (y==topIndex+choices.length) { - if (core.status.event.data.actions.length>0) { - core.status.route.push("shop:"+core.status.event.data.id+":"+core.status.event.data.actions.join("")); - } - - core.status.event.data.actions = []; - core.status.boxAnimateObjs = []; - if (core.status.event.data.fromList) - core.ui.drawQuickShop(); - else core.ui.closePanel(); - } - else return false; - } - return true; -} - -////// 商店界面时,按下某个键的操作 ////// -events.prototype.keyDownShop = function (keycode) { - if (keycode==38) { - core.status.event.selection--; - core.ui.drawChoices(core.status.event.ui.text, core.status.event.ui.choices); - } - if (keycode==40) { - core.status.event.selection++; - core.ui.drawChoices(core.status.event.ui.text, core.status.event.ui.choices); - } -} - -////// 商店界面时,放开某个键的操作 ////// -events.prototype.keyUpShop = function (keycode) { - if (keycode==27 || keycode==88) { - if (core.status.event.data.actions.length>0) { - core.status.route.push("shop:"+core.status.event.data.id+":"+core.status.event.data.actions.join("")); - } - - core.status.event.data.actions = []; - - core.status.boxAnimateObjs = []; - - if (core.status.event.data.fromList) - core.ui.drawQuickShop(); - else - core.ui.closePanel(); - return; - } - var shop = core.status.event.data.shop; - var choices = shop.choices; - if (keycode==13 || keycode==32 || keycode==67) { - var topIndex = 6 - parseInt(choices.length / 2); - this.clickShop(6, topIndex+core.status.event.selection); - } - return; -} - -////// 快捷商店界面时的点击操作 ////// -events.prototype.clickQuickShop = function(x, y) { - var shopList = core.status.shops, keys = Object.keys(shopList); - if (x >= 5 && x <= 7) { - var topIndex = 6 - parseInt(keys.length / 2); - if (y>=topIndex && y=10 && x<=12 && y==12) { - core.ui.closePanel(); - return; - } - if (x>=10 && x<=12 && y<=1) { - if (!core.isset(core.status.event.data)) return; - if (!core.flags.enableDeleteItem) { - core.drawTip("不支持删除道具!"); - return; - } - core.removeItem(core.status.event.data); - core.status.event.data = null; - core.ui.drawToolbox(); - return; - } - - var index=0; - if (y==4||y==5||y==9||y==10) index=parseInt(x/2); - else index=6+parseInt(x/2); - if (y>=9) index+=100; - this.clickToolboxIndex(index); -} - -////// 选择工具栏界面中某个Index后的操作 ////// -events.prototype.clickToolboxIndex = function(index) { - var items = null; - var ii=index; - if (ii<100) - items = Object.keys(core.status.hero.items.tools).sort(); - else { - ii-=100; - items = Object.keys(core.status.hero.items.constants).sort(); - } - if (items==null) return; - if (ii>=items.length) return; - var itemId=items[ii]; - if (itemId==core.status.event.data) { - core.events.useItem(itemId); - } - else { - core.ui.drawToolbox(index); - } -} - -////// 工具栏界面时,按下某个键的操作 ////// -events.prototype.keyDownToolbox = function (keycode) { - if (!core.isset(core.status.event.data)) return; - - var tools = Object.keys(core.status.hero.items.tools).sort(); - var constants = Object.keys(core.status.hero.items.constants).sort(); - var index=core.status.event.selection; - - if (keycode==37) { // left - if ((index>0 && index<100) || index>100) { - this.clickToolboxIndex(index-1); - return; - } - if (index==100 && tools.length>0) { - this.clickToolboxIndex(tools.length-1); - return; - } - } - if (keycode==38) { // up - if ((index>5 && index<100) || index>105) { - this.clickToolboxIndex(index-6); - return; - } - if (index>=100 && index<=105) { - if (tools.length>6) { - this.clickToolboxIndex(Math.min(tools.length-1, index-100+6)); - } - else if (tools.length>0) { - this.clickToolboxIndex(Math.min(tools.length-1, index-100)); - } - return; - } - } - if (keycode==39) { // right - if ((index=100 && index0) { - this.clickToolboxIndex(100); - return; - } - } - if (keycode==40) { // down - if (index<=5) { - if (tools.length>6) { - this.clickToolboxIndex(Math.min(tools.length-1, index+6)); - } - else if (constants.length>0) { - this.clickToolboxIndex(100+Math.min(constants.length-1, index)); - } - return; - } - if (index>5 && index<100 && constants.length>0) { - this.clickToolboxIndex(100+Math.min(constants.length-1, index-6)); - return; - } - if (index>=100 && index<=105 && constants.length>6) { - this.clickToolboxIndex(Math.min(100+constants.length-1, index+6)); - return; - } - } -} - -////// 工具栏界面时,放开某个键的操作 ////// -events.prototype.keyUpToolbox = function (keycode) { - if (keycode==84 || keycode==27 || keycode==88) { - core.ui.closePanel(); - return; - } - if (!core.isset(core.status.event.data)) return; - - if (keycode==13 || keycode==32 || keycode==67) { - this.clickToolboxIndex(core.status.event.selection); - return; - } - - if (keycode==46) { // delete - if (!core.isset(core.status.event.data)) return; - if (!core.flags.enableDeleteItem) { - core.drawTip("不支持删除道具!"); - return; - } - core.removeItem(core.status.event.data); - core.status.event.data = null; - core.ui.drawToolbox(); - return; - } - -} - -////// 存读档界面时的点击操作 ////// -events.prototype.clickSL = function(x,y) { - - var index=core.status.event.data; - var page = parseInt(index/10), offset=index%10; - - // 上一页 - if ((x == 3 || x == 4) && y == 12) { - core.ui.drawSLPanel(10*(page-1)+offset); - } - // 下一页 - if ((x == 8 || x == 9) && y == 12) { - core.ui.drawSLPanel(10*(page+1)+offset); - } - // 返回 - if (x>=10 && x<=12 && y==12) { - core.ui.closePanel(); - if (!core.isPlaying()) { - core.showStartAnimate(); - } - return; - } - - var index=6*page+1; - if (y>=1 && y<=4) { - if (x>=1 && x<=3) core.doSL("autoSave", core.status.event.id); - if (x>=5 && x<=7) core.doSL(5*page+1, core.status.event.id); - if (x>=9 && x<=11) core.doSL(5*page+2, core.status.event.id); - } - if (y>=7 && y<=10) { - if (x>=1 && x<=3) core.doSL(5*page+3, core.status.event.id); - if (x>=5 && x<=7) core.doSL(5*page+4, core.status.event.id); - if (x>=9 && x<=11) core.doSL(5*page+5, core.status.event.id); - } -} - -////// 存读档界面时,按下某个键的操作 ////// -events.prototype.keyDownSL = function(keycode) { - - var index=core.status.event.data; - var page = parseInt(index/10), offset=index%10; - - if (keycode==37) { // left - if (offset==0) { - core.ui.drawSLPanel(10*(page-1) + 5); - } - else { - core.ui.drawSLPanel(index - 1); - } - return; - } - if (keycode==38) { // up - if (offset<3) { - core.ui.drawSLPanel(10*(page-1) + offset + 3); - } - else { - core.ui.drawSLPanel(index - 3); - } - return; - } - if (keycode==39) { // right - if (offset==5) { - core.ui.drawSLPanel(10*(page+1)+1); - } - else { - core.ui.drawSLPanel(index + 1); - } - return; - } - if (keycode==40) { // down - if (offset>=3) { - core.ui.drawSLPanel(10*(page+1) + offset - 3); - } - else { - core.ui.drawSLPanel(index + 3); - } - return; - } - if (keycode==33) { // PAGEUP - core.ui.drawSLPanel(10*(page-1) + offset); - return; - } - if (keycode==34) { // PAGEDOWN - core.ui.drawSLPanel(10*(page+1) + offset); - return; - } -} - -////// 存读档界面时,放开某个键的操作 ////// -events.prototype.keyUpSL = function (keycode) { - - var index=core.status.event.data; - var page = parseInt(index/10), offset=index%10; - - if (keycode==27 || keycode==88 || (core.status.event.id == 'save' && keycode==83) || (core.status.event.id == 'load' && keycode==68)) { - core.ui.closePanel(); - if (!core.isPlaying()) { - core.showStartAnimate(); - } - return; - } - if (keycode==13 || keycode==32 || keycode==67) { - if (offset==0) { - core.doSL("autoSave", core.status.event.id); - } - else { - core.doSL(5*page+offset, core.status.event.id); - } - return; - } -} - -////// 系统设置界面时的点击操作 ////// -events.prototype.clickSwitchs = 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 && y7) return; - var choices = core.status.event.ui.choices; - var topIndex = 6 - parseInt((choices.length - 1) / 2); - if (y>=topIndex && y0) { - text+="\n当前MAX为"+ending.max+",最早由 "+(ending.username||"匿名")+" 于"+core.formatDate(new Date(1000*ending.timestamp))+"打出。"; - } - }) - }) - core.drawText(text); - } - } - else { - core.drawText("出错啦!\n无法拉取统计信息。\n错误原因:HTTP "+xhr.status); - } - }; - xhr.ontimeout = function() { - core.drawText("出错啦!\n无法拉取统计信息。\n错误原因:Timeout"); - } - xhr.onerror = function() { - core.drawText("出错啦!\n无法拉取统计信息。\n错误原因:XHR Error"); - } - xhr.send(formData); - break; - case 6: - core.ui.drawHelp(); - break; - case 7: - core.ui.drawAbout(); - break; - case 8: - core.ui.closePanel(); - break; - } - } - return; -} - -////// 系统菜单栏界面时,按下某个键的操作 ////// -events.prototype.keyDownSettings = function (keycode) { - if (keycode==38) { - core.status.event.selection--; - core.ui.drawChoices(core.status.event.ui.text, core.status.event.ui.choices); - } - if (keycode==40) { - core.status.event.selection++; - core.ui.drawChoices(core.status.event.ui.text, core.status.event.ui.choices); - } -} - -////// 系统菜单栏界面时,放开某个键的操作 ////// -events.prototype.keyUpSettings = function (keycode) { - if (keycode==27 || keycode==88) { - core.ui.closePanel(); - return; - } - var choices = core.status.event.ui.choices; - if (keycode==13 || keycode==32 || keycode==67) { - var topIndex = 6 - parseInt((choices.length - 1) / 2); - this.clickSettings(6, topIndex+core.status.event.selection); - } -} - -////// 同步存档界面时的点击操作 ////// -events.prototype.clickSyncSave = 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;i--) { - if (core.getLocalStorage("save"+i, null)==null) - index=i; - else break; - } - core.setLocalStorage("save"+index, data); - core.drawText("同步成功!\n单存档已覆盖至存档"+index); - } - }, function () { - - }); - break; - case 4: - core.download(core.firstData.name+"_"+core.formatDate2(new Date())+".h5route", JSON.stringify({ - 'name': core.firstData.name, - 'hard': core.status.hard, - 'route': core.encodeRoute(core.status.route) - })); - break; - case 5: - core.status.event.selection=1; - core.ui.drawConfirmBox("你确定要清空所有存档吗?", function() { - localStorage.clear(); - core.drawText("\t[操作成功]你的所有存档已被清空。"); - }, function() { - core.status.event.selection=5; - core.ui.drawSyncSave(); - }) - break; - case 6: - core.status.event.selection=3; - core.ui.drawSettings(); - break; - - } - } - return; -} - -////// 同步存档界面时,按下某个键的操作 ////// -events.prototype.keyDownSyncSave = function (keycode) { - if (keycode==38) { - core.status.event.selection--; - core.ui.drawChoices(core.status.event.ui.text, core.status.event.ui.choices); - } - if (keycode==40) { - core.status.event.selection++; - core.ui.drawChoices(core.status.event.ui.text, core.status.event.ui.choices); - } -} - -////// 同步存档界面时,放开某个键的操作 ////// -events.prototype.keyUpSyncSave = function (keycode) { - if (keycode==27 || keycode==88) { - core.status.event.selection=2; - core.ui.drawSettings(); - return; - } - var choices = core.status.event.ui.choices; - if (keycode==13 || keycode==32 || keycode==67) { - var topIndex = 6 - parseInt((choices.length - 1) / 2); - this.clickSyncSave(6, topIndex+core.status.event.selection); - } -} - -////// 同步存档选择界面时的点击操作 ////// -events.prototype.clickSyncSelect = 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 && y7) return; - var choices = core.status.event.ui.choices; - - var topIndex = 6 - parseInt((choices.length - 1) / 2); - - var saves=null; - - if (y>=topIndex && y=1;i--) { - saves=core.getLocalStorage("save"+i, null); - if (core.isset(saves)) { - break; - } - } - break; - case 2: - break; - } - } - if (core.isset(saves)) { - var content = { - "name": core.firstData.name, - "version": core.firstData.version, - "data": saves - } - core.download(core.firstData.name+"_"+core.formatDate2(new Date())+".h5save", JSON.stringify(content)); - } - core.status.event.selection=2; - core.ui.drawSyncSave(); -} - -////// 存档下载界面时,按下某个键的操作 ////// -events.prototype.keyDownLocalSaveSelect = function (keycode) { - if (keycode==38) { - core.status.event.selection--; - core.ui.drawChoices(core.status.event.ui.text, core.status.event.ui.choices); - } - if (keycode==40) { - core.status.event.selection++; - core.ui.drawChoices(core.status.event.ui.text, core.status.event.ui.choices); - } -} - -////// 存档下载界面时,放开某个键的操作 ////// -events.prototype.keyUpLocalSaveSelect = function (keycode) { - if (keycode==27 || keycode==88) { - core.status.event.selection=0; - core.ui.drawSettings(); - return; - } - var choices = core.status.event.ui.choices; - if (keycode==13 || keycode==32 || keycode==67) { - var topIndex = 6 - parseInt((choices.length - 1) / 2); - this.clickLocalSaveSelect(6, topIndex+core.status.event.selection); - } -} - -////// “虚拟键盘”界面时的点击操作 ////// -events.prototype.clickKeyBoard = function (x, y) { - if (y==3 && x>=1 && x<=11) { - core.ui.closePanel(); - core.keyUp(112+x-1); // F1-F12: 112-122 - } - if (y==4 && x>=1 && x<=10) { - core.ui.closePanel(); - core.keyUp(x==10?48:48+x); // 1-9: 49-57; 0: 48 - } - // 字母 - var lines = [ - ["Q","W","E","R","T","Y","U","I","O","P"], - ["A","S","D","F","G","H","J","K","L"], - ["Z","X","C","V","B","N","M"], - ]; - if (y==5 && x>=1 && x<=10) { - core.ui.closePanel(); - core.keyUp(lines[0][x-1].charCodeAt(0)); - } - if (y==6 && x>=1 && x<=9) { - core.ui.closePanel(); - core.keyUp(lines[1][x-1].charCodeAt(0)); - } - if (y==7 && x>=1 && x<=7) { - core.ui.closePanel(); - core.keyUp(lines[2][x-1].charCodeAt(0)); - } - if (y==8 && x>=1 && x<=11) { - core.ui.closePanel(); - if (x==1) core.keyUp(189); // - - if (x==2) core.keyUp(187); // = - if (x==3) core.keyUp(219); // [ - if (x==4) core.keyUp(221); // ] - if (x==5) core.keyUp(220); // \ - if (x==6) core.keyUp(186); // ; - if (x==7) core.keyUp(222); // ' - if (x==8) core.keyUp(188); // , - if (x==9) core.keyUp(190); // . - if (x==10) core.keyUp(191); // / - if (x==11) core.keyUp(192); // ` - } - if (y==9 && x>=1 && x<=10) { - core.ui.closePanel(); - if (x==1) core.keyUp(27); // ESC - if (x==2) core.keyUp(9); // TAB - if (x==3) core.keyUp(20); // CAPS - if (x==4) core.keyUp(16); // SHIFT - if (x==5) core.keyUp(17); // CTRL - if (x==6) core.keyUp(18); // ALT - if (x==7) core.keyUp(32); // SPACE - if (x==8) core.keyUp(8); // BACKSPACE - if (x==9) core.keyUp(13); // ENTER - if (x==10) core.keyUp(46); // DEL - } - if (y==10 && x>=9 && x<=11) - core.ui.closePanel(); -} - -////// 光标界面时的点击操作 ////// -events.prototype.clickCursor = function (x,y) { - - if (x==core.status.automaticRoute.cursorX && y==core.status.automaticRoute.cursorY) { - core.ui.closePanel(); - core.onclick(x,y,[]); - return; - } - core.status.automaticRoute.cursorX=x; - core.status.automaticRoute.cursorY=y; - core.ui.drawCursor(); -} - -////// 光标界面时,按下某个键的操作 ////// -events.prototype.keyDownCursor = function (keycode) { - if (keycode==37) { // left - core.status.automaticRoute.cursorX--; - core.ui.drawCursor(); - return; - } - if (keycode==38) { // up - core.status.automaticRoute.cursorY--; - core.ui.drawCursor(); - return; - } - if (keycode==39) { // right - core.status.automaticRoute.cursorX++; - core.ui.drawCursor(); - return; - } - if (keycode==40) { // down - core.status.automaticRoute.cursorY++; - core.ui.drawCursor(); - return; - } -} - -////// 光标界面时,放开某个键的操作 ////// -events.prototype.keyUpCursor = function (keycode) { - if (keycode==27 || keycode==88) { - core.ui.closePanel(); - return; - } - if (keycode==13 || keycode==32 || keycode==67 || keycode==69) { - core.ui.closePanel(); - core.onclick(core.status.automaticRoute.cursorX, core.status.automaticRoute.cursorY, []); - return; - } -} - -////// “关于”界面时的点击操作 ////// -events.prototype.clickAbout = function () { - if (core.isPlaying()) - core.ui.closePanel(); - else - core.showStartAnimate(); -} delete(eventdata); \ No newline at end of file diff --git a/libs/icons.js b/libs/icons.js index 417ca988..f1a557a1 100644 --- a/libs/icons.js +++ b/libs/icons.js @@ -1,5 +1,5 @@ function icons() { - + this.init(); } icons.prototype.init = function () { @@ -9,6 +9,4 @@ icons.prototype.init = function () { icons.prototype.getIcons = function () { return this.icons; -} - -main.instance.icons = new icons(); \ No newline at end of file +} \ No newline at end of file diff --git a/libs/items.js b/libs/items.js index 0422392d..df582f25 100644 --- a/libs/items.js +++ b/libs/items.js @@ -1,5 +1,5 @@ function items() { - + this.init(); } ////// 初始化 ////// @@ -36,8 +36,6 @@ items.prototype.getItems = function () { return this.items; } -main.instance.items = new items(); - ////// “即捡即用类”道具的使用效果 ////// items.prototype.getItemEffect = function(itemId, itemNum) { var itemCls = core.material.items[itemId].cls; @@ -319,3 +317,57 @@ items.prototype.canUseItem = function (itemId) { return false; } + +////// 获得某个物品的个数 ////// +items.prototype.itemCount = function (itemId) { + if (!core.isset(itemId) || !core.isset(core.material.items[itemId])) return 0; + var itemCls = core.material.items[itemId].cls; + if (itemCls=="items") return 0; + return core.isset(core.status.hero.items[itemCls][itemId]) ? core.status.hero.items[itemCls][itemId] : 0; +} + +////// 是否存在某个物品 ////// +items.prototype.hasItem = function (itemId) { + return core.itemCount(itemId) > 0; +} + +////// 设置某个物品的个数 ////// +items.prototype.setItem = function (itemId, itemNum) { + var itemCls = core.material.items[itemId].cls; + if (itemCls == 'items') return; + if (!core.isset(core.status.hero.items[itemCls])) { + core.status.hero.items[itemCls] = {}; + } + core.status.hero.items[itemCls][itemId] = itemNum; + if (itemCls!='keys' && itemNum==0) { + delete core.status.hero.items[itemCls][itemId]; + } +} + +////// 删除某个物品 ////// +items.prototype.removeItem = function (itemId) { + if (!core.hasItem(itemId)) return false; + var itemCls = core.material.items[itemId].cls; + core.status.hero.items[itemCls][itemId]--; + if (itemCls!='keys' && core.status.hero.items[itemCls][itemId]==0) { + delete core.status.hero.items[itemCls][itemId]; + } + core.updateStatusBar(); + return true; +} + +////// 增加某个物品的个数 ////// +items.prototype.addItem = function (itemId, itemNum) { + var itemData = core.material.items[itemId]; + var itemCls = itemData.cls; + if (itemCls == 'items') return; + if (!core.isset(core.status.hero.items[itemCls])) { + core.status.hero.items[itemCls] = {}; + core.status.hero.items[itemCls][itemId] = 0; + } + else if (!core.isset(core.status.hero.items[itemCls][itemId])) { + core.status.hero.items[itemCls][itemId] = 0; + } + core.status.hero.items[itemCls][itemId] += itemNum; +} + diff --git a/libs/loader.js b/libs/loader.js new file mode 100644 index 00000000..e9a09e5e --- /dev/null +++ b/libs/loader.js @@ -0,0 +1,224 @@ +/* +loader.js:负责对资源的加载 + + */ + +function loader() { + this.init(); +} + +loader.prototype.init = function () { + +} + +////// 设置加载进度条进度 ////// +loader.prototype.setStartProgressVal = function (val) { + core.dom.startTopProgress.style.width = val + '%'; +} + +////// 设置加载进度条提示文字 ////// +loader.prototype.setStartLoadTipText = function (text) { + core.dom.startTopLoadTips.innerHTML = text; +} + +loader.prototype.load = function (callback) { + + // 加载图片 + core.loader.loadImages(core.images, core.material.images, function () { + // 加载png图片 + core.material.images.pngs = {}; + core.loader.loadImages(core.pngs, core.material.images.pngs, function () { + // 加载autotile + core.material.images.autotile = {}; + core.loader.loadImages(Object.keys(core.material.icons.autotile), core.material.images.autotile, function () { + core.loader.loadAnimates(); + core.loader.loadMusic(); + if (core.isset(callback)) + callback(); + }) + }) + }) +} + +loader.prototype.loadImages = function (names, toSave, callback) { + if (names.length==0) { + if (core.isset(callback)) callback(); + return; + } + var items = 0; + for (var i=0;i0) + core.playBgm(core.bgms[0]); +} diff --git a/libs/maps.js b/libs/maps.js index d6b17e66..032b59f5 100644 --- a/libs/maps.js +++ b/libs/maps.js @@ -1,4 +1,7 @@ -function maps() {} +function maps() { + this.init(); +} + maps.prototype.init = function() { this.blocksInfo = maps_90f36752_8815_4be8_b32b_d7fad1d0542e; //delete(maps_90f36752_8815_4be8_b32b_d7fad1d0542e); @@ -17,7 +20,7 @@ maps.prototype.loadFloor = function (floorId, map) { var blocks = []; for (var i = 0; i < 13; i++) { for (var j = 0; j < 13; j++) { - var block = maps.getBlock(j, i, map[i][j]); + var block = maps.initBlock(j, i, map[i][j]); maps.addInfo(block); maps.addEvent(block,j,i,floor.events[j+","+i]) maps.addChangeFloor(block,j,i,floor.changeFloor[j+","+i]); @@ -37,7 +40,7 @@ maps.prototype.loadFloor = function (floorId, map) { } ////// 数字和ID的对应关系 ////// -maps.prototype.getBlock = function (x, y, id) { +maps.prototype.initBlock = function (x, y, id) { var enable=null; id = ""+id; if (id.length>2) { @@ -199,4 +202,688 @@ maps.prototype.getMapArray = function (blockArray){ return blocks; } -main.instance.maps = new maps(); \ No newline at end of file + + +////// 勇士能否前往某方向 ////// +maps.prototype.canMoveHero = function(x,y,direction,floorId) { + if (!core.isset(x)) x=core.getHeroLoc('x'); + if (!core.isset(y)) y=core.getHeroLoc('y'); + if (!core.isset(direction)) direction=core.getHeroLoc('direction'); + if (!core.isset(floorId)) floorId=core.status.floorId; + + // 检查当前块的cannotMove + if (core.isset(core.floors[floorId].cannotMove)) { + var cannotMove = core.floors[floorId].cannotMove[x+","+y]; + if (core.isset(cannotMove) && cannotMove instanceof Array && cannotMove.indexOf(direction)>=0) + return false; + } + + var nowBlock = core.getBlock(x,y,floorId); + if (nowBlock!=null){ + nowId = nowBlock.block.event.id; + var nowIsArrow = nowId.slice(0, 5).toLowerCase() == 'arrow'; + if(nowIsArrow){ + var nowArrow = nowId.slice(5).toLowerCase(); + if (direction != nowArrow) { + return false; + } + } + } + var scan = { + 'up': {'x': 0, 'y': -1}, + 'left': {'x': -1, 'y': 0}, + 'down': {'x': 0, 'y': 1}, + 'right': {'x': 1, 'y': 0} + }; + var nextBlock = core.getBlock(x+scan[direction].x,y+scan[direction].y,floorId); + if (nextBlock!=null){ + nextId = nextBlock.block.event.id; + // 遇到单向箭头处理 + var isArrow = nextId.slice(0, 5).toLowerCase() == 'arrow'; + if(isArrow){ + var nextArrow = nextId.slice(5).toLowerCase(); + if ( (scan[direction].x + scan[nextArrow].x) == 0 && (scan[direction].y + scan[nextArrow].y) == 0 ) { + return false; + } + } + } + return true; +} + +////// 能否瞬间移动 ////// +maps.prototype.canMoveDirectly = function (destX,destY) { + if (!core.flags.enableMoveDirectly) return false; + + // 中毒状态:不能 + if (core.hasFlag('poison')) return false; + + var fromX = core.getHeroLoc('x'), fromY = core.getHeroLoc('y'); + if (fromX==destX&&fromY==destY) return false; + + if (core.getBlock(fromX,fromY)!=null||core.status.checkBlock.damage[13*fromX+fromY]>0) + return false; + + // BFS + var visited=[], queue=[]; + visited[13*fromX+fromY]=true; + queue.push(13*fromX+fromY); + + var directions = [[-1,0],[1,0],[0,1],[0,-1]]; + while (queue.length>0) { + var now=queue.shift(), nowX=parseInt(now/13), nowY=now%13; + + for (var dir in directions) { + var nx=nowX+directions[dir][0], ny=nowY+directions[dir][1]; + if (nx<0||nx>=13||ny<0||ny>=13||visited[13*nx+ny]||core.getBlock(nx,ny)!=null||core.status.checkBlock.damage[13*nx+ny]>0) continue; + if (nx==destX&&ny==destY) return true; + visited[13*nx+ny]=true; + queue.push(13*nx+ny); + } + } + return false; +} + +////// 绘制某张地图 ////// +maps.prototype.drawMap = function (mapName, callback) { + core.clearMap('all'); + core.removeGlobalAnimate(null, null, true); + var drawBg = function(){ + var groundId = core.floors[mapName].defaultGround || "ground"; + var blockIcon = core.material.icons.terrains[groundId]; + var blockImage = core.material.images.terrains; + for (var x = 0; x < 13; x++) { + for (var y = 0; y < 13; y++) { + core.canvas.bg.drawImage(blockImage, 0, blockIcon * 32, 32, 32, x * 32, y * 32, 32, 32); + } + } + // 如果存在png + if (core.isset(core.floors[mapName].png)) { + + var x=0, y=0, size=416; + + var png = core.floors[mapName].png; + + var ratio = size/416; + + if (typeof png == 'string') { + if (core.isset(core.material.images.pngs[png])) { + core.canvas.bg.drawImage(core.material.images.pngs[png], x, y, size, size); + } + } + else if (png instanceof Array) { + png.forEach(function (t) { + if (t.length!=3) return; + var dx=parseInt(t[0]), dy=parseInt(t[1]), p=t[2]; + if (core.isset(dx) && core.isset(dy) && core.isset(core.material.images.pngs[p])) { + dx*=32; dy*=32; + var image = core.material.images.pngs[p]; + core.canvas.bg.drawImage(image, x+dx*ratio, y+dy*ratio, Math.min(size-dx*ratio, ratio*image.width), Math.min(size-dy*ratio, ratio*image.height)); + } + }) + } + } + } + if (main.mode=='editor'){ + main.editor.drawMapBg = function(){ + core.clearMap('bg', 0, 0, 416, 416); + drawBg(); + } + } else { + drawBg(); + } + + core.status.floorId = mapName; + core.status.thisMap = core.status.maps[mapName]; + var drawEvent = function(){ + var mapData = core.status.maps[core.status.floorId]; + var mapBlocks = mapData.blocks; + + var mapArray = core.maps.getMapArray(mapBlocks); + for (var b = 0; b < mapBlocks.length; b++) { + // 事件启用 + var block = mapBlocks[b]; + if (core.isset(block.event) && !(core.isset(block.enable) && !block.enable)) { + if (block.event.cls == 'autotile') { + core.drawAutotile(core.canvas.event, mapArray, block, 32, 0, 0); + } + else { + if (block.event.id!='none') { + 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); + } + } + } + } + } + + if (main.mode=='editor'){ + main.editor.updateMap = function(){ + core.removeGlobalAnimate(null, null, true); + core.clearMap('event', 0, 0, 416, 416); + drawEvent(); + core.setGlobalAnimate(core.values.animateSpeed); + } + } else { + drawEvent(); + } + core.setGlobalAnimate(core.values.animateSpeed); + if (core.isset(callback)) + callback(); +} + +////// 绘制Autotile ////// +maps.prototype.drawAutotile = function(ctx, mapArr, block, size, left, top){ + var indexArrs = [ //16种组合的图块索引数组; // 将autotile分割成48块16*16的小块; 数组索引即对应各个小块 + // +----+----+----+----+----+----+ + [10, 9, 4, 3 ], //0 bin:0000 | 1 | 2 | 3 | 4 | 5 | 6 | + [10, 9, 4, 13], //1 bin:0001 +----+----+----+----+----+----+ + [10, 9, 18, 3 ], //2 bin:0010 | 7 | 8 | 9 | 10 | 11 | 12 | + [10, 9, 16, 15], //3 bin:0011 +----+----+----+----+----+----+ + [10, 43, 4, 3 ], //4 bin:0100 | 13 | 14 | 15 | 16 | 17 | 18 | + [10, 31, 4, 25], //5 bin:0101 +----+----+----+----+----+----+ + [10, 7, 2, 3 ], //6 bin:0110 | 19 | 20 | 21 | 22 | 23 | 24 | + [10, 31, 16, 5 ], //7 bin:0111 +----+----+----+----+----+----+ + [48, 9, 4, 3 ], //8 bin:1000 | 25 | 26 | 27 | 28 | 29 | 30 | + [ 8, 9, 4, 1 ], //9 bin:1001 +----+----+----+----+----+----+ + [36, 9, 30, 3 ], //10 bin:1010 | 31 | 32 | 33 | 34 | 35 | 36 | + [36, 9, 6, 15], //11 bin:1011 +----+----+----+----+----+----+ + [46, 45, 4, 3 ], //12 bin:1100 | 37 | 38 | 39 | 40 | 41 | 42 | + [46, 11, 4, 25], //13 bin:1101 +----+----+----+----+----+----+ + [12, 45, 30, 3 ], //14 bin:1110 | 43 | 44 | 45 | 46 | 47 | 48 | + [34, 33, 28, 27] //15 bin:1111 +----+----+----+----+----+----+ + ]; + + var drawBlockByIndex = function(ctx, dx, dy, autotileImg, index, size){ //index为autotile的图块索引1-48 + var sx = 16*((index-1)%6), sy = 16*(~~((index-1)/6)); + ctx.drawImage(autotileImg, sx, sy, 16, 16, dx, dy, size/2, size/2); + } + var getAutotileAroundId = function(currId, x, y){ + if(x<0 || y<0 || x>12 || y>12) return 1; + else return mapArr[y][x]==currId ? 1:0; + } + var checkAround = function(x, y){ // 得到周围四个32*32块(周围每块都包含当前块的1/4,不清楚的话画下图你就明白)的数组索引 + var currId = mapArr[y][x]; + var pointBlock = []; + for(var i=0; i<4; i++){ + var bsum = 0; + var offsetx = i%2, offsety = ~~(i/2); + for(var j=0; j<4; j++){ + var mx = j%2, my = ~~(j/2); + var b = getAutotileAroundId(currId, x+offsetx+mx-1, y+offsety+my-1); + bsum += b*(Math.pow(2, 3-j)); + } + pointBlock.push(bsum); + } + return pointBlock; + } + var getAutotileIndexs = function(x, y){ + var indexArr = []; + var pointBlocks = checkAround(x, y); + for(var i=0; i<4; i++){ + var arr = indexArrs[pointBlocks[i]] + indexArr.push(arr[3-i]); + } + return indexArr; + } + // 开始绘制autotile + var x = block.x, y = block.y; + var pieceIndexs = getAutotileIndexs(x, y); + + //修正四个边角的固定搭配 + if(pieceIndexs[0] == 13){ + if(pieceIndexs[1] == 16) pieceIndexs[1] = 14; + if(pieceIndexs[2] == 31) pieceIndexs[2] = 19; + } + if(pieceIndexs[1] == 18){ + if(pieceIndexs[0] == 15) pieceIndexs[0] = 17; + if(pieceIndexs[3] == 36) pieceIndexs[3] = 24; + } + if(pieceIndexs[2] == 43){ + if(pieceIndexs[0] == 25) pieceIndexs[0] = 37; + if(pieceIndexs[3] == 46) pieceIndexs[3] = 44; + } + if(pieceIndexs[3] == 48){ + if(pieceIndexs[1] == 30) pieceIndexs[1] = 42; + if(pieceIndexs[2] == 45) pieceIndexs[2] = 47; + } + for(var i=0; i<4; i++){ + var index = pieceIndexs[i]; + var dx = x*size + size/2*(i%2), dy = y*size + size/2*(~~(i/2)); + drawBlockByIndex(ctx, dx+left, dy+top, core.material.images['autotile'][block.event.id], index, size); + } +} + +////// 某个点是否不可通行 ////// +maps.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; +} + +////// 某个点是否在区域内且不可通行 ////// +maps.prototype.noPass = function (x, y) { + return x<0 || x>12 || y<0 || y>12 || this.noPassExists(x,y); +} + +////// 某个点是否存在NPC ////// +maps.prototype.npcExists = function (x, y, floorId) { + var block = this.getBlock(x,y,floorId); + if (block==null) return false; + return block.block.event.cls == 'npcs'; +} + +////// 某个点是否存在(指定的)地形 ////// +maps.prototype.terrainExists = function (x, y, id, floorId) { + var block = this.getBlock(x,y,floorId); + if (block==null) return false; + return block.block.event.cls=='terrains' && (core.isset(id)?block.block.event.id==id:true); +} + +////// 某个点是否存在楼梯 ////// +maps.prototype.stairExists = function (x, y, floorId) { + var block = this.getBlock(x,y,floorId); + if (block==null) return false; + return block.block.event.cls=='terrains' && (block.block.event.id=='upFloor' || block.block.event.id=='downFloor'); +} + +////// 当前位置是否在楼梯边 ////// +maps.prototype.nearStair = function() { + var x=core.getHeroLoc('x'), y=core.getHeroLoc('y'); + return this.stairExists(x,y) || this.stairExists(x-1,y) || this.stairExists(x,y-1) || this.stairExists(x+1,y) || this.stairExists(x,y+1); +} + +////// 某个点是否存在(指定的)怪物 ////// +maps.prototype.enemyExists = function (x, y, id,floorId) { + var block = this.getBlock(x,y,floorId); + if (block==null) return false; + return block.block.event.cls=='enemys' && (core.isset(id)?block.block.event.id==id:true); +} + +////// 获得某个点的block ////// +maps.prototype.getBlock = function (x, y, floorId, needEnable) { + 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= core.values.animateSpeed * 2 / animateValue) { + animateCurrent++; + animateTime = 0; + if (animateCurrent>=animateValue) animateCurrent=0; + } + + // 已经移动完毕,消失 + if (moveSteps.length==0) { + if (immediateHide) opacityVal=0; + else opacityVal -= 0.06; + core.setOpacity('animate', opacityVal); + core.clearMap('animate', nowX, nowY, 32, 32); + core.canvas.animate.drawImage(blockImage, animateCurrent * 32, blockIcon * 32, 32, 32, nowX, nowY, 32, 32); + if (opacityVal<=0) { + clearInterval(animate); + core.loadCanvas('animate'); + core.clearMap('animate', 0, 0, 416, 416); + core.setOpacity('animate', 1); + core.status.replay.animate=false; + if (core.isset(callback)) callback(); + } + } + else { + // 移动中 + step++; + nowX+=scan[moveSteps[0]].x*2; + nowY+=scan[moveSteps[0]].y*2; + core.clearMap('animate', nowX-32, nowY-32, 96, 96); + // 绘制 + core.canvas.animate.drawImage(blockImage, animateCurrent * 32, blockIcon * 32, 32, 32, nowX, nowY, 32, 32); + if (step==16) { + // 该移动完毕,继续 + step=0; + moveSteps.shift(); + } + } + }, time / 16 / core.status.replay.speed); +} + +////// 显示/隐藏某个块时的动画效果 ////// +maps.prototype.animateBlock = function (loc,type,time,callback) { + if (type!='hide') type='show'; + + //clearInterval(core.interval.tipAnimate); + core.saveCanvas('animate'); + core.clearMap('animate', 0, 0, 416, 416); + + if (typeof loc[0] == 'number' && typeof loc[1] == 'number') + loc = [loc]; + + var list = []; + loc.forEach(function (t) { + var block = core.getBlock(t[0],t[1],core.status.floorId,false); + if (block==null) return; + block=block.block; + list.push({ + 'x': t[0], 'y': t[1], + 'blockIcon': core.material.icons[block.event.cls][block.event.id], + 'blockImage': core.material.images[block.event.cls] + }) + }) + + if (list.length==0) { + if (core.isset(callback)) callback(); + return; + } + + core.status.replay.animate=true; + var draw = function () { + list.forEach(function (t) { + core.canvas.animate.drawImage(t.blockImage, 0, t.blockIcon * 32, 32, 32, t.x * 32, t.y * 32, 32, 32); + }) + } + + var opacityVal = 0; + if (type=='hide') opacityVal=1; + + core.setOpacity('animate', opacityVal); + draw(); + + var animate = window.setInterval(function () { + if (type=='show') opacityVal += 0.1; + else opacityVal -= 0.1; + core.setOpacity('animate', opacityVal); + core.clearMap('animate',0,0,416,416); + + // core.canvas.animate.drawImage(blockImage, 0, blockIcon * 32, 32, 32, block.x * 32, block.y * 32, 32, 32); + draw(); + if (opacityVal >=1 || opacityVal<=0) { + clearInterval(animate); + core.loadCanvas('animate'); + core.clearMap('animate', 0, 0, 416, 416); + core.setOpacity('animate', 1); + core.status.replay.animate=false; + if (core.isset(callback)) callback(); + } + }, time / 10 / core.status.replay.speed); +} + +////// 将某个块从禁用变成启用状态 ////// +maps.prototype.showBlock = 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.syncGlobalAnimate(); + } + core.updateStatusBar(); + } +} + +////// 将某个块从启用变成禁用状态 ////// +maps.prototype.removeBlock = function (x, y, floorId) { + floorId = floorId || core.status.floorId; + + var block = core.getBlock(x,y,floorId,false); + if (block==null) return; // 不存在 + + var index=block.index; + + // 删除动画,清除地图 + if (floorId==core.status.floorId) { + core.removeGlobalAnimate(x, y); + core.canvas.event.clearRect(x * 32, y * 32, 32, 32); + } + + // 删除Index + core.removeBlockById(index, floorId); + core.updateFg(); +} + +////// 根据block的索引删除该块 ////// +maps.prototype.removeBlockById = function (index, floorId) { + + var blocks = core.status.maps[floorId].blocks; + var x=blocks[index].x, y=blocks[index].y; + + // 检查该点是否存在事件 + 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; + } + blocks[index].enable = false; +} + +////// 一次性删除多个block ////// +maps.prototype.removeBlockByIds = function (floorId, ids) { + ids.sort(function (a,b) {return b-a}).forEach(function (id) { + core.removeBlockById(id, floorId); + }); +} + +////// 添加一个全局动画 ////// +maps.prototype.addGlobalAnimate = function (animateMore, x, y, loc, image) { + if (main.mode=='editor' && main.editor.disableGlobalAnimate) return; + if (animateMore == 2) { + core.status.twoAnimateObjs.push({ + 'x': x, + 'y': y, + 'status': 0, + 'loc': loc, + 'image': image + }); + } + else if (animateMore == 4) { + core.status.fourAnimateObjs.push({ + 'x': x, + 'y': y, + 'status': 0, + 'loc': loc, + 'image': image + }); + } +} + +////// 删除一个或所有全局动画 ////// +maps.prototype.removeGlobalAnimate = function (x, y, all) { + if (all == true) { + core.status.twoAnimateObjs = []; + core.status.fourAnimateObjs = []; + } + + if (main.mode=='editor' && main.editor.disableGlobalAnimate) return; + + for (var t = 0; t < core.status.twoAnimateObjs.length; t++) { + if (core.status.twoAnimateObjs[t].x == x * 32 && core.status.twoAnimateObjs[t].y == y * 32) { + core.status.twoAnimateObjs.splice(t, 1); + return; + } + } + for (var f = 0; f < core.status.fourAnimateObjs.length; f++) { + if (core.status.fourAnimateObjs[f].x == x * 32 && core.status.fourAnimateObjs[f].y == y * 32) { + core.status.fourAnimateObjs.splice(f, 1); + return; + } + } +} + +////// 设置全局动画的显示效果 ////// +maps.prototype.setGlobalAnimate = function (speed) { + if (main.mode=='editor' && main.editor.disableGlobalAnimate) return; + core.syncGlobalAnimate(); + core.animateFrame.speed = speed; + core.animateFrame.globalAnimate = true; +} + +////// 同步所有的全局动画效果 ////// +maps.prototype.syncGlobalAnimate = function () { + core.status.twoAnimateObjs.forEach(function (t) { + t.status=0; + }) + core.status.fourAnimateObjs.forEach(function (t) { + t.status=0; + }) +} + +////// 绘制UI层的box动画 ////// +maps.prototype.drawBoxAnimate = function () { + for (var a = 0; a < core.status.boxAnimateObjs.length; a++) { + var obj = core.status.boxAnimateObjs[a]; + obj.status = ((obj.status||0)+1)%2; + core.clearMap('ui', obj.bgx, obj.bgy, obj.bgsize, obj.bgsize); + core.fillRect('ui', obj.bgx, obj.bgy, obj.bgsize, obj.bgsize, core.animateFrame.background); + core.canvas.ui.drawImage(obj.image, obj.status * 32, obj.icon * 32, + 32, 32, obj.x, obj.y, 32, 32); + } +} + +////// 绘制动画 ////// +maps.prototype.drawAnimate = function (name, x, y, callback) { + + // 正在播放录像:不显示动画 + if (core.isset(core.status.replay) && core.status.replay.replaying) { + if (core.isset(callback)) callback(); + return; + } + + // 检测动画是否存在 + if (!core.isset(core.material.animates[name]) || !core.isset(x) || !core.isset(y)) { + if (core.isset(callback)) callback(); + return; + } + + // 清空animate层 + clearInterval(core.interval.animateInterval); + core.clearMap('animate', 0, 0, 416, 416); + + // 开始绘制 + var animate = core.material.animates[name]; + var ratio = animate.ratio; + var centerX = 32*x+16, centerY = 32*y+16; + var index=0; + + var draw = function (index) { + core.clearMap('animate', 0, 0, 416, 416); + + var frame = animate.frames[index]; + frame.forEach(function (t) { + var image = animate.images[t.index]; + if (!core.isset(image)) return; + var realWidth = image.width * ratio * t.zoom / 100; + var realHeight = image.height * ratio * t.zoom / 100; + core.setAlpha('animate', t.opacity / 255); + + var cx = centerX+t.x, cy=centerY+t.y; + + if (!t.mirror && !t.angle) { + core.canvas.animate.drawImage(image, cx-realWidth/2, cy-realHeight/2, realWidth, realHeight); + } + else { + core.saveCanvas('animate'); + core.canvas.animate.translate(cx,cy); + if (t.angle) + core.canvas.animate.rotate(-t.angle*Math.PI/180); + if (t.mirror) + core.canvas.animate.scale(-1,1); + core.canvas.animate.drawImage(image, -realWidth/2, -realHeight/2, realWidth, realHeight); + core.loadCanvas('animate'); + } + }) + } + + draw(index++); + + core.interval.animateInterval = setInterval(function (t) { + if (index == animate.frames.length) { + clearInterval(core.interval.animateInterval); + core.clearMap('animate', 0, 0, 416, 416); + core.setAlpha('animate', 1); + if (core.isset(callback)) callback(); + return; + } + draw(index++); + }, 50); +} \ No newline at end of file diff --git a/libs/ui.js b/libs/ui.js index 6f9a8e8c..638897b3 100644 --- a/libs/ui.js +++ b/libs/ui.js @@ -3,14 +3,146 @@ * 包括: * 自动寻路、怪物手册、楼传器、存读档、菜单栏、NPC对话事件、等等 */ -function ui() {} +function ui() { + this.init(); +} var uidata = functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a.ui; // 初始化UI ui.prototype.init = function () { + } -main.instance.ui = new ui(); +////////////////// 地图设置 +////// 清除地图 ////// +ui.prototype.clearMap = function (map, x, y, width, height) { + if (map == 'all') { + for (var m in core.canvas) { + core.canvas[m].clearRect(0, 0, 416, 416); + } + } + else { + core.canvas[map].clearRect(x||0, y||0, width||416, height||416); + } +} + +////// 在某个canvas上绘制一段文字 ////// +ui.prototype.fillText = function (map, text, x, y, style, font) { + if (core.isset(style)) { + core.setFillStyle(map, style); + } + if (core.isset(font)) { + core.setFont(map, font); + } + core.canvas[map].fillText(text, x, y); +} + +////// 在某个canvas上绘制一个矩形 ////// +ui.prototype.fillRect = function (map, x, y, width, height, style) { + if (core.isset(style)) { + core.setFillStyle(map, style); + } + core.canvas[map].fillRect(x, y, width, height); +} + +////// 在某个canvas上绘制一个矩形的边框 ////// +ui.prototype.strokeRect = function (map, x, y, width, height, style, lineWidth) { + if (core.isset(style)) { + core.setStrokeStyle(map, style); + } + if (core.isset(lineWidth)) { + core.setLineWidth(map, lineWidth); + } + core.canvas[map].strokeRect(x, y, width, height); +} + +////// 在某个canvas上绘制一条线 ////// +ui.prototype.drawLine = function (map, x1, y1, x2, y2, style, lineWidth) { + if (core.isset(style)) { + core.setStrokeStyle(map, style); + } + if (core.isset(lineWidth)) { + core.setLineWidth(map, lineWidth); + } + core.canvas[map].beginPath(); + core.canvas[map].moveTo(x1, y1); + core.canvas[map].lineTo(x2, y2); + core.canvas[map].closePath(); + core.canvas[map].stroke(); +} + +////// 设置某个canvas的文字字体 ////// +ui.prototype.setFont = function (map, font) { + core.canvas[map].font = font; +} + +////// 设置某个canvas的线宽度 ////// +ui.prototype.setLineWidth = function (map, lineWidth) { + if (map == 'all') { + for (var m in core.canvas) { + core.canvas[m].lineWidth = lineWidth; + } + } + core.canvas[map].lineWidth = lineWidth; +} + +////// 保存某个canvas状态 ////// +ui.prototype.saveCanvas = function (map) { + core.canvas[map].save(); +} + +////// 加载某个canvas状态 ////// +ui.prototype.loadCanvas = function (map) { + core.canvas[map].restore(); +} + +////// 设置某个canvas边框属性 ////// +ui.prototype.setStrokeStyle = function (map, style) { + if (map == 'all') { + for (var m in core.canvas) { + core.canvas[m].strokeStyle = style; + } + } + else { + core.canvas[map].strokeStyle = style; + } +} + +////// 设置某个canvas的alpha值 ////// +ui.prototype.setAlpha = function (map, alpha) { + if (map == 'all') { + for (var m in core.canvas) { + core.canvas[m].globalAlpha = alpha; + } + } + else core.canvas[map].globalAlpha = alpha; +} + +////// 设置某个canvas的透明度 ////// +ui.prototype.setOpacity = function (map, opacity) { + if (map == 'all') { + for (var m in core.canvas) { + core.canvas[m].canvas.style.opacity = opacity; + } + } + else core.canvas[map].canvas.style.opacity = opacity; +} + +////// 设置某个canvas的绘制属性(如颜色等) ////// +ui.prototype.setFillStyle = function (map, style) { + if (map == 'all') { + for (var m in core.canvas) { + core.canvas[m].fillStyle = style; + } + } + else { + core.canvas[map].fillStyle = style; + } +} + + + +///////////////// UI绘制 ////// 结束一切事件和绘制,关闭UI窗口,返回游戏进程 ////// ui.prototype.closePanel = function () { @@ -26,6 +158,110 @@ ui.prototype.closePanel = function () { core.status.event.interval = null; } +////// 左上角绘制一段提示 ////// +ui.prototype.drawTip = function (text, itemIcon) { + var textX, textY, width, height, hide = false, opacityVal = 0; + clearInterval(core.interval.tipAnimate); + core.setFont('data', "16px Arial"); + core.saveCanvas('data'); + core.setOpacity('data', 0); + core.canvas.data.textAlign = 'left'; + if (!core.isset(itemIcon)) { + textX = 16; + textY = 18; + width = textX + core.canvas.data.measureText(text).width + 16; + height = 42; + } + else { + textX = 44; + textY = 18; + width = textX + core.canvas.data.measureText(text).width + 8; + height = 42; + } + core.interval.tipAnimate = window.setInterval(function () { + if (hide) { + opacityVal -= 0.1; + } + else { + opacityVal += 0.1; + } + core.setOpacity('data', opacityVal); + core.clearMap('data', 5, 5, 400, height); + core.fillRect('data', 5, 5, width, height, '#000'); + if (core.isset(itemIcon)) { + core.canvas.data.drawImage(core.material.images.items, 0, itemIcon * 32, 32, 32, 10, 8, 32, 32); + } + core.fillText('data', text, textX + 5, textY + 15, '#fff'); + if (opacityVal > 0.6 || opacityVal < 0) { + if (hide) { + core.loadCanvas('data'); + core.clearMap('data', 5, 5, 400, height); + core.setOpacity('data', 1); + clearInterval(core.interval.tipAnimate); + return; + } + else { + if (!core.isset(core.timeout.getItemTipTimeout)) { + core.timeout.getItemTipTimeout = window.setTimeout(function () { + hide = true; + core.timeout.getItemTipTimeout = null; + }, 750); + } + opacityVal = 0.6; + core.setOpacity('data', opacityVal); + } + } + }, 30); +} + +////// 地图中间绘制一段文字 ////// +ui.prototype.drawText = function (contents, callback) { + if (core.isset(contents)) { + + // 合并 + if (core.isset(core.status.event)&&core.status.event.id=='action') { + core.insertAction(contents,null,null,callback); + return; + } + + if (typeof contents == 'string') { + contents = [{'content': contents}]; + } + else if (contents instanceof Object && core.isset(contents.content)) { + contents = [contents]; + } + else if (!(contents instanceof Array)) { + core.drawTip("出错了"); + console.log(contents); + return; + } + + core.status.event = {'id': 'text', 'data': {'list': contents, 'callback': callback}}; + core.lockControl(); + + // wait the hero to stop + core.stopAutomaticRoute(); + setTimeout(function() { + core.drawText(); + }, 30); + return; + } + + if (core.status.event.data.list.length==0) { + var callback = core.status.event.data.callback; + core.ui.closePanel(false); + if (core.isset(callback)) callback(); + return; + } + + var data=core.status.event.data.list.shift(); + if (typeof data == 'string') + core.ui.drawTextBox(data); + else + core.ui.drawTextBox(data.content, data.id); + // core.drawTextBox(content); +} + ////// 绘制一个对话框 ////// ui.prototype.drawTextBox = function(content) { diff --git a/libs/utils.js b/libs/utils.js new file mode 100644 index 00000000..5ad4a9de --- /dev/null +++ b/libs/utils.js @@ -0,0 +1,464 @@ +/* +utils.js 工具类 + + */ + +function utils() { + +} + +utils.prototype.init = function () { + +} + +////// 将文字中的${和}(表达式)进行替换 ////// +utils.prototype.replaceText = function (text) { + return text.replace(/\${([^}]+)}/g, function (word, value) { + return core.calValue(value); + }); +} + +////// 计算表达式的值 ////// +utils.prototype.calValue = function (value) { + value=value.replace(/status:([\w\d_]+)/g, "core.getStatus('$1')"); + value=value.replace(/item:([\w\d_]+)/g, "core.itemCount('$1')"); + value=value.replace(/flag:([\w\d_]+)/g, "core.getFlag('$1', false)"); + return eval(value); +} + +////// 字符串自动换行的分割 ////// +utils.prototype.splitLines = function(canvas, text, maxLength, font) { + if (core.isset(font)) core.setFont(canvas, font); + + var contents = []; + var last = 0; + for (var i=0;imaxLength) { + contents.push(text.substring(last, i)); + last=i; + } + } + } + contents.push(text.substring(last)); + return contents; +} + +////// 向某个数组前插入另一个数组或元素 ////// +utils.prototype.unshift = function (a,b) { + if (!(a instanceof Array) || !core.isset(b)) return; + if (b instanceof Array) { + core.clone(b).reverse().forEach(function (e) { + a.unshift(e); + }); + } + else a.unshift(b); + return a; +} + +////// 设置本地存储 ////// +utils.prototype.setLocalStorage = function(key, value) { + try { + localStorage.setItem(core.firstData.name + "_" + key, JSON.stringify(value)); + return true; + } + catch (e) { + console.log(e); + return false; + } +} + +////// 获得本地存储 ////// +utils.prototype.getLocalStorage = function(key, defaultValue) { + var value = localStorage.getItem(core.firstData.name+"_"+key); + if (core.isset(value)) return JSON.parse(value); + return defaultValue; +} + +////// 移除本地存储 ////// +utils.prototype.removeLocalStorage = function (key) { + localStorage.removeItem(core.firstData.name+"_"+key); +} + +////// 深拷贝一个对象 ////// +utils.prototype.clone = function (data) { + if (!core.isset(data)) return data; + // date + if (data instanceof Date) { + var copy=new Date(); + copy.setTime(data.getTime()); + return copy; + } + // array + if (data instanceof Array) { + var copy=[]; + // for (var i=0;i255) nowR=255; if (nowB>255) nowB=255; if (nowG>255) nowG=255; + return "#"+((1<<24)+(nowR<<16)+(nowG<<8)+nowB).toString(16).slice(1); +} + +////// 加密路线 ////// +utils.prototype.encodeRoute = function (route) { + var ans=""; + var lastMove = "", cnt=0; + + var items=Object.keys(core.material.items).sort(); + var shops=Object.keys(core.initStatus.shops).sort(); + route.forEach(function (t) { + if (t=='up' || t=='down' || t=='left' || t=='right') { + if (t!=lastMove && cnt>0) { + ans+=lastMove.substring(0,1).toUpperCase(); + if (cnt>1) ans+=cnt; + cnt=0; + } + lastMove=t; + cnt++; + } + else { + if (cnt>0) { + ans+=lastMove.substring(0,1).toUpperCase(); + if (cnt>1) ans+=cnt; + cnt=0; + } + if (t.indexOf('item:')==0) + ans+="I"+items.indexOf(t.substring(5)); + else if (t.indexOf('fly:')==0) + ans+="F"+core.floorIds.indexOf(t.substring(4)); + else if (t.indexOf('choices:')==0) + ans+="C"+t.substring(8); + else if (t.indexOf('shop:')==0) { + var sp=t.substring(5).split(":"); + ans+="S"+shops.indexOf(sp[0])+":"+sp[1]; + } + else if (t=='turn') + ans+='T'; + else if (t=='getNext') + ans+='G'; + else if (t.indexOf('input:')==0) + ans+="P"+t.substring(6); + else if (t=='no') + ans+='N'; + else if (t.indexOf('move:')==0) { + ans+="M"+t.substring(5); + } + } + }); + if (cnt>0) { + ans+=lastMove.substring(0,1).toUpperCase(); + if (cnt>1) ans+=cnt; + } + return ans; +} + +////// 解密路线 ////// +utils.prototype.decodeRoute = function (route) { + + if (!core.isset(route)) return route; + + var ans=[], index=0; + + var getNumber = function (noparse) { + var num=""; + while (index 1) { + clearInterval(showAnimate); + if (core.isset(callback)) { + callback(); + } + } + }, speed); +} + +////// 动画使某对象消失 ////// +utils.prototype.hide = function (obj, speed, callback) { + if (!core.isset(speed)) { + obj.style.display = 'none'; + return; + } + if (main.mode!='play'){ + obj.style.display = 'none'; + if (core.isset(callback)) {callback();} + return; + } + var opacityVal = 1; + var hideAnimate = window.setInterval(function () { + opacityVal -= 0.03; + obj.style.opacity = opacityVal; + if (opacityVal < 0) { + obj.style.display = 'none'; + clearInterval(hideAnimate); + if (core.isset(callback)) { + callback(); + } + } + }, speed); +} + +utils.prototype.http = function (type, url, formData, success, error, mimeType) { + var xhr = new XMLHttpRequest(); + xhr.open(type, url, true); + if (core.isset(mimeType)) + xhr.overrideMimeType(mimeType); + xhr.onload = function(e) { + if (xhr.status==200) { + if (core.isset(success)) { + success(xhr.response); + } + } + else { + if (core.isset(error)) + error("HTTP "+xhr.status); + } + }; + xhr.onabort = function () { + if (core.isset(error)) + error("Abort"); + } + xhr.ontimeout = function() { + if (core.isset(error)) + error("Timeout"); + } + xhr.onerror = function() { + if (core.isset(error)) + error("Error on Connection"); + } + if (core.isset(formData)) + xhr.send(formData); + else xhr.send(); +} diff --git a/main.js b/main.js index c2fb77c8..f0117813 100644 --- a/main.js +++ b/main.js @@ -47,7 +47,7 @@ function main() { }; this.mode = 'play'; this.loadList = [ - 'items', 'icons', 'maps', 'enemys', 'events', 'data', 'ui', 'core' + 'loader', 'control', 'utils', 'items', 'icons', 'maps', 'enemys', 'events', 'actions', 'data', 'ui', 'core' ]; this.pureData = [ "data","enemys","icons","maps","items","functions" @@ -142,14 +142,16 @@ main.prototype.init = function (mode) { }); main.loaderJs(function () { - var coreData = {}; + main.core = core; + for (i = 0; i < main.loadList.length; i++) { var name = main.loadList[i]; if (name === 'core') continue; - main[name].init(main.dom); - coreData[name] = main[name]; + main.core[name] = new (eval(name))(); } + main.loaderFloors(function() { + var coreData = {}; ["dom", "statusBar", "canvas", "images", "pngs", "animates", "bgms", "sounds", "floorIds", "floors"].forEach(function (t) { coreData[t] = main[t]; @@ -168,14 +170,9 @@ main.prototype.loaderJs = function (callback) { main.setMainTipsText('正在加载核心js文件...') for (var i = 0; i < main.loadList.length; i++) { main.loadMod(main.loadList[i], function (modName) { - instanceNum = 0; main.setMainTipsText(modName + '.js 加载完毕'); - for (var key in main.instance) { - instanceNum++; - } + instanceNum++; if (instanceNum === main.loadList.length) { - delete main.instance; - // main.dom.mainTips.style.display = 'none'; callback(); } }); diff --git a/project/functions.js b/project/functions.js index 376d35fe..50c3f9f5 100644 --- a/project/functions.js +++ b/project/functions.js @@ -88,9 +88,38 @@ functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = }, ////// 战斗结束后触发的事件 ////// "afterBattle" : function(enemyId,x,y,callback) { - + var enemy = core.material.enemys[enemyId]; + // 扣减体力值 + core.status.hero.hp -= core.enemys.getDamage(enemyId); + if (core.status.hero.hp<=0) { + core.status.hero.hp=0; + core.updateStatusBar(); + core.events.lose('battle'); + return; + } + // 获得金币和经验 + var money = enemy.money; + if (core.hasItem('coin')) money *= 2; + if (core.hasFlag('curse')) money=0; + core.status.hero.money += money; + var experience =enemy.experience; + if (core.hasFlag('curse')) experience=0; + core.status.hero.experience += experience; + var hint = "打败 " + enemy.name; + if (core.flags.enableMoney) + hint += ",金币+" + money; + if (core.flags.enableExperience) + hint += ",经验+" + experience; + core.drawTip(hint); + + // 删除该块 + if (core.isset(x) && core.isset(y)) { + core.removeBlock(x, y); + core.canvas.event.clearRect(32 * x, 32 * y, 32, 32); + } + // 毒衰咒的处理 var special = enemy.special; // 中毒