diff --git a/README.md b/README.md index 9fdc6774..03a25ad8 100644 --- a/README.md +++ b/README.md @@ -5,8 +5,8 @@ HTML5 canvas制作的魔塔样板,支持全平台游戏! **即使完全不会编程的用户,按照模板和说明文档也能很快做出一个魔塔游戏!** -* [Demo / 样板效果](http://ckcz123.com/games/template/) -* [Docs / 使用文档说明](http://ckcz123.github.io/mota-js) +* [Demo / 样板效果](https://ckcz123.com/games/template/) +* [Docs / 使用文档说明](https://ckcz123.github.io/mota-js) ![样板](./docs/img/sample0.png) diff --git a/libs/core.js b/libs/core.js index 42f79220..0ea2ebdf 100644 --- a/libs/core.js +++ b/libs/core.js @@ -21,7 +21,8 @@ function core() { 'events': {} } this.timeout = { - 'getItemTipTimeout': null + 'getItemTipTimeout': null, + 'turnHeroTimeout': null, } this.interval = { 'twoAnimate': null, @@ -56,6 +57,7 @@ function core() { 'floorId': null, 'thisMap': null, 'maps': null, + 'checkBlock': [], // 显伤伤害 // 勇士状态;自动寻路相关 'heroMoving': false, @@ -106,7 +108,6 @@ core.prototype.init = function (dom, statusBar, canvas, images, sounds, floorIds core[key] = coreData[key]; } core.flags = core.clone(core.data.flags); - core.flags.battleAnimate = core.getLocalStorage('battleAnimate', core.flags.battleAnimate); core.values = core.clone(core.data.values); core.firstData = core.data.getFirstData(); core.initStatus.shops = core.firstData.shops; @@ -296,7 +297,7 @@ core.prototype.clearStatus = function() { core.resize(main.dom.body.clientWidth, main.dom.body.clientHeight); } -core.prototype.resetStatus = function(hero, hard, floorId, maps) { +core.prototype.resetStatus = function(hero, hard, floorId, flags, maps) { // 停止各个Timeout和Interval for (var i in core.interval) { @@ -314,6 +315,8 @@ core.prototype.resetStatus = function(hero, hard, floorId, maps) { // 初始化人物属性 core.status.hero = core.clone(hero); core.status.hard = hard; + if (core.isset(flags)) + core.flags = core.clone(flags); // 保存页面 core.status.savePage = core.getLocalStorage('savePage', 0); @@ -324,7 +327,7 @@ core.prototype.resetStatus = function(hero, hard, floorId, maps) { core.prototype.startGame = function (hard, callback) { console.log('开始游戏'); - core.resetStatus(core.firstData.hero, hard, core.firstData.floorId, core.initStatus.maps); + core.resetStatus(core.firstData.hero, hard, core.firstData.floorId, core.flags, core.initStatus.maps); core.changeFloor(core.status.floorId, null, core.firstData.hero.loc, null, function() { core.setHeroMoveTriggerInterval(); @@ -501,6 +504,10 @@ core.prototype.keyUp = function(keyCode) { if (core.status.heroStop) core.ui.drawQuickShop(true); break; + case 32: // SPACE + if (!core.status.lockControl && core.status.heroStop) + core.getNextItem(); + break; case 37: // UP break; case 38: // DOWN @@ -626,7 +633,7 @@ core.prototype.getClickLoc = function (x, y) { } core.prototype.onclick = function (x, y, stepPostfix) { - console.log("Click: (" + x + "," + y + ")"); + // console.log("Click: (" + x + "," + y + ")"); // 非游戏屏幕内 if (x<0 || y<0 || x>12 || y>12) return; @@ -649,6 +656,12 @@ core.prototype.onclick = function (x, y, stepPostfix) { return; } + // 开关 + if (core.status.event.id == 'switchs') { + core.events.clickSwitchs(x,y); + return; + } + // 设置 if (core.status.event.id == 'settings') { core.events.clickSettings(x,y); @@ -745,14 +758,14 @@ core.prototype.onmousewheel = function (direct) { } // 怪物手册 - if (core.status.event.id == 'book') { + if (core.status.lockControl && core.status.event.id == 'book') { if (direct==1) core.ui.drawEnemyBook(core.status.event.data - 1); if (direct==-1) core.ui.drawEnemyBook(core.status.event.data + 1); return; } // 存读档 - if (core.status.event.id == 'save' || core.status.event.id == 'load') { + if (core.status.lockControl && (core.status.event.id == 'save' || core.status.event.id == 'load')) { if (direct==1) core.ui.drawSLPanel(core.status.event.data - 1); if (direct==-1) core.ui.drawSLPanel(core.status.event.data + 1); return; @@ -807,7 +820,18 @@ core.prototype.setAutomaticRoute = function (destX, destY, stepPostfix) { return; } if (destX == core.status.hero.loc.x && destY == core.status.hero.loc.y && stepPostfix.length==0) { - core.turnHero(); + 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; @@ -960,14 +984,16 @@ core.prototype.automaticRoute = function (destX, destY) { if ( (scan[direction].x + scan[nextArrow].x) == 0 && (scan[direction].y + scan[nextArrow].y) == 0 ) continue; } // 绕过亮灯(因为只有一次通行机会很宝贵) - if(nextId == "light") deepAdd=50; + if(nextId == "light") deepAdd=100; // 绕过路障 - if (nextId.substring(nextId.length-3)=="Net") 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 == 'checkBlock') deepAdd=200; + // if (nextBlock.block.event.trigger == 'checkBlock') deepAdd=200; } + if (core.status.checkBlock[nid]>0) + deepAdd = core.status.checkBlock[nid]; if (nx == destX && ny == destY) { route[nid] = direction; @@ -1273,6 +1299,24 @@ core.prototype.moveOneStep = function() { } core.updateStatusBar(); } + // 检查领域、夹击事件 + var x=core.getHeroLoc('x'), y=core.getHeroLoc('y'); + if (core.status.checkBlock[13*x+y]>0) { + core.status.hero.hp -= core.status.checkBlock[13*x+y]; + if (core.hasBetweenAttack(x,y)) { + core.drawTip('受到夹击,生命变成一半'); + } + else if (core.hasZone(x,y)) { + core.drawTip('受到领域伤害'+core.status.checkBlock[13*x+y]+'点'); + } + if (core.status.hero.hp<=0) { + core.status.hero.hp=0; + core.updateStatusBar(); + core.events.lose('zone'); + return; + } + core.updateStatusBar(); + } } core.prototype.waitHeroToStop = function(callback) { @@ -1415,6 +1459,7 @@ core.prototype.afterBattle = function(id, x, y, callback) { hint += ",经验+" + core.material.enemys[id].experience; core.drawTip(hint); + core.updateCheckBlockMap(); // 打完怪物,触发事件 core.events.afterBattle(id,x,y,callback); @@ -1491,6 +1536,8 @@ core.prototype.changeFloor = function (floorId, stair, heroLoc, time, callback) core.setHeroLoc('x', heroLoc.x); core.setHeroLoc('y', heroLoc.y); core.drawHero(core.getHeroLoc('direction'), core.getHeroLoc('x'), core.getHeroLoc('y'), 'stop'); + core.updateCheckBlockMap(); + core.updateCheckBlock(); core.updateFg(); }, 15) }); @@ -1992,6 +2039,7 @@ core.prototype.addBlock = function(x,y,floodId) { // 本身是禁用事件,启用之 if (core.isset(block.enable) && !block.enable) { block.enable = true; + core.updateCheckBlockMap(); // 在本层,添加动画 if (floodId == core.status.floorId && core.isset(block.event)) { blockIcon = core.material.icons[block.event.cls][block.event.id]; @@ -2028,24 +2076,22 @@ core.prototype.removeBlockById = function (index, floorId) { var blocks = core.status.maps[floorId].blocks; var x=blocks[index].x, y=blocks[index].y; - // 检查该点是否是checkBlock - if (core.floors[floorId].checkBlock.indexOf(x+","+y)>=0) { - blocks[index] = {'x': x, 'y': y, 'event': {'cls': 'terrains', 'id': 'ground', 'noPass': false, 'trigger': 'checkBlock'}}; - return; - } - // 检查该点是否存在事件 var event = core.floors[floorId].events[x+","+y]; if (!core.isset(event)) event = core.floors[floorId].changeFloor[x+","+y]; + var shouldUpdateBlockMap = blocks[index].event.cls == 'enemys'; // 不存在事件,直接删除 if (!core.isset(event)) { blocks.splice(index,1); + if (shouldUpdateBlockMap) + core.updateCheckBlockMap(); return; } - blocks[index].enable = false; + if (shouldUpdateBlockMap) + core.updateCheckBlockMap(); } core.prototype.removeBlockByIds = function (floorId, ids) { @@ -2144,6 +2190,101 @@ core.prototype.drawBoxAnimate = function (background) { } } +core.prototype.updateCheckBlockMap = function() { + // 更新领域、夹击地图 + core.status.checkBlockMap = []; + var blocks = core.status.thisMap.blocks; + for (var n=0;n12 || ny<0 || ny>12) return; + if (core.status.checkBlockMap[13*nx+ny]%1000000>0) { + damage += core.status.checkBlockMap[13*nx+ny] % 1000000; + } + }) + + var leftValue = core.status.hero.hp - damage; + if (leftValue>=0) { + // 夹击 + if (x>0 && x<12) { + var id1=parseInt(core.status.checkBlockMap[13*(x-1)+y]/1000000), + id2=parseInt(core.status.checkBlockMap[13*(x+1)+y]/1000000); + if (id1>0 && id1==id2) + damage += parseInt(leftValue/2); + } + else if (y>0 && y<12) { + var id1=parseInt(core.status.checkBlockMap[13*x+y-1]/1000000), + id2=parseInt(core.status.checkBlockMap[13*x+y+1]/1000000); + if (id1>0 && id1==id2) + damage += parseInt(leftValue/2); + } + } + } + core.status.checkBlock[13*x+y] = damage; + } + } +} + +core.prototype.hasZone = function (x,y) { + if (!core.isset(core.status.checkBlockMap)) core.updateCheckBlockMap(); + var isZone = false; + // 领域 + [[-1,0],[0,-1],[1,0],[0,1]].forEach(function (dir) { + var nx = x+dir[0], ny = y+dir[1]; + if (nx<0 || nx>12 || ny<0 || ny>12) return; + if (core.status.checkBlockMap[13*nx+ny]%1000000>0) { + isZone = true; + } + }) + return isZone; +} + +core.prototype.hasBetweenAttack = function(x,y) { + if (!core.isset(core.status.checkBlockMap)) core.updateCheckBlockMap(); + // 夹击 + if (x>0 && x<12) { + var id1=parseInt(core.status.checkBlockMap[13*(x-1)+y]/1000000), + id2=parseInt(core.status.checkBlockMap[13*(x+1)+y]/1000000); + if (id1>0 && id1==id2) + return true; + } + if (y>0 && y<12) { + var id1=parseInt(core.status.checkBlockMap[13*x+y-1]/1000000), + id2=parseInt(core.status.checkBlockMap[13*x+y+1]/1000000); + if (id1>0 && id1==id2) + return true; + } +} + core.prototype.setFg = function(color, time, callback) { time = time || 750; core.setOpacity('fg', 1); @@ -2254,32 +2395,54 @@ core.prototype.updateFg = function () { if (!core.hasItem('book')) return; core.setFont('fg', "bold 11px Arial"); var hero_hp = core.status.hero.hp; - 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' && mapBlocks[b].event.trigger=='battle' + 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' && mapBlocks[b].event.trigger == 'battle' && !(core.isset(mapBlocks[b].enable) && !mapBlocks[b].enable)) { - var id = mapBlocks[b].event.id; + 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'; + 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"; + 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', '#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); + 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[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); + } + } } } } @@ -2341,6 +2504,16 @@ core.prototype.addItem = function (itemId, itemNum) { core.status.hero.items[itemCls][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.prototype.getItem = function (itemId, itemNum, itemX, itemY, callback) { // core.getItemAnimate(itemId, itemNum, itemX, itemY); core.playSound('item', 'ogg'); @@ -2368,6 +2541,7 @@ core.prototype.drawTip = function (text, itemIcon) { 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; @@ -2845,6 +3019,7 @@ core.prototype.saveData = function(dataId) { 'hard': core.status.hard, 'maps': core.maps.save(core.status.maps), 'shops': {}, + 'flags': core.flags, 'version': core.firstData.version, "time": new Date().getTime() }; @@ -2862,7 +3037,7 @@ core.prototype.saveData = function(dataId) { core.prototype.loadData = function (data, callback) { - core.resetStatus(data.hero, data.hard, data.floorId, core.maps.load(data.maps)); + core.resetStatus(data.hero, data.hard, data.floorId, data.flags, core.maps.load(data.maps)); // load shop times for (var shop in core.status.shops) { @@ -3038,7 +3213,6 @@ core.prototype.updateStatusBar = function () { core.statusBar.weak.innerHTML = core.hasFlag('weak')?"衰":""; core.statusBar.curse.innerHTML = core.hasFlag('curse')?"咒":""; } - core.statusBar.hard.innerHTML = core.status.hard; if (core.hasItem('book')) { @@ -3051,6 +3225,7 @@ core.prototype.updateStatusBar = function () { } else { core.statusBar.image.fly.style.opacity = 0.3; } + core.updateCheckBlock(); core.updateFg(); } diff --git a/libs/data.js b/libs/data.js index f298e063..df1f02d0 100644 --- a/libs/data.js +++ b/libs/data.js @@ -111,12 +111,12 @@ data.prototype.init = function() { 'breakArmor': 0.9, // 破甲的比例(战斗前,怪物附加角色防御的x%作为伤害) 'counterAttack': 0.1, // 反击的比例(战斗时,怪物每回合附加角色攻击的x%作为伤害,无视角色防御) 'purify': 3, // 净化的比例(战斗前,怪物附加勇士魔防的x倍作为伤害) + 'hatred': 2, // 仇恨属性中,每杀死一个怪物获得的仇恨值 /****** 系统相关 ******/ 'animateSpeed': 500, // 动画时间 } // 系统FLAG,在游戏运行中中请不要修改它。 this.flags = { - /****** 角色状态相关 ******/ "enableMDef": true, // 是否涉及勇士的魔防值;如果此项为false,则状态栏不会显示勇士的魔防值 "enableExperience": true, // 是否涉及经验值;如果此项为false,则状态栏和怪物手册均将不会显示经验值 @@ -125,10 +125,12 @@ data.prototype.init = function() { "flyNearStair": true, // 是否需要在楼梯边使用传送器 "pickaxeFourDirections": true, // 使用破墙镐是否四个方向都破坏;如果false则只破坏面前的墙壁 "bigKeyIsBox": false, // 如果此项为true,则视为钥匙盒,红黄蓝钥匙+1;若为false,则视为大黄门钥匙 - /****** 系统相关 ******/ "startDirectly": false, // 点击“开始游戏”后是否立刻开始游戏而不显示难度选择界面 - "battleAnimate": true, // 是否默认显示战斗动画;用户可以手动在菜单栏中关闭 + "battleAnimate": true, // 是否默认显示战斗动画;用户可以手动在菜单栏中开关 + "displayEnemyDamage": true, // 是否地图怪物显伤;用户可以手动在菜单栏中开关 + "displayExtraDamage": false, // 是否地图高级显伤(领域、夹击等);用户可以手动在菜单栏中开关 + "enableGentleClick": true, // 是否允许轻触(获得面前物品) "portalWithoutTrigger": true, // 经过楼梯、传送门时是否能“穿透”。穿透的意思是,自动寻路得到的的路径中间经过了楼梯,行走时是否触发楼层转换事件 "potionWhileRouting": false, // 寻路算法是否经过血瓶;如果该项为false,则寻路算法会自动尽量绕过血瓶 } diff --git a/libs/enemys.js b/libs/enemys.js index 04611d30..62401bab 100644 --- a/libs/enemys.js +++ b/libs/enemys.js @@ -99,6 +99,7 @@ enemys.prototype.getSpecialText = function (enemyId) { if (this.hasSpecial(special, 14)) text.push("诅咒"); if (this.hasSpecial(special, 15)) text.push("领域"); if (this.hasSpecial(special, 16)) text.push("夹击"); + if (this.hasSpecial(special, 17)) text.push("仇恨"); return text.join(" "); } @@ -118,6 +119,9 @@ enemys.prototype.getExtraDamage = function (monster) { extra_damage = core.status.hero.hp * monster.value; extra_damage = parseInt(extra_damage); } + if (this.hasSpecial(monster.special, 17)) { // 仇恨 + extra_damage += core.getFlag('hatred', 0); + } return extra_damage; } diff --git a/libs/events.js b/libs/events.js index c90a3cfa..296baa1d 100644 --- a/libs/events.js +++ b/libs/events.js @@ -34,11 +34,6 @@ events.prototype.init = function () { if (core.isset(callback)) callback(); }, - "checkBlock": function (data, core, callback) { - core.events.checkBlock(data.x, data.y); - if (core.isset(callback)) - callback(); - }, "changeLight": function (data, core, callback) { core.events.changeLight(data.x, data.y); if (core.isset(callback)) @@ -112,50 +107,6 @@ events.prototype.lose = function(reason) { }) } - -////// 检查领域、夹击事件 ////// -events.prototype.checkBlock = function (x,y) { - var damage = 0; - // 获得四个方向的怪物 - var directions = [[0,-1],[-1,0],[0,1],[1,0]]; // 上,左,下,右 - var enemys = [null,null,null,null]; - for (var i in directions) { - var block = core.getBlock(x+directions[i][0], y+directions[i][1]); - if (block==null) continue; - // 是怪物 - if (block.block.event.cls=='enemys') - enemys[i]=core.material.enemys[block.block.event.id]; - } - - // 领域 - for (var i in enemys) { - if (enemys[i]!=null && core.enemys.hasSpecial(enemys[i].special, 15)) { - damage+=enemys[i].value; - } - } - if (damage>0) - core.drawTip('受到领域伤害'+damage+'点'); - core.status.hero.hp-=damage; - if (core.status.hero.hp<=0) { - core.status.hero.hp=0; - core.updateStatusBar(); - core.events.lose('zone'); - return; - } - - // 夹击 - var has=false; - if (enemys[0]!=null && enemys[2]!=null && enemys[0].id==enemys[2].id && core.enemys.hasSpecial(enemys[0].special, 16)) - has=true; - if (enemys[1]!=null && enemys[3]!=null && enemys[1].id==enemys[3].id && core.enemys.hasSpecial(enemys[1].special, 16)) - has=true; - if (has && core.status.hero.hp>1) { // 1血夹击不死 - core.status.hero.hp = parseInt(core.status.hero.hp/2); - core.drawTip('受到夹击,生命变成一半'); - } - core.updateStatusBar(); -} - ////// 转换楼层结束的事件 ////// events.prototype.afterChangeFloor = function (floorId) { if (!core.hasFlag("visited_"+floorId)) { @@ -451,8 +402,10 @@ events.prototype.disableQuickShop = function (shopId) { } ////// 降低难度 ////// -/* + events.prototype.decreaseHard = function() { + core.drawTip("本塔不支持降低难度!"); + /* if (core.status.hard == 0) { core.drawTip("当前已是难度0,不能再降低难度了"); return; @@ -470,8 +423,8 @@ events.prototype.decreaseHard = function() { }, function () { core.ui.drawSettings(false); }); + */ } -*/ ////// 能否使用快捷商店 ////// events.prototype.canUseQuickShop = function(shopIndex) { @@ -506,20 +459,24 @@ events.prototype.afterBattle = function(enemyId,x,y,callback) { // 中毒 if (core.enemys.hasSpecial(special, 12) && !core.hasFlag('poison')) { core.setFlag('poison', true); - core.updateStatusBar(); } // 衰弱 if (core.enemys.hasSpecial(special, 13) && !core.hasFlag('weak')) { core.setFlag('weak', true); core.status.hero.atk-=core.values.weakValue; core.status.hero.def-=core.values.weakValue; - core.updateStatusBar(); } // 诅咒 if (core.enemys.hasSpecial(special, 14) && !core.hasFlag('curse')) { core.setFlag('curse', true); - core.updateStatusBar(); } + // 仇恨属性:减半 + if (core.enemys.hasSpecial(special, 17)) { + core.setFlag('hatred', parseInt(core.getFlag('hatred', 0)/2)); + } + // 增加仇恨值 + core.setFlag('hatred', core.getFlag('hatred',0)+core.values.hatred); + core.updateStatusBar(); // 如果已有事件正在处理中 if (core.status.lockControl) { @@ -604,11 +561,11 @@ events.prototype.changeLight = function(x, y) { core.canvas.event.clearRect(x * 32, y * 32, 32, 32); var blockIcon = core.material.icons[block.event.cls][block.event.id]; core.canvas.event.drawImage(core.material.images[block.event.cls], 0, blockIcon * 32, 32, 32, block.x * 32, block.y * 32, 32, 32); - this.afterChangeLight(); + this.afterChangeLight(x,y); } // 改变灯后的事件 -events.prototype.afterChangeLight = function() { +events.prototype.afterChangeLight = function(x,y) { } @@ -822,21 +779,48 @@ events.prototype.clickSL = function(x,y) { } } -// 菜单栏 -events.prototype.clickSettings = function (x,y) { +events.prototype.clickSwitchs = function (x,y) { if (x<5 || x>7) return; - if (y == 3) { + if (y==4) { if (core.musicStatus.isIOS) { core.drawTip("iOS设备不支持播放音乐"); return; } core.changeSoundStatus(); + core.ui.drawSwitchs(); + } + if (y==5) { + core.flags.battleAnimate=!core.flags.battleAnimate; + core.ui.drawSwitchs(); + } + if (y==6) { + core.flags.displayEnemyDamage=!core.flags.displayEnemyDamage; + core.updateFg(); + core.ui.drawSwitchs(); + } + if (y==7) { + core.flags.displayExtraDamage=!core.flags.displayExtraDamage; + core.updateFg(); + core.ui.drawSwitchs(); + } + if (y==8) { core.ui.drawSettings(false); } +} + +// 菜单栏 +events.prototype.clickSettings = function (x,y) { + if (x<5 || x>7) return; + if (y == 3) { + core.ui.drawSwitchs(); + } if (y==4) { + /* core.flags.battleAnimate=!core.flags.battleAnimate; core.setLocalStorage('battleAnimate', core.flags.battleAnimate); core.ui.drawSettings(false); + */ + this.decreaseHard(); } if (y == 5) core.ui.drawQuickShop(); // if (y == 5) this.decreaseHard(); diff --git a/libs/floors/MT0.js b/libs/floors/MT0.js index 9d66ec6b..32000498 100644 --- a/libs/floors/MT0.js +++ b/libs/floors/MT0.js @@ -27,14 +27,6 @@ main.floors.MT0 = { }, "afterOpenDoor": { // 开完门后可能触发的事件列表 - }, - "checkBlock": [ - /****** 领域、夹击检查事件 ******/ - // 所有可能的领域、夹击点均需要在这里给出,否则将不会触发检查事件 - // 另外,如果该点已经存在events事件或changeFloor事件(即上面有相同点位置定义),则会被覆盖 - // afterBattle, afterGetItem, afterOpenDoor则不受影响(仍能正常工作)。 - // 所以 |****** 强烈要求可能的夹击、领域点不要存在自定义事件!! ******| - ] - + } } diff --git a/libs/floors/sample0.js b/libs/floors/sample0.js index e3952451..266fb844 100644 --- a/libs/floors/sample0.js +++ b/libs/floors/sample0.js @@ -108,15 +108,7 @@ main.floors.sample0 = { }, "afterOpenDoor": { // 开完门后可能触发的事件列表 "11,12": ["你开了一个绿门,触发了一个afterOpenDoor事件"] - }, - "checkBlock": [ - /****** 领域、夹击检查事件 ******/ - // 所有可能的领域、夹击点均需要在这里给出,否则将不会触发检查事件 - // 另外,如果该点已经存在events事件或changeFloor事件(即上面有相同点位置定义),则会被覆盖 - // afterBattle, afterGetItem, afterOpenDoor则不受影响(仍能正常工作)。 - // 所以 |****** 强烈要求可能的夹击、领域点不要存在自定义事件!! ******| - "1,0", "3,0", "0,1", "2,1", "4,1", "1,2", "3,2" - ] + } } diff --git a/libs/floors/sample1.js b/libs/floors/sample1.js index 74cfca5f..c3685f07 100644 --- a/libs/floors/sample1.js +++ b/libs/floors/sample1.js @@ -13,7 +13,7 @@ main.floors.sample1 = { [2, 2, 2, 2, 121, 2, 2, 2, 0, 0, 229, 0, 0], [43, 33, 44, 1, 0, 0, 0, 2, 165, 161, 0, 163, 165], [21, 22, 21, 1, 0, 0, 0, 2, 166, 165, 0, 165, 166], - [1, 245, 1, 1, 0, 87, 0, 2, 2, 2, 85, 2, 2], + [1, 245, 1, 1, 219, 87, 0, 2, 2, 2, 85, 2, 2], [0, 246, 0, 1, 0, 0, 0, 2, 2, 221, 0, 221, 2], [246, 0, 246, 1, 0, 0, 0, 121, 85, 0, 0, 0, 2], [1, 246, 1, 1, 0, 2, 2, 2, 2, 2, 2, 2, 2], @@ -299,14 +299,6 @@ main.floors.sample1 = { }, "afterOpenDoor": { // 开完门后可能触发的事件列表 - }, - "checkBlock": [ - /****** 领域、夹击检查事件 ******/ - // 所有可能的领域、夹击点均需要在这里给出,否则将不会触发检查事件 - // 另外,如果该点已经存在events事件或changeFloor事件(即上面有相同点位置定义),则会被覆盖 - // afterBattle, afterGetItem, afterOpenDoor则不受影响(仍能正常工作)。 - // 所以 |****** 强烈要求可能的夹击、领域点不要存在自定义事件!! ******| - ] - + } } diff --git a/libs/floors/sample2.js b/libs/floors/sample2.js index b0bc470d..9dfe71b5 100644 --- a/libs/floors/sample2.js +++ b/libs/floors/sample2.js @@ -365,14 +365,6 @@ main.floors.sample2 = { }, "afterOpenDoor": { // 开完门后可能触发的事件列表 - }, - "checkBlock": [ - /****** 领域、夹击检查事件 ******/ - // 所有可能的领域、夹击点均需要在这里给出,否则将不会触发检查事件 - // 另外,如果该点已经存在events事件或changeFloor事件(即上面有相同点位置定义),则会被覆盖 - // afterBattle, afterGetItem, afterOpenDoor则不受影响(仍能正常工作)。 - // 所以 |****** 强烈要求可能的夹击、领域点不要存在自定义事件!! ******| - ] - + } } diff --git a/libs/maps.js b/libs/maps.js index d10c21ee..27c2efc3 100644 --- a/libs/maps.js +++ b/libs/maps.js @@ -36,8 +36,6 @@ maps.prototype.loadFloor = function (floorId, map) { } this.addEvent(block,j,i,floor.events[j+","+i]) this.addChangeFloor(block,j,i,floor.changeFloor[j+","+i]); - if (floor.checkBlock.indexOf(j+","+i)>=0) - this.addEvent(block,j,i,{"trigger":"checkBlock"}); if (core.isset(block.event)) blocks.push(block); } } diff --git a/libs/ui.js b/libs/ui.js index 71c7484c..3d238f6f 100644 --- a/libs/ui.js +++ b/libs/ui.js @@ -302,6 +302,30 @@ ui.prototype.drawConfirmBox = function (text, yesCallback, noCallback) { core.fillText('ui', "取消", 208 + 38, top + bottom - 35); } +////// 绘制开关界面 ////// +ui.prototype.drawSwitchs = function() { + // 背景音乐、背景音效、战斗动画、怪物显伤、领域显伤、返回 + + core.status.event.id = 'switchs'; + + var background = core.canvas.ui.createPattern(core.material.ground, "repeat"); + core.clearMap('ui', 0, 0, 416, 416); + core.setAlpha('ui', 1); + core.setFillStyle('ui', background); + var left = 97, top = 64 + 32, right = 416 - 2 * left, bottom = 416 - 2 * top; + core.fillRect('ui', left, top, right, bottom, background); + core.strokeRect('ui', left - 1, top - 1, right + 1, bottom + 1, '#FFFFFF', 2); + + core.canvas.ui.textAlign = "center"; + core.fillText('ui', "背景音乐: " + (core.musicStatus.soundStatus ? "[ON]" : "[OFF]"), 208, top + 56, "#FFFFFF", "bold 17px Verdana"); + // core.fillText('ui', "背景音效" + (core.musicStatus.soundStatus ? "[ON]" : "[OFF]"), 208, top + 88, "#FFFFFF", "bold 17px Verdana") + core.fillText('ui', "战斗动画: " + (core.flags.battleAnimate ? "[ON]" : "[OFF]"), 208, top + 88, "#FFFFFF", "bold 17px Verdana") + core.fillText('ui', "怪物显伤: " + (core.flags.displayEnemyDamage ? "[ON]" : "[OFF]"), 208, top + 120, "#FFFFFF", "bold 17px Verdana") + core.fillText('ui', "领域显伤: " + (core.flags.displayExtraDamage ? "[ON]" : "[OFF]"), 208, top + 152, "#FFFFFF", "bold 17px Verdana") + + core.fillText('ui', "返回上级菜单", 208, top + 184, "#FFFFFF", "bold 17px Verdana"); +} + /** * 绘制菜单栏 * @param need @@ -319,8 +343,8 @@ ui.prototype.drawSettings = function (need) { core.strokeRect('ui', left - 1, top - 1, right + 1, bottom + 1, '#FFFFFF', 2); core.canvas.ui.textAlign = "center"; - core.fillText('ui', "音乐: " + (core.musicStatus.soundStatus ? "[ON]" : "[OFF]"), 208, top + 56, "#FFFFFF", "bold 17px Verdana"); - core.fillText('ui', '战斗过程: ' +(core.flags.battleAnimate?'[ON]':'[OFF]'), 208, top + 88, "#FFFFFF", "bold 17px Verdana") + core.fillText('ui', "系统设置", 208, top + 56, "#FFFFFF", "bold 17px Verdana"); + core.fillText('ui', "降低难度", 208, top + 88, "#FFFFFF", "bold 17px Verdana") core.fillText('ui', "快捷商店", 208, top + 120, "#FFFFFF", "bold 17px Verdana"); core.fillText('ui', "同步存档", 208, top + 152, "#FFFFFF", "bold 17px Verdana"); // core.fillText('ui', "清空存档", 208, top + 152, "#FFFFFF", "bold 17px Verdana"); @@ -359,7 +383,6 @@ ui.prototype.drawQuickShop = function (need) { } core.fillText('ui', "返回游戏", 208, top + bottom - 40); - } ui.prototype.drawBattleAnimate = function(monsterId, callback) { @@ -395,10 +418,15 @@ ui.prototype.drawBattleAnimate = function(monsterId, callback) { if (core.enemys.hasSpecial(mon_special, 6)) turns=5; - // 初始伤害(破甲、净化) + // 初始伤害 var initDamage = 0; if (core.enemys.hasSpecial(mon_special, 7)) initDamage+=parseInt(core.values.breakArmor * hero_def); - if (core.enemys.hasSpecial(mon_special, 9)) initDamage=parseInt(core.values.purify * hero_mdef); + if (core.enemys.hasSpecial(mon_special, 9)) initDamage+=parseInt(core.values.purify * hero_mdef); + if (core.enemys.hasSpecial(mon_special, 11)) { // 吸血 + var extraDamage = monster.value * hero_hp; + initDamage+=parseInt(extraDamage); + } + if (core.enemys.hasSpecial(mon_special, 17)) initDamage+=core.getFlag('hatred', 0); hero_mdef-=initDamage; if (hero_mdef<0) { hero_hp+=hero_mdef; @@ -425,6 +453,7 @@ ui.prototype.drawBattleAnimate = function(monsterId, callback) { core.fillRect('ui', left, top, right, bottom, '#000000'); core.setAlpha('ui', 1); core.strokeRect('ui', left - 1, top - 1, right + 1, bottom + 1, '#FFFFFF', 2); + core.clearMap('data',0,0,416,416); core.setAlpha('data', 1); core.setOpacity('data', 1); core.status.boxAnimateObjs = []; diff --git a/更新内容.txt b/更新内容.txt index 204a5f44..24206cd5 100644 --- a/更新内容.txt +++ b/更新内容.txt @@ -2,7 +2,8 @@ 新增:可视化地图编辑工具 新增:便捷P图工具 √ 新增:支持Autotile √ -新增:怪物支持多属性 √ +新增:怪物支持多属性,添加仇恨属性 √ +移除checkBlock,现在对领域和夹击无需指定坐标了 √ 新增:单向箭头、感叹号 √ 新增:勇士支持移动;其他事件支持移动 √ 快捷道具使用:1破2炸3飞;读档改为D键 √