领域夹击处理机制更新

This commit is contained in:
oc 2017-12-20 16:48:11 +08:00
parent c8be88c8a0
commit 91b19477f8
12 changed files with 310 additions and 149 deletions

View File

@ -5,8 +5,8 @@
HTML5 canvas制作的魔塔样板支持全平台游戏 HTML5 canvas制作的魔塔样板支持全平台游戏
**即使完全不会编程的用户,按照模板和说明文档也能很快做出一个魔塔游戏!** **即使完全不会编程的用户,按照模板和说明文档也能很快做出一个魔塔游戏!**
* [Demo / 样板效果](http://ckcz123.com/games/template/) * [Demo / 样板效果](https://ckcz123.com/games/template/)
* [Docs / 使用文档说明](http://ckcz123.github.io/mota-js) * [Docs / 使用文档说明](https://ckcz123.github.io/mota-js)
![样板](./docs/img/sample0.png) ![样板](./docs/img/sample0.png)

View File

@ -21,7 +21,8 @@ function core() {
'events': {} 'events': {}
} }
this.timeout = { this.timeout = {
'getItemTipTimeout': null 'getItemTipTimeout': null,
'turnHeroTimeout': null,
} }
this.interval = { this.interval = {
'twoAnimate': null, 'twoAnimate': null,
@ -56,6 +57,7 @@ function core() {
'floorId': null, 'floorId': null,
'thisMap': null, 'thisMap': null,
'maps': null, 'maps': null,
'checkBlock': [], // 显伤伤害
// 勇士状态;自动寻路相关 // 勇士状态;自动寻路相关
'heroMoving': false, 'heroMoving': false,
@ -106,7 +108,6 @@ core.prototype.init = function (dom, statusBar, canvas, images, sounds, floorIds
core[key] = coreData[key]; core[key] = coreData[key];
} }
core.flags = core.clone(core.data.flags); core.flags = core.clone(core.data.flags);
core.flags.battleAnimate = core.getLocalStorage('battleAnimate', core.flags.battleAnimate);
core.values = core.clone(core.data.values); core.values = core.clone(core.data.values);
core.firstData = core.data.getFirstData(); core.firstData = core.data.getFirstData();
core.initStatus.shops = core.firstData.shops; 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.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 // 停止各个Timeout和Interval
for (var i in core.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.hero = core.clone(hero);
core.status.hard = hard; core.status.hard = hard;
if (core.isset(flags))
core.flags = core.clone(flags);
// 保存页面 // 保存页面
core.status.savePage = core.getLocalStorage('savePage', 0); 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) { core.prototype.startGame = function (hard, callback) {
console.log('开始游戏'); 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.changeFloor(core.status.floorId, null, core.firstData.hero.loc, null, function() {
core.setHeroMoveTriggerInterval(); core.setHeroMoveTriggerInterval();
@ -501,6 +504,10 @@ core.prototype.keyUp = function(keyCode) {
if (core.status.heroStop) if (core.status.heroStop)
core.ui.drawQuickShop(true); core.ui.drawQuickShop(true);
break; break;
case 32: // SPACE
if (!core.status.lockControl && core.status.heroStop)
core.getNextItem();
break;
case 37: // UP case 37: // UP
break; break;
case 38: // DOWN case 38: // DOWN
@ -626,7 +633,7 @@ core.prototype.getClickLoc = function (x, y) {
} }
core.prototype.onclick = function (x, y, stepPostfix) { 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; if (x<0 || y<0 || x>12 || y>12) return;
@ -649,6 +656,12 @@ core.prototype.onclick = function (x, y, stepPostfix) {
return; return;
} }
// 开关
if (core.status.event.id == 'switchs') {
core.events.clickSwitchs(x,y);
return;
}
// 设置 // 设置
if (core.status.event.id == 'settings') { if (core.status.event.id == 'settings') {
core.events.clickSettings(x,y); 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);
if (direct==-1) core.ui.drawEnemyBook(core.status.event.data + 1); if (direct==-1) core.ui.drawEnemyBook(core.status.event.data + 1);
return; 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);
if (direct==-1) core.ui.drawSLPanel(core.status.event.data + 1); if (direct==-1) core.ui.drawSLPanel(core.status.event.data + 1);
return; return;
@ -807,7 +820,18 @@ core.prototype.setAutomaticRoute = function (destX, destY, stepPostfix) {
return; return;
} }
if (destX == core.status.hero.loc.x && destY == core.status.hero.loc.y && stepPostfix.length==0) { 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; return;
} }
var step = 0; 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 ( (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 (!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) { if (nx == destX && ny == destY) {
route[nid] = direction; route[nid] = direction;
@ -1273,6 +1299,24 @@ core.prototype.moveOneStep = function() {
} }
core.updateStatusBar(); 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) { core.prototype.waitHeroToStop = function(callback) {
@ -1415,6 +1459,7 @@ core.prototype.afterBattle = function(id, x, y, callback) {
hint += ",经验+" + core.material.enemys[id].experience; hint += ",经验+" + core.material.enemys[id].experience;
core.drawTip(hint); core.drawTip(hint);
core.updateCheckBlockMap();
// 打完怪物,触发事件 // 打完怪物,触发事件
core.events.afterBattle(id,x,y,callback); 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('x', heroLoc.x);
core.setHeroLoc('y', heroLoc.y); core.setHeroLoc('y', heroLoc.y);
core.drawHero(core.getHeroLoc('direction'), core.getHeroLoc('x'), core.getHeroLoc('y'), 'stop'); core.drawHero(core.getHeroLoc('direction'), core.getHeroLoc('x'), core.getHeroLoc('y'), 'stop');
core.updateCheckBlockMap();
core.updateCheckBlock();
core.updateFg(); core.updateFg();
}, 15) }, 15)
}); });
@ -1992,6 +2039,7 @@ core.prototype.addBlock = function(x,y,floodId) {
// 本身是禁用事件,启用之 // 本身是禁用事件,启用之
if (core.isset(block.enable) && !block.enable) { if (core.isset(block.enable) && !block.enable) {
block.enable = true; block.enable = true;
core.updateCheckBlockMap();
// 在本层,添加动画 // 在本层,添加动画
if (floodId == core.status.floorId && core.isset(block.event)) { if (floodId == core.status.floorId && core.isset(block.event)) {
blockIcon = core.material.icons[block.event.cls][block.event.id]; 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 blocks = core.status.maps[floorId].blocks;
var x=blocks[index].x, y=blocks[index].y; 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]; var event = core.floors[floorId].events[x+","+y];
if (!core.isset(event)) if (!core.isset(event))
event = core.floors[floorId].changeFloor[x+","+y]; event = core.floors[floorId].changeFloor[x+","+y];
var shouldUpdateBlockMap = blocks[index].event.cls == 'enemys';
// 不存在事件,直接删除 // 不存在事件,直接删除
if (!core.isset(event)) { if (!core.isset(event)) {
blocks.splice(index,1); blocks.splice(index,1);
if (shouldUpdateBlockMap)
core.updateCheckBlockMap();
return; return;
} }
blocks[index].enable = false; blocks[index].enable = false;
if (shouldUpdateBlockMap)
core.updateCheckBlockMap();
} }
core.prototype.removeBlockByIds = function (floorId, ids) { 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;n<blocks.length;n++) {
var block = blocks[n];
if (core.isset(block.event) && !(core.isset(block.enable) && !block.enable)) {
if (block.event.cls=='enemys') {
var enemy = core.enemys.getEnemys(block.event.id);
if (core.isset(enemy)) {
var value=0;
if (core.enemys.hasSpecial(enemy.special, 15)) // 领域
value += enemy.value;
if (core.enemys.hasSpecial(enemy.special, 16)) // 夹击
value += 1000000 * block.id;
core.status.checkBlockMap[13*block.x+block.y] = value;
}
}
}
}
}
// 更新领域、显伤点
core.prototype.updateCheckBlock = function() {
if (!core.isset(core.status.thisMap)) return;
if (!core.isset(core.status.checkBlockMap)) core.updateCheckBlockMap();
core.status.checkBlock = [];
for (var x=0;x<13;x++) {
for (var y=0;y<13;y++) {
// 计算(x,y)点伤害
var damage = 0;
if (!core.enemyExists(x,y)) { // 如果该点本身不存在怪物(打死怪物会调用更新)
// 领域
[[-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) {
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) { core.prototype.setFg = function(color, time, callback) {
time = time || 750; time = time || 750;
core.setOpacity('fg', 1); core.setOpacity('fg', 1);
@ -2254,32 +2395,54 @@ core.prototype.updateFg = function () {
if (!core.hasItem('book')) return; if (!core.hasItem('book')) return;
core.setFont('fg', "bold 11px Arial"); core.setFont('fg', "bold 11px Arial");
var hero_hp = core.status.hero.hp; var hero_hp = core.status.hero.hp;
for (var b = 0; b < mapBlocks.length; b++) { if (core.flags.displayEnemyDamage) {
var x = mapBlocks[b].x, y = mapBlocks[b].y; core.canvas.fg.textAlign = 'left';
if (core.isset(mapBlocks[b].event) && mapBlocks[b].event.cls == 'enemys' && mapBlocks[b].event.trigger=='battle' 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)) { && !(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 damage = core.enemys.getDamage(id);
var color = "#000000"; var color = "#000000";
if (damage <= 0) color = '#00FF00'; if (damage <= 0) color = '#00FF00';
else if (damage < hero_hp / 3) color = '#FFFFFF'; else if (damage < hero_hp / 3) color = '#FFFFFF';
else if (damage < hero_hp * 2 / 3) color = '#FFFF00'; else if (damage < hero_hp * 2 / 3) color = '#FFFF00';
else if (damage < hero_hp) color = '#FF7F00'; else if (damage < hero_hp) color = '#FF7F00';
else color = '#FF0000'; else color = '#FF0000';
if (damage >= 999999999) damage = "???"; if (damage >= 999999999) damage = "???";
else if (damage > 100000) damage = (damage / 10000).toFixed(1) + "w"; else if (damage > 100000) damage = (damage / 10000).toFixed(1) + "w";
core.setFillStyle('fg', '#000000'); core.setFillStyle('fg', '#000000');
core.canvas.fg.fillText(damage, 32 * x + 2, 32 * (y + 1) - 2); 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, 32 * (y + 1) - 2);
core.canvas.fg.fillText(damage, 32 * x + 2, 32 * (y + 1)); core.canvas.fg.fillText(damage, 32 * x + 2, 32 * (y + 1));
core.canvas.fg.fillText(damage, 32 * x, 32 * (y + 1)); core.canvas.fg.fillText(damage, 32 * x, 32 * (y + 1));
core.setFillStyle('fg', color); core.setFillStyle('fg', color);
core.canvas.fg.fillText(damage, 32 * x + 1, 32 * (y + 1) - 1); 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.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.prototype.getItem = function (itemId, itemNum, itemX, itemY, callback) {
// core.getItemAnimate(itemId, itemNum, itemX, itemY); // core.getItemAnimate(itemId, itemNum, itemX, itemY);
core.playSound('item', 'ogg'); core.playSound('item', 'ogg');
@ -2368,6 +2541,7 @@ core.prototype.drawTip = function (text, itemIcon) {
core.setFont('data', "16px Arial"); core.setFont('data', "16px Arial");
core.saveCanvas('data'); core.saveCanvas('data');
core.setOpacity('data', 0); core.setOpacity('data', 0);
core.canvas.data.textAlign = 'left';
if (!core.isset(itemIcon)) { if (!core.isset(itemIcon)) {
textX = 16; textX = 16;
textY = 18; textY = 18;
@ -2845,6 +3019,7 @@ core.prototype.saveData = function(dataId) {
'hard': core.status.hard, 'hard': core.status.hard,
'maps': core.maps.save(core.status.maps), 'maps': core.maps.save(core.status.maps),
'shops': {}, 'shops': {},
'flags': core.flags,
'version': core.firstData.version, 'version': core.firstData.version,
"time": new Date().getTime() "time": new Date().getTime()
}; };
@ -2862,7 +3037,7 @@ core.prototype.saveData = function(dataId) {
core.prototype.loadData = function (data, callback) { 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 // load shop times
for (var shop in core.status.shops) { for (var shop in core.status.shops) {
@ -3038,7 +3213,6 @@ core.prototype.updateStatusBar = function () {
core.statusBar.weak.innerHTML = core.hasFlag('weak')?"衰":""; core.statusBar.weak.innerHTML = core.hasFlag('weak')?"衰":"";
core.statusBar.curse.innerHTML = core.hasFlag('curse')?"咒":""; core.statusBar.curse.innerHTML = core.hasFlag('curse')?"咒":"";
} }
core.statusBar.hard.innerHTML = core.status.hard; core.statusBar.hard.innerHTML = core.status.hard;
if (core.hasItem('book')) { if (core.hasItem('book')) {
@ -3051,6 +3225,7 @@ core.prototype.updateStatusBar = function () {
} else { } else {
core.statusBar.image.fly.style.opacity = 0.3; core.statusBar.image.fly.style.opacity = 0.3;
} }
core.updateCheckBlock();
core.updateFg(); core.updateFg();
} }

View File

@ -111,12 +111,12 @@ data.prototype.init = function() {
'breakArmor': 0.9, // 破甲的比例战斗前怪物附加角色防御的x%作为伤害) 'breakArmor': 0.9, // 破甲的比例战斗前怪物附加角色防御的x%作为伤害)
'counterAttack': 0.1, // 反击的比例战斗时怪物每回合附加角色攻击的x%作为伤害,无视角色防御) 'counterAttack': 0.1, // 反击的比例战斗时怪物每回合附加角色攻击的x%作为伤害,无视角色防御)
'purify': 3, // 净化的比例战斗前怪物附加勇士魔防的x倍作为伤害 'purify': 3, // 净化的比例战斗前怪物附加勇士魔防的x倍作为伤害
'hatred': 2, // 仇恨属性中,每杀死一个怪物获得的仇恨值
/****** 系统相关 ******/ /****** 系统相关 ******/
'animateSpeed': 500, // 动画时间 'animateSpeed': 500, // 动画时间
} }
// 系统FLAG在游戏运行中中请不要修改它。 // 系统FLAG在游戏运行中中请不要修改它。
this.flags = { this.flags = {
/****** 角色状态相关 ******/ /****** 角色状态相关 ******/
"enableMDef": true, // 是否涉及勇士的魔防值如果此项为false则状态栏不会显示勇士的魔防值 "enableMDef": true, // 是否涉及勇士的魔防值如果此项为false则状态栏不会显示勇士的魔防值
"enableExperience": true, // 是否涉及经验值如果此项为false则状态栏和怪物手册均将不会显示经验值 "enableExperience": true, // 是否涉及经验值如果此项为false则状态栏和怪物手册均将不会显示经验值
@ -125,10 +125,12 @@ data.prototype.init = function() {
"flyNearStair": true, // 是否需要在楼梯边使用传送器 "flyNearStair": true, // 是否需要在楼梯边使用传送器
"pickaxeFourDirections": true, // 使用破墙镐是否四个方向都破坏如果false则只破坏面前的墙壁 "pickaxeFourDirections": true, // 使用破墙镐是否四个方向都破坏如果false则只破坏面前的墙壁
"bigKeyIsBox": false, // 如果此项为true则视为钥匙盒红黄蓝钥匙+1若为false则视为大黄门钥匙 "bigKeyIsBox": false, // 如果此项为true则视为钥匙盒红黄蓝钥匙+1若为false则视为大黄门钥匙
/****** 系统相关 ******/ /****** 系统相关 ******/
"startDirectly": false, // 点击“开始游戏”后是否立刻开始游戏而不显示难度选择界面 "startDirectly": false, // 点击“开始游戏”后是否立刻开始游戏而不显示难度选择界面
"battleAnimate": true, // 是否默认显示战斗动画;用户可以手动在菜单栏中关闭 "battleAnimate": true, // 是否默认显示战斗动画;用户可以手动在菜单栏中开关
"displayEnemyDamage": true, // 是否地图怪物显伤;用户可以手动在菜单栏中开关
"displayExtraDamage": false, // 是否地图高级显伤(领域、夹击等);用户可以手动在菜单栏中开关
"enableGentleClick": true, // 是否允许轻触(获得面前物品)
"portalWithoutTrigger": true, // 经过楼梯、传送门时是否能“穿透”。穿透的意思是,自动寻路得到的的路径中间经过了楼梯,行走时是否触发楼层转换事件 "portalWithoutTrigger": true, // 经过楼梯、传送门时是否能“穿透”。穿透的意思是,自动寻路得到的的路径中间经过了楼梯,行走时是否触发楼层转换事件
"potionWhileRouting": false, // 寻路算法是否经过血瓶如果该项为false则寻路算法会自动尽量绕过血瓶 "potionWhileRouting": false, // 寻路算法是否经过血瓶如果该项为false则寻路算法会自动尽量绕过血瓶
} }

View File

@ -99,6 +99,7 @@ enemys.prototype.getSpecialText = function (enemyId) {
if (this.hasSpecial(special, 14)) text.push("诅咒"); if (this.hasSpecial(special, 14)) text.push("诅咒");
if (this.hasSpecial(special, 15)) text.push("领域"); if (this.hasSpecial(special, 15)) text.push("领域");
if (this.hasSpecial(special, 16)) text.push("夹击"); if (this.hasSpecial(special, 16)) text.push("夹击");
if (this.hasSpecial(special, 17)) text.push("仇恨");
return text.join(" "); return text.join(" ");
} }
@ -118,6 +119,9 @@ enemys.prototype.getExtraDamage = function (monster) {
extra_damage = core.status.hero.hp * monster.value; extra_damage = core.status.hero.hp * monster.value;
extra_damage = parseInt(extra_damage); extra_damage = parseInt(extra_damage);
} }
if (this.hasSpecial(monster.special, 17)) { // 仇恨
extra_damage += core.getFlag('hatred', 0);
}
return extra_damage; return extra_damage;
} }

View File

@ -34,11 +34,6 @@ events.prototype.init = function () {
if (core.isset(callback)) if (core.isset(callback))
callback(); callback();
}, },
"checkBlock": function (data, core, callback) {
core.events.checkBlock(data.x, data.y);
if (core.isset(callback))
callback();
},
"changeLight": function (data, core, callback) { "changeLight": function (data, core, callback) {
core.events.changeLight(data.x, data.y); core.events.changeLight(data.x, data.y);
if (core.isset(callback)) 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) { events.prototype.afterChangeFloor = function (floorId) {
if (!core.hasFlag("visited_"+floorId)) { if (!core.hasFlag("visited_"+floorId)) {
@ -451,8 +402,10 @@ events.prototype.disableQuickShop = function (shopId) {
} }
////// 降低难度 ////// ////// 降低难度 //////
/*
events.prototype.decreaseHard = function() { events.prototype.decreaseHard = function() {
core.drawTip("本塔不支持降低难度!");
/*
if (core.status.hard == 0) { if (core.status.hard == 0) {
core.drawTip("当前已是难度0不能再降低难度了"); core.drawTip("当前已是难度0不能再降低难度了");
return; return;
@ -470,8 +423,8 @@ events.prototype.decreaseHard = function() {
}, function () { }, function () {
core.ui.drawSettings(false); core.ui.drawSettings(false);
}); });
*/
} }
*/
////// 能否使用快捷商店 ////// ////// 能否使用快捷商店 //////
events.prototype.canUseQuickShop = function(shopIndex) { 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')) { if (core.enemys.hasSpecial(special, 12) && !core.hasFlag('poison')) {
core.setFlag('poison', true); core.setFlag('poison', true);
core.updateStatusBar();
} }
// 衰弱 // 衰弱
if (core.enemys.hasSpecial(special, 13) && !core.hasFlag('weak')) { if (core.enemys.hasSpecial(special, 13) && !core.hasFlag('weak')) {
core.setFlag('weak', true); core.setFlag('weak', true);
core.status.hero.atk-=core.values.weakValue; core.status.hero.atk-=core.values.weakValue;
core.status.hero.def-=core.values.weakValue; core.status.hero.def-=core.values.weakValue;
core.updateStatusBar();
} }
// 诅咒 // 诅咒
if (core.enemys.hasSpecial(special, 14) && !core.hasFlag('curse')) { if (core.enemys.hasSpecial(special, 14) && !core.hasFlag('curse')) {
core.setFlag('curse', true); 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) { if (core.status.lockControl) {
@ -604,11 +561,11 @@ events.prototype.changeLight = function(x, y) {
core.canvas.event.clearRect(x * 32, y * 32, 32, 32); core.canvas.event.clearRect(x * 32, y * 32, 32, 32);
var blockIcon = core.material.icons[block.event.cls][block.event.id]; 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); 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.clickSwitchs = function (x,y) {
events.prototype.clickSettings = function (x,y) {
if (x<5 || x>7) return; if (x<5 || x>7) return;
if (y == 3) { if (y==4) {
if (core.musicStatus.isIOS) { if (core.musicStatus.isIOS) {
core.drawTip("iOS设备不支持播放音乐"); core.drawTip("iOS设备不支持播放音乐");
return; return;
} }
core.changeSoundStatus(); 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); 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) { if (y==4) {
/*
core.flags.battleAnimate=!core.flags.battleAnimate; core.flags.battleAnimate=!core.flags.battleAnimate;
core.setLocalStorage('battleAnimate', core.flags.battleAnimate); core.setLocalStorage('battleAnimate', core.flags.battleAnimate);
core.ui.drawSettings(false); core.ui.drawSettings(false);
*/
this.decreaseHard();
} }
if (y == 5) core.ui.drawQuickShop(); if (y == 5) core.ui.drawQuickShop();
// if (y == 5) this.decreaseHard(); // if (y == 5) this.decreaseHard();

View File

@ -27,14 +27,6 @@ main.floors.MT0 = {
}, },
"afterOpenDoor": { // 开完门后可能触发的事件列表 "afterOpenDoor": { // 开完门后可能触发的事件列表
}, }
"checkBlock": [
/****** 领域、夹击检查事件 ******/
// 所有可能的领域、夹击点均需要在这里给出,否则将不会触发检查事件
// 另外如果该点已经存在events事件或changeFloor事件即上面有相同点位置定义则会被覆盖
// afterBattle, afterGetItem, afterOpenDoor则不受影响仍能正常工作
// 所以 |****** 强烈要求可能的夹击、领域点不要存在自定义事件!! ******|
]
} }

View File

@ -108,15 +108,7 @@ main.floors.sample0 = {
}, },
"afterOpenDoor": { // 开完门后可能触发的事件列表 "afterOpenDoor": { // 开完门后可能触发的事件列表
"11,12": ["你开了一个绿门触发了一个afterOpenDoor事件"] "11,12": ["你开了一个绿门触发了一个afterOpenDoor事件"]
}, }
"checkBlock": [
/****** 领域、夹击检查事件 ******/
// 所有可能的领域、夹击点均需要在这里给出,否则将不会触发检查事件
// 另外如果该点已经存在events事件或changeFloor事件即上面有相同点位置定义则会被覆盖
// afterBattle, afterGetItem, afterOpenDoor则不受影响仍能正常工作
// 所以 |****** 强烈要求可能的夹击、领域点不要存在自定义事件!! ******|
"1,0", "3,0", "0,1", "2,1", "4,1", "1,2", "3,2"
]
} }

View File

@ -13,7 +13,7 @@ main.floors.sample1 = {
[2, 2, 2, 2, 121, 2, 2, 2, 0, 0, 229, 0, 0], [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], [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], [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], [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], [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], [1, 246, 1, 1, 0, 2, 2, 2, 2, 2, 2, 2, 2],
@ -299,14 +299,6 @@ main.floors.sample1 = {
}, },
"afterOpenDoor": { // 开完门后可能触发的事件列表 "afterOpenDoor": { // 开完门后可能触发的事件列表
}, }
"checkBlock": [
/****** 领域、夹击检查事件 ******/
// 所有可能的领域、夹击点均需要在这里给出,否则将不会触发检查事件
// 另外如果该点已经存在events事件或changeFloor事件即上面有相同点位置定义则会被覆盖
// afterBattle, afterGetItem, afterOpenDoor则不受影响仍能正常工作
// 所以 |****** 强烈要求可能的夹击、领域点不要存在自定义事件!! ******|
]
} }

View File

@ -365,14 +365,6 @@ main.floors.sample2 = {
}, },
"afterOpenDoor": { // 开完门后可能触发的事件列表 "afterOpenDoor": { // 开完门后可能触发的事件列表
}, }
"checkBlock": [
/****** 领域、夹击检查事件 ******/
// 所有可能的领域、夹击点均需要在这里给出,否则将不会触发检查事件
// 另外如果该点已经存在events事件或changeFloor事件即上面有相同点位置定义则会被覆盖
// afterBattle, afterGetItem, afterOpenDoor则不受影响仍能正常工作
// 所以 |****** 强烈要求可能的夹击、领域点不要存在自定义事件!! ******|
]
} }

View File

@ -36,8 +36,6 @@ maps.prototype.loadFloor = function (floorId, map) {
} }
this.addEvent(block,j,i,floor.events[j+","+i]) this.addEvent(block,j,i,floor.events[j+","+i])
this.addChangeFloor(block,j,i,floor.changeFloor[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); if (core.isset(block.event)) blocks.push(block);
} }
} }

