领域夹击处理机制更新
This commit is contained in:
parent
c8be88c8a0
commit
91b19477f8
@ -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)
|
||||
|
||||

|
||||
|
||||
|
||||
255
libs/core.js
255
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;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) {
|
||||
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();
|
||||
}
|
||||
|
||||
|
||||
@ -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,则寻路算法会自动尽量绕过血瓶
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
102
libs/events.js
102
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();
|
||||
|
||||
@ -27,14 +27,6 @@ main.floors.MT0 = {
|
||||
},
|
||||
"afterOpenDoor": { // 开完门后可能触发的事件列表
|
||||
|
||||
},
|
||||
"checkBlock": [
|
||||
/****** 领域、夹击检查事件 ******/
|
||||
// 所有可能的领域、夹击点均需要在这里给出,否则将不会触发检查事件
|
||||
// 另外,如果该点已经存在events事件或changeFloor事件(即上面有相同点位置定义),则会被覆盖
|
||||
// afterBattle, afterGetItem, afterOpenDoor则不受影响(仍能正常工作)。
|
||||
// 所以 |****** 强烈要求可能的夹击、领域点不要存在自定义事件!! ******|
|
||||
]
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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"
|
||||
]
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -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则不受影响(仍能正常工作)。
|
||||
// 所以 |****** 强烈要求可能的夹击、领域点不要存在自定义事件!! ******|
|
||||
]
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -365,14 +365,6 @@ main.floors.sample2 = {
|
||||
},
|
||||
"afterOpenDoor": { // 开完门后可能触发的事件列表
|
||||
|
||||
},
|
||||
"checkBlock": [
|
||||
/****** 领域、夹击检查事件 ******/
|
||||
// 所有可能的领域、夹击点均需要在这里给出,否则将不会触发检查事件
|
||||
// 另外,如果该点已经存在events事件或changeFloor事件(即上面有相同点位置定义),则会被覆盖
|
||||
// afterBattle, afterGetItem, afterOpenDoor则不受影响(仍能正常工作)。
|
||||
// 所以 |****** 强烈要求可能的夹击、领域点不要存在自定义事件!! ******|
|
||||
]
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
39
libs/ui.js
39
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 = [];
|
||||
|
||||
Loading…
Reference in New Issue
Block a user