View File

@ -302,6 +302,30 @@ ui.prototype.drawConfirmBox = function (text, yesCallback, noCallback) {
core.fillText('ui', "取消", 208 + 38, top + bottom - 35); 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 * @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.strokeRect('ui', left - 1, top - 1, right + 1, bottom + 1, '#FFFFFF', 2);
core.canvas.ui.textAlign = "center"; core.canvas.ui.textAlign = "center";
core.fillText('ui', "音乐: " + (core.musicStatus.soundStatus ? "[ON]" : "[OFF]"), 208, top + 56, "#FFFFFF", "bold 17px Verdana"); core.fillText('ui', "系统设置", 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 + 88, "#FFFFFF", "bold 17px Verdana")
core.fillText('ui', "快捷商店", 208, top + 120, "#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");
// 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); core.fillText('ui', "返回游戏", 208, top + bottom - 40);
} }
ui.prototype.drawBattleAnimate = function(monsterId, callback) { 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; if (core.enemys.hasSpecial(mon_special, 6)) turns=5;
// 初始伤害(破甲、净化) // 初始伤害
var initDamage = 0; var initDamage = 0;
if (core.enemys.hasSpecial(mon_special, 7)) initDamage+=parseInt(core.values.breakArmor * hero_def); 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; hero_mdef-=initDamage;
if (hero_mdef<0) { if (hero_mdef<0) {
hero_hp+=hero_mdef; hero_hp+=hero_mdef;
@ -425,6 +453,7 @@ ui.prototype.drawBattleAnimate = function(monsterId, callback) {
core.fillRect('ui', left, top, right, bottom, '#000000'); core.fillRect('ui', left, top, right, bottom, '#000000');
core.setAlpha('ui', 1); core.setAlpha('ui', 1);
core.strokeRect('ui', left - 1, top - 1, right + 1, bottom + 1, '#FFFFFF', 2); 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.setAlpha('data', 1);
core.setOpacity('data', 1); core.setOpacity('data', 1);
core.status.boxAnimateObjs = []; core.status.boxAnimateObjs = [];

View File

@ -2,7 +2,8 @@
新增:可视化地图编辑工具 新增:可视化地图编辑工具
新增便捷P图工具 √ 新增便捷P图工具 √
新增支持Autotile √ 新增支持Autotile √
新增:怪物支持多属性 √ 新增:怪物支持多属性,添加仇恨属性 √
移除checkBlock现在对领域和夹击无需指定坐标了 √
新增:单向箭头、感叹号 √ 新增:单向箭头、感叹号 √
新增:勇士支持移动;其他事件支持移动 √ 新增:勇士支持移动;其他事件支持移动 √
快捷道具使用1破2炸3飞读档改为D键 √ 快捷道具使用1破2炸3飞读档改为D键 √