automaticRoute & autoMove
This commit is contained in:
parent
ac8faed0f3
commit
ef5aa25047
@ -972,7 +972,7 @@ this.getAchievements = function () {
|
||||
- **`flag:__color__`**, **`flag:__weather__`**, **`flag:__volume__`**: 当前的画面色调、天气和音量。
|
||||
- **`flag:__events__`**: 当前保存的事件列表,读档时会恢复(适用于在事件中存档)
|
||||
- **`flag:textAttribute`**, **`flag:globalAttribute`**, **`flag:globalFlags`**: 当前的剧情文本属性,当前的全局属性,当前的全局开关。
|
||||
- **`flag:cannotMoveDirectly`**, **`flag:clickMove`**: 当前是否不允许瞬间移动,当前用户是否开启了单击瞬移。
|
||||
- **`flag:cannotMoveDirectly`**, **`flag:__noClickMove__`**: 当前是否不允许瞬间移动,当前用户是否开启了单击瞬移。
|
||||
- **`flag:hideStatusBar`**, **`flag:showToolbox`**: 是否隐藏状态栏,是否显示工具栏。
|
||||
- **`flag:debug`**, **`flag:__consoleOpened__`**: 当前是否开启了调试模式,是否开启了控制台。
|
||||
- **`flag:__seed__`**, **`flag:__rand__`**: 伪随机数生成种子和当前的状态
|
||||
|
||||
@ -105,7 +105,6 @@ var functions_comment_c456ea59_6018_45ef_8bcc_211a24c627dc =
|
||||
}
|
||||
},
|
||||
"enemys": {
|
||||
|
||||
"_type": "object",
|
||||
"_data": {
|
||||
"getSpecials": {
|
||||
@ -135,7 +134,6 @@ var functions_comment_c456ea59_6018_45ef_8bcc_211a24c627dc =
|
||||
}
|
||||
},
|
||||
"actions": {
|
||||
|
||||
"_type": "object",
|
||||
"_data": {
|
||||
"onKeyUp": {
|
||||
@ -147,7 +145,6 @@ var functions_comment_c456ea59_6018_45ef_8bcc_211a24c627dc =
|
||||
}
|
||||
},
|
||||
"control": {
|
||||
|
||||
"_type": "object",
|
||||
"_data": {
|
||||
"flyTo": {
|
||||
@ -173,11 +170,16 @@ var functions_comment_c456ea59_6018_45ef_8bcc_211a24c627dc =
|
||||
"_type": "textarea",
|
||||
"_lint": true,
|
||||
"_data": "勇士每走一步的操作"
|
||||
},
|
||||
"moveDirectly": {
|
||||
"_leaf": true,
|
||||
"_type": "textarea",
|
||||
"_lint": true,
|
||||
"_data": "瞬间移动"
|
||||
}
|
||||
}
|
||||
},
|
||||
"ui": {
|
||||
|
||||
"_type": "object",
|
||||
"_data": {
|
||||
"drawStatusBar": {
|
||||
@ -201,7 +203,6 @@ var functions_comment_c456ea59_6018_45ef_8bcc_211a24c627dc =
|
||||
}
|
||||
},
|
||||
"plugins": {
|
||||
|
||||
"_type": "object",
|
||||
"_data": {
|
||||
"parallelDo": {
|
||||
|
||||
@ -1789,7 +1789,8 @@ actions.prototype._clickSwitchs = function (x, y) {
|
||||
core.ui.drawSwitchs();
|
||||
break;
|
||||
case 6:
|
||||
core.setFlag('clickMove', !core.getFlag('clickMove', true));
|
||||
if (core.hasFlag('__noClickMove__')) core.removeFlag('__noClickMove__');
|
||||
else core.setFlag('__noClickMove__', true);
|
||||
core.ui.drawSwitchs();
|
||||
break;
|
||||
case 7:
|
||||
|
||||
334
libs/control.js
334
libs/control.js
@ -374,20 +374,16 @@ control.prototype._initStatistics = function (totalTime) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/////////////////////// 寻路算法 & 人物行走控制 ///////////////////////
|
||||
// ------ 自动寻路,人物行走 ------ //
|
||||
|
||||
////// 清除自动寻路路线 //////
|
||||
control.prototype.clearAutomaticRouteNode = function (x, y) {
|
||||
if (core.status.event.id==null)
|
||||
core.clearMap('route', x * 32 + 5 - core.status.automaticRoute.offsetX, y * 32 + 5 - core.status.automaticRoute.offsetY, 27, 27);
|
||||
core.clearMap('route', x * 32 + 5 - core.status.automaticRoute.offsetX, y * 32 + 5 - core.status.automaticRoute.offsetY, 27, 27);
|
||||
}
|
||||
|
||||
////// 停止自动寻路操作 //////
|
||||
control.prototype.stopAutomaticRoute = function () {
|
||||
if (!core.status.played) {
|
||||
return;
|
||||
}
|
||||
if (!core.status.played) return;
|
||||
core.status.automaticRoute.autoHeroMove = false;
|
||||
core.status.automaticRoute.autoStep = 0;
|
||||
core.status.automaticRoute.destStep = 0;
|
||||
@ -401,6 +397,7 @@ control.prototype.stopAutomaticRoute = function () {
|
||||
core.deleteCanvas('route');
|
||||
}
|
||||
|
||||
////// 保存剩下的寻路,并停止 //////
|
||||
control.prototype.saveAndStopAutomaticRoute = function () {
|
||||
var automaticRoute = core.status.automaticRoute;
|
||||
if (automaticRoute.moveStepBeforeStop.length == 0) {
|
||||
@ -431,52 +428,33 @@ control.prototype.clearContinueAutomaticRoute = function (callback) {
|
||||
if (callback) callback();
|
||||
}
|
||||
|
||||
////// 瞬间移动 //////
|
||||
control.prototype.moveDirectly = function (destX, destY) {
|
||||
var ignoreSteps = core.canMoveDirectly(destX, destY);
|
||||
if (ignoreSteps>=0) {
|
||||
core.clearMap('hero');
|
||||
var lastDirection = core.status.route[core.status.route.length-1];
|
||||
if (['left', 'right', 'up', 'down'].indexOf(lastDirection)>=0)
|
||||
core.setHeroLoc('direction', lastDirection);
|
||||
core.setHeroLoc('x', destX);
|
||||
core.setHeroLoc('y', destY);
|
||||
core.drawHero();
|
||||
core.status.route.push("move:"+destX+":"+destY);
|
||||
core.status.hero.statistics.moveDirectly++;
|
||||
core.status.hero.statistics.ignoreSteps+=ignoreSteps;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
////// 尝试瞬间移动 //////
|
||||
control.prototype.tryMoveDirectly = function (destX, destY) {
|
||||
if (Math.abs(core.getHeroLoc('x')-destX)+Math.abs(core.getHeroLoc('y')-destY)<=1)
|
||||
return false;
|
||||
var canMoveArray = core.maps.generateMovableArray();
|
||||
var testMove = function (dx, dy, dir) {
|
||||
if (dx<0 || dx>=core.bigmap.width|| dy<0 || dy>=core.bigmap.height) return false;
|
||||
if (core.isset(dir) && !core.inArray(canMoveArray[dx][dy],dir)) return false;
|
||||
if (core.control.moveDirectly(dx, dy)) {
|
||||
if (core.isset(dir)) core.moveHero(dir, function() {});
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return testMove(destX,destY) || testMove(destX-1, destY, "right") || testMove(destX,destY-1,"down")
|
||||
|| testMove(destX,destY+1,"up") || testMove(destX+1,destY,"left");
|
||||
////// 显示离散的寻路点 //////
|
||||
control.prototype.fillPosWithPoint = function (pos) {
|
||||
core.fillRect('ui', pos.x*32+12,pos.y*32+12,8,8, '#bfbfbf');
|
||||
}
|
||||
|
||||
////// 设置自动寻路路线 //////
|
||||
control.prototype.setAutomaticRoute = function (destX, destY, stepPostfix) {
|
||||
if (!core.status.played || core.status.lockControl) {
|
||||
return;
|
||||
}
|
||||
// 正在寻路中
|
||||
if (!core.status.played || core.status.lockControl) return;
|
||||
if (this._setAutomaticRoute_isMoving(destX, destY)) return;
|
||||
if (this._setAutomaticRoute_isTurning(destX, destY, stepPostfix)) return;
|
||||
if (this._setAutomaticRoute_clickMoveDirectly(destX, destY, stepPostfix)) return;
|
||||
// 找寻自动寻路路线
|
||||
var moveStep = core.automaticRoute(destX, destY).concat(stepPostfix);
|
||||
if (moveStep.length == 0) return core.deleteCanvas('route');
|
||||
core.status.automaticRoute.destX=destX;
|
||||
core.status.automaticRoute.destY=destY;
|
||||
this._setAutomaticRoute_drawRoute(moveStep);
|
||||
this._setAutomaticRoute_setAutoSteps(moveStep);
|
||||
// 立刻移动
|
||||
core.setAutoHeroMove();
|
||||
}
|
||||
|
||||
control.prototype._setAutomaticRoute_isMoving = function (destX, destY) {
|
||||
if (core.status.automaticRoute.autoHeroMove) {
|
||||
var lastX = core.status.automaticRoute.destX, lastY=core.status.automaticRoute.destY;
|
||||
core.stopAutomaticRoute();
|
||||
// 双击瞬移
|
||||
if (lastX==destX && lastY==destY) {
|
||||
core.status.automaticRoute.moveDirectly = true;
|
||||
setTimeout(function () {
|
||||
@ -486,8 +464,12 @@ control.prototype.setAutomaticRoute = function (destX, destY, stepPostfix) {
|
||||
core.status.automaticRoute.moveDirectly = false;
|
||||
}, core.values.moveSpeed || 100);
|
||||
}
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
control.prototype._setAutomaticRoute_isTurning = function (destX, destY, stepPostfix) {
|
||||
if (destX == core.status.hero.loc.x && destY == core.status.hero.loc.y && stepPostfix.length==0) {
|
||||
if (core.timeout.turnHeroTimeout==null) {
|
||||
core.timeout.turnHeroTimeout = setTimeout(function() {
|
||||
@ -501,27 +483,23 @@ control.prototype.setAutomaticRoute = function (destX, destY, stepPostfix) {
|
||||
core.timeout.turnHeroTimeout = null;
|
||||
core.getNextItem();
|
||||
}
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
if (core.timeout.turnHeroTimeout!=null) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (core.timeout.turnHeroTimeout!=null) return;
|
||||
|
||||
control.prototype._setAutomaticRoute_clickMoveDirectly = function (destX, destY, stepPostfix) {
|
||||
// 单击瞬间移动
|
||||
if (core.status.heroStop && core.status.heroMoving==0) {
|
||||
if (stepPostfix.length<=1 && core.getFlag('clickMove', true) && core.control.tryMoveDirectly(destX, destY))
|
||||
return;
|
||||
if (stepPostfix.length<=1 && !core.hasFlag('__noClickMove__') && core.control.tryMoveDirectly(destX, destY))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
var moveStep = core.automaticRoute(destX, destY).concat(stepPostfix);
|
||||
if (moveStep.length == 0) {
|
||||
core.deleteCanvas('route');
|
||||
return;
|
||||
}
|
||||
|
||||
core.status.automaticRoute.destX=destX;
|
||||
core.status.automaticRoute.destY=destY;
|
||||
|
||||
// 计算绘制区域的宽高
|
||||
control.prototype._setAutomaticRoute_drawRoute = function (moveStep) {
|
||||
// 计算绘制区域的宽高,并尽可能小的创建route层
|
||||
var sx = core.bigmap.width * 32, sy = core.bigmap.height * 32, dx = 0, dy = 0;
|
||||
moveStep.forEach(function (t) {
|
||||
sx = Math.min(sx, t.x * 32); dx = Math.max(dx, t.x * 32);
|
||||
@ -547,7 +525,9 @@ control.prototype.setAutomaticRoute = function (destX, destY, stepPostfix) {
|
||||
ctx.stroke();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
control.prototype._setAutomaticRoute_setAutoSteps = function (moveStep) {
|
||||
// 路线转autoStepRoutes
|
||||
var step = 0, currStep = null;
|
||||
moveStep.forEach(function (t) {
|
||||
@ -556,111 +536,17 @@ control.prototype.setAutomaticRoute = function (destX, destY, stepPostfix) {
|
||||
step++;
|
||||
else {
|
||||
core.status.automaticRoute.autoStepRoutes.push({'direction': currStep, 'step': step});
|
||||
step = 1;
|
||||
step = 1;
|
||||
}
|
||||
currStep = dir;
|
||||
});
|
||||
core.status.automaticRoute.autoStepRoutes.push({'direction': currStep, 'step': step});
|
||||
|
||||
// 立刻移动
|
||||
core.setAutoHeroMove();
|
||||
}
|
||||
|
||||
////// 自动寻路算法,找寻最优路径 //////
|
||||
control.prototype.automaticRoute = function (destX, destY) {
|
||||
var fw = core.bigmap.width, fh = core.bigmap.height;
|
||||
var startX = core.getHeroLoc('x');
|
||||
var startY = core.getHeroLoc('y');
|
||||
if (destX == startX && destY == startY) return [];
|
||||
|
||||
var route = [];
|
||||
var queue = new PriorityQueue({comparator: function (a,b) {
|
||||
return a.depth - b.depth;
|
||||
}});
|
||||
var ans = [];
|
||||
|
||||
var canMoveArray = core.maps.generateMovableArray();
|
||||
|
||||
route[startX + fw * startY] = '';
|
||||
queue.queue({depth: 0, x: startX, y: startY});
|
||||
while (queue.length!=0) {
|
||||
var curr = queue.dequeue();
|
||||
var deep = curr.depth, nowX = curr.x, nowY = curr.y;
|
||||
|
||||
for (var direction in core.utils.scan) {
|
||||
if (!core.inArray(canMoveArray[nowX][nowY], direction))
|
||||
continue;
|
||||
|
||||
var nx = nowX + core.utils.scan[direction].x;
|
||||
var ny = nowY + core.utils.scan[direction].y;
|
||||
if (nx<0 || nx>=fw || ny<0 || ny>=fh) continue;
|
||||
|
||||
var nid = nx + fw * ny;
|
||||
|
||||
if (core.isset(route[nid])) continue;
|
||||
|
||||
var deepAdd=1;
|
||||
var nextId, nextBlock = core.getBlock(nx,ny);
|
||||
if (nextBlock!=null){
|
||||
nextId = nextBlock.block.event.id;
|
||||
// 绕过亮灯(因为只有一次通行机会很宝贵)
|
||||
if(nextId == "light") deepAdd=100;
|
||||
// 绕过路障
|
||||
// if (nextId.substring(nextId.length-3)=="Net") deepAdd=core.values.lavaDamage*10;
|
||||
// 绕过血瓶
|
||||
if (!core.flags.potionWhileRouting && nextId.substring(nextId.length-6)=="Potion") deepAdd+=20;
|
||||
// 绕过传送点
|
||||
if (nextBlock.block.event.trigger == 'changeFloor') deepAdd+=10;
|
||||
}
|
||||
deepAdd+=core.status.checkBlock.damage[nid]*10;
|
||||
// 绕过捕捉
|
||||
if ((core.status.checkBlock.ambush||[])[nid])
|
||||
deepAdd += 10000;
|
||||
|
||||
if (nx == destX && ny == destY) {
|
||||
route[nid] = direction;
|
||||
break;
|
||||
}
|
||||
if (core.noPass(nx, ny))
|
||||
continue;
|
||||
|
||||
route[nid] = direction;
|
||||
queue.queue({depth: deep+deepAdd, x: nx, y: ny});
|
||||
}
|
||||
if (core.isset(route[destX + fw * destY])) break;
|
||||
}
|
||||
if (!core.isset(route[destX + fw * destY])) {
|
||||
return [];
|
||||
}
|
||||
|
||||
var nowX = destX, nowY = destY;
|
||||
while (nowX != startX || nowY != startY) {
|
||||
var dir = route[nowX + fw * nowY];
|
||||
ans.push({'direction': dir, 'x': nowX, 'y': nowY});
|
||||
nowX -= core.utils.scan[dir].x;
|
||||
nowY -= core.utils.scan[dir].y;
|
||||
}
|
||||
|
||||
ans.reverse();
|
||||
return ans;
|
||||
}
|
||||
|
||||
////// 显示离散的寻路点 //////
|
||||
control.prototype.fillPosWithPoint = function (pos) {
|
||||
core.fillRect('ui', pos.x*32+12,pos.y*32+12,8,8, '#bfbfbf');
|
||||
}
|
||||
|
||||
// 当前是否正在移动
|
||||
control.prototype.isMoving = function () {
|
||||
return !core.status.heroStop || core.status.heroMoving > 0;
|
||||
}
|
||||
|
||||
////// 设置勇士的自动行走路线 //////
|
||||
control.prototype.setAutoHeroMove = function (steps) {
|
||||
steps=steps||core.status.automaticRoute.autoStepRoutes;
|
||||
if (steps.length == 0) {
|
||||
return;
|
||||
}
|
||||
if (steps.length == 0) return;
|
||||
core.status.automaticRoute.autoStepRoutes=steps;
|
||||
core.status.automaticRoute.autoHeroMove = true;
|
||||
core.status.automaticRoute.autoStep = 1;
|
||||
@ -670,35 +556,30 @@ control.prototype.setAutoHeroMove = function (steps) {
|
||||
|
||||
////// 设置行走的效果动画 //////
|
||||
control.prototype.setHeroMoveInterval = function (direction, x, y, callback) {
|
||||
if (core.status.heroMoving>0) {
|
||||
return;
|
||||
}
|
||||
if (core.status.heroMoving > 0) return;
|
||||
core.status.heroMoving=1;
|
||||
|
||||
var toAdd = 1;
|
||||
if (core.status.replay.speed>3)
|
||||
toAdd = 2;
|
||||
if (core.status.replay.speed>6)
|
||||
toAdd = 4;
|
||||
if (core.status.replay.speed>12)
|
||||
toAdd = 8;
|
||||
if (core.status.replay.speed>3) toAdd = 2;
|
||||
if (core.status.replay.speed>6) toAdd = 4;
|
||||
if (core.status.replay.speed>12) toAdd = 8;
|
||||
|
||||
core.interval.heroMoveInterval = window.setInterval(function () {
|
||||
core.status.heroMoving+=toAdd;
|
||||
if (core.status.heroMoving>=8) {
|
||||
core.setHeroLoc('x', x+core.utils.scan[direction].x, true);
|
||||
core.setHeroLoc('y', y+core.utils.scan[direction].y, true);
|
||||
core.control.updateFollowers();
|
||||
core.moveOneStep();
|
||||
core.clearMap('hero');
|
||||
core.drawHero(direction);
|
||||
clearInterval(core.interval.heroMoveInterval);
|
||||
core.status.heroMoving = 0;
|
||||
if (core.isset(callback)) callback();
|
||||
core.moveOneStep(x + core.utils.scan[direction].x, y + core.utils.scan[direction].y);
|
||||
if (callback) callback();
|
||||
}
|
||||
}, (core.values.moveSpeed||100) / 8 * toAdd / core.status.replay.speed);
|
||||
}
|
||||
|
||||
////// 每移动一格后执行的事件 //////
|
||||
control.prototype.moveOneStep = function(x, y) {
|
||||
return this.controldata.moveOneStep(x, y);
|
||||
}
|
||||
|
||||
////// 实际每一步的行走过程 //////
|
||||
control.prototype.moveAction = function (callback) {
|
||||
if (core.status.heroMoving>0) return;
|
||||
@ -763,22 +644,6 @@ control.prototype.moveAction = function (callback) {
|
||||
}
|
||||
}
|
||||
|
||||
////// 转向 //////
|
||||
control.prototype.turnHero = function(direction) {
|
||||
if (core.isset(direction)) {
|
||||
core.setHeroLoc('direction', direction);
|
||||
core.drawHero();
|
||||
core.status.route.push("turn:"+direction);
|
||||
return;
|
||||
}
|
||||
if (core.status.hero.loc.direction == 'up') core.status.hero.loc.direction = 'right';
|
||||
else if (core.status.hero.loc.direction == 'right') core.status.hero.loc.direction = 'down';
|
||||
else if (core.status.hero.loc.direction == 'down') core.status.hero.loc.direction = 'left';
|
||||
else if (core.status.hero.loc.direction == 'left') core.status.hero.loc.direction = 'up';
|
||||
core.drawHero();
|
||||
core.status.route.push("turn");
|
||||
}
|
||||
|
||||
////// 让勇士开始移动 //////
|
||||
control.prototype.moveHero = function (direction, callback) {
|
||||
// 如果正在移动,直接return
|
||||
@ -822,6 +687,51 @@ control.prototype.moveHero = function (direction, callback) {
|
||||
}
|
||||
}
|
||||
|
||||
////// 当前是否正在移动 //////
|
||||
control.prototype.isMoving = function () {
|
||||
return !core.status.heroStop || core.status.heroMoving > 0;
|
||||
}
|
||||
|
||||
////// 停止勇士的一切行动,等待勇士行动结束后,再执行callback //////
|
||||
control.prototype.waitHeroToStop = function(callback) {
|
||||
var lastDirection = core.status.automaticRoute.lastDirection;
|
||||
core.stopAutomaticRoute();
|
||||
core.clearContinueAutomaticRoute();
|
||||
if (core.isset(callback)) {
|
||||
core.status.replay.animate=true;
|
||||
core.lockControl();
|
||||
core.status.automaticRoute.moveDirectly = false;
|
||||
setTimeout(function(){
|
||||
core.status.replay.animate=false;
|
||||
if (core.isset(lastDirection))
|
||||
core.setHeroLoc('direction', lastDirection);
|
||||
core.drawHero();
|
||||
callback();
|
||||
}, 30);
|
||||
}
|
||||
}
|
||||
|
||||
////// 停止勇士的移动状态 //////
|
||||
control.prototype.stopHero = function () {
|
||||
core.status.heroStop = true;
|
||||
}
|
||||
|
||||
////// 转向 //////
|
||||
control.prototype.turnHero = function(direction) {
|
||||
if (core.isset(direction)) {
|
||||
core.setHeroLoc('direction', direction);
|
||||
core.drawHero();
|
||||
core.status.route.push("turn:"+direction);
|
||||
return;
|
||||
}
|
||||
if (core.status.hero.loc.direction == 'up') core.status.hero.loc.direction = 'right';
|
||||
else if (core.status.hero.loc.direction == 'right') core.status.hero.loc.direction = 'down';
|
||||
else if (core.status.hero.loc.direction == 'down') core.status.hero.loc.direction = 'left';
|
||||
else if (core.status.hero.loc.direction == 'left') core.status.hero.loc.direction = 'up';
|
||||
core.drawHero();
|
||||
core.status.route.push("turn");
|
||||
}
|
||||
|
||||
/////// 使用事件让勇士移动。这个函数将不会触发任何事件 //////
|
||||
control.prototype.eventMoveHero = function(steps, time, callback) {
|
||||
time = time || core.values.moveSpeed || 100;
|
||||
@ -949,33 +859,27 @@ control.prototype.jumpHero = function (ex, ey, time, callback) {
|
||||
core.animateFrame.asyncId[animate] = true;
|
||||
}
|
||||
|
||||
////// 每移动一格后执行的事件 //////
|
||||
control.prototype.moveOneStep = function() {
|
||||
return this.controldata.moveOneStep();
|
||||
////// 瞬间移动 //////
|
||||
control.prototype.moveDirectly = function (destX, destY) {
|
||||
return this.controldata.moveDirectly(destX, destY);
|
||||
}
|
||||
|
||||
////// 停止勇士的一切行动,等待勇士行动结束后,再执行callback //////
|
||||
control.prototype.waitHeroToStop = function(callback) {
|
||||
var lastDirection = core.status.automaticRoute.lastDirection;
|
||||
core.stopAutomaticRoute();
|
||||
core.clearContinueAutomaticRoute();
|
||||
if (core.isset(callback)) {
|
||||
core.status.replay.animate=true;
|
||||
core.lockControl();
|
||||
core.status.automaticRoute.moveDirectly = false;
|
||||
setTimeout(function(){
|
||||
core.status.replay.animate=false;
|
||||
if (core.isset(lastDirection))
|
||||
core.setHeroLoc('direction', lastDirection);
|
||||
core.drawHero();
|
||||
callback();
|
||||
}, 30);
|
||||
////// 尝试瞬间移动 //////
|
||||
control.prototype.tryMoveDirectly = function (destX, destY) {
|
||||
if (Math.abs(core.getHeroLoc('x')-destX)+Math.abs(core.getHeroLoc('y')-destY)<=1)
|
||||
return false;
|
||||
var canMoveArray = core.maps.generateMovableArray();
|
||||
var testMove = function (dx, dy, dir) {
|
||||
if (dx<0 || dx>=core.bigmap.width|| dy<0 || dy>=core.bigmap.height) return false;
|
||||
if (core.isset(dir) && !core.inArray(canMoveArray[dx][dy],dir)) return false;
|
||||
if (core.control.moveDirectly(dx, dy)) {
|
||||
if (core.isset(dir)) core.moveHero(dir, function() {});
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
////// 停止勇士的移动状态 //////
|
||||
control.prototype.stopHero = function () {
|
||||
core.status.heroStop = true;
|
||||
return testMove(destX,destY) || testMove(destX-1, destY, "right") || testMove(destX,destY-1,"down")
|
||||
|| testMove(destX,destY+1,"up") || testMove(destX+1,destY,"left");
|
||||
}
|
||||
|
||||
////// 设置画布偏移
|
||||
@ -1038,7 +942,7 @@ control.prototype.drawHero = function (direction, x, y, status, offset) {
|
||||
|
||||
core.clearAutomaticRouteNode(x+dx, y+dy);
|
||||
|
||||
core.clearMap('hero', x * 32 - core.bigmap.offsetX - 32, y * 32 - core.bigmap.offsetY - 32, 96, 96);
|
||||
core.clearMap('hero', x * 32 - core.bigmap.offsetX - 32, y * 32 - core.bigmap.offsetY - 64, 96, 128);
|
||||
|
||||
var heroIconArr = core.material.icons.hero;
|
||||
var drawObjs = [];
|
||||
|
||||
@ -156,7 +156,7 @@ items.prototype.canUseItem = function (itemId) {
|
||||
|
||||
////// 获得某个物品的个数 //////
|
||||
items.prototype.itemCount = function (itemId) {
|
||||
if (!core.material.items[itemId]) return 0;
|
||||
if (!core.material.items[itemId] || !core.isPlaying()) return 0;
|
||||
var itemCls = core.material.items[itemId].cls;
|
||||
if (itemCls == "items") return 0;
|
||||
return core.status.hero.items[itemCls][itemId] || 0;
|
||||
@ -169,7 +169,7 @@ items.prototype.hasItem = function (itemId) {
|
||||
|
||||
////// 是否装备某件装备 //////
|
||||
items.prototype.hasEquip = function (itemId) {
|
||||
if (!(core.material.items[itemId] || {}).equip) return null;
|
||||
if (!(core.material.items[itemId] || {}).equip || !core.isPlaying()) return null;
|
||||
|
||||
for (var i in core.status.hero.equipment)
|
||||
if (core.status.hero.equipment[i] == itemId)
|
||||
|
||||
69
libs/maps.js
69
libs/maps.js
@ -505,6 +505,75 @@ maps.prototype._canMoveDirectly_checkNextPoint = function (blocksObj, x, y) {
|
||||
return true;
|
||||
}
|
||||
|
||||
////// 自动寻路找寻最优路径 //////
|
||||
maps.prototype.automaticRoute = function (destX, destY) {
|
||||
var startX = core.getHeroLoc('x'), startY = core.getHeroLoc('y');
|
||||
if (destX == startX && destY == startY) return [];
|
||||
// BFS找寻最短路径
|
||||
var route = this._automaticRoute_bfs(startX, startY, destX, destY);
|
||||
if (route[destX+","+destY] == null) return [];
|
||||
// 路径数组转换
|
||||
var ans = [], nowX = destX, nowY = destY;
|
||||
while (nowX != startX || nowY != startY) {
|
||||
var dir = route[nowX + "," + nowY];
|
||||
ans.push({'direction': dir, 'x': nowX, 'y': nowY});
|
||||
nowX -= core.utils.scan[dir].x;
|
||||
nowY -= core.utils.scan[dir].y;
|
||||
}
|
||||
ans.reverse();
|
||||
return ans;
|
||||
}
|
||||
|
||||
maps.prototype._automaticRoute_bfs = function (startX, startY, destX, destY) {
|
||||
var route = {}, canMoveArray = this.generateMovableArray();
|
||||
// 使用优先队列
|
||||
var queue = new PriorityQueue({comparator: function (a,b) { return a.depth - b.depth; }});
|
||||
route[startX + "," + startY] = '';
|
||||
queue.queue({depth: 0, x: startX, y: startY});
|
||||
while (queue.length!=0) {
|
||||
var curr = queue.dequeue(), deep = curr.depth, nowX = curr.x, nowY = curr.y;
|
||||
for (var direction in core.utils.scan) {
|
||||
if (!core.inArray(canMoveArray[nowX][nowY], direction)) continue;
|
||||
var nx = nowX + core.utils.scan[direction].x;
|
||||
var ny = nowY + core.utils.scan[direction].y;
|
||||
if (nx<0 || nx>=core.bigmap.width || ny<0 || ny>=core.bigmap.height || route[nx+","+ny] != null) continue;
|
||||
// 重点
|
||||
if (nx == destX && ny == destY) {
|
||||
route[nx+","+ny] = direction;
|
||||
break;
|
||||
}
|
||||
// 不可通行
|
||||
if (core.noPass(nx, ny)) continue;
|
||||
route[nx+","+ny] = direction;
|
||||
queue.queue({depth: deep + this._automaticRoute_deepAdd(nx, ny), x: nx, y: ny});
|
||||
}
|
||||
if (route[destX+","+destY] != null) break;
|
||||
}
|
||||
return route;
|
||||
}
|
||||
|
||||
maps.prototype._automaticRoute_deepAdd = function (x, y) {
|
||||
// 判定每个可通行点的损耗值,越高越应该绕路
|
||||
var deepAdd = 1;
|
||||
var block = core.getBlock(x,y);
|
||||
if (block != null){
|
||||
var id = block.block.event.id;
|
||||
// 绕过亮灯
|
||||
if (id == "light") deepAdd += 100;
|
||||
// 绕过路障
|
||||
if (id.endsWith("Net")) deepAdd += 100;
|
||||
// 绕过血瓶
|
||||
if (!core.flags.potionWhileRouting && id.endsWith("Potion")) deepAdd += 100;
|
||||
// 绕过传送点
|
||||
// if (nextBlock.block.event.trigger == 'changeFloor') deepAdd+=10;
|
||||
}
|
||||
// 绕过存在伤害的地方
|
||||
deepAdd += core.status.checkBlock.damage[x+","+y] * 100;
|
||||
// 绕过捕捉
|
||||
if ((core.status.checkBlock.ambush||[])[x+","+y]) deepAdd += 1000;
|
||||
return deepAdd;
|
||||
}
|
||||
|
||||
// -------- 绘制地图,各层图块,楼层贴图,Autotile -------- //
|
||||
|
||||
////// 绘制一个图块 //////
|
||||
|
||||
@ -1155,7 +1155,7 @@ ui.prototype.drawSwitchs = function() {
|
||||
"临界显伤: "+(core.flags.displayCritical ? "[ON]" : "[OFF]"),
|
||||
"领域显伤: "+(core.flags.displayExtraDamage ? "[ON]" : "[OFF]"),
|
||||
"新版存档: "+(core.platform.useLocalForage ? "[ON]":"[OFF]"),
|
||||
"单击瞬移: "+(core.getFlag('clickMove', true) ? "[ON]":"[OFF]"),
|
||||
"单击瞬移: "+(!core.hasFlag("__noClickMove__") ? "[ON]":"[OFF]"),
|
||||
"拓展键盘: "+(core.platform.extendKeyboard ? "[ON]":"[OFF]"),
|
||||
"返回主菜单"
|
||||
];
|
||||
|
||||
@ -1156,26 +1156,61 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a =
|
||||
}
|
||||
}
|
||||
},
|
||||
"moveOneStep": function () {
|
||||
// 勇士每走一步后执行的操作
|
||||
core.status.hero.steps++;
|
||||
// 中毒状态:扣血
|
||||
if (core.hasFlag('poison')) {
|
||||
core.status.hero.statistics.poisonDamage += core.values.poisonDamage;
|
||||
core.status.hero.hp -= core.values.poisonDamage;
|
||||
if (core.status.hero.hp<=0) {
|
||||
core.status.hero.hp=0;
|
||||
core.updateStatusBar();
|
||||
core.events.lose();
|
||||
return;
|
||||
}
|
||||
core.updateStatusBar();
|
||||
}
|
||||
// 备注:瞬间移动不会执行该函数。如果要控制能否瞬间移动有三种方法:
|
||||
"moveOneStep": function (x, y) {
|
||||
// 勇士每走一步后执行的操作,x,y为要移动到的坐标。
|
||||
// 这个函数执行在“刚走完”的时候,即还没有检查该点的事件和领域伤害等。
|
||||
// 请注意:瞬间移动不会执行该函数。如果要控制能否瞬间移动有三种方法:
|
||||
// 1. 将全塔属性中的cannotMoveDirectly这个开关勾上,即可在全塔中全程禁止使用瞬移。
|
||||
// 2, 将楼层属性中的cannotMoveDirectly这个开关勾上,即禁止在该层楼使用瞬移。
|
||||
// 3. 将flag:cannotMoveDirectly置为true,即可使用flag控制在某段剧情范围内禁止瞬移。
|
||||
|
||||
// 设置当前坐标,增加步数
|
||||
core.setHeroLoc('x', x, true);
|
||||
core.setHeroLoc('y', y, true);
|
||||
core.status.hero.steps++;
|
||||
// 更新跟随者状态,并绘制
|
||||
core.updateFollowers();
|
||||
core.drawHero();
|
||||
// 检查中毒状态的扣血和死亡
|
||||
if (core.hasFlag('poison')) {
|
||||
core.status.hero.statistics.poisonDamage += core.values.poisonDamage;
|
||||
core.status.hero.hp -= core.values.poisonDamage;
|
||||
if (core.status.hero.hp <= 0) {
|
||||
core.status.hero.hp = 0;
|
||||
core.updateStatusBar();
|
||||
core.events.lose();
|
||||
return;
|
||||
}
|
||||
}
|
||||
// 如需强行终止行走可以在这里条件判定:
|
||||
// core.stopAutomaticRoute();
|
||||
|
||||
core.updateStatusBar();
|
||||
},
|
||||
"moveDirectly": function (x, y) {
|
||||
// 瞬间移动;x,y为要瞬间移动的点
|
||||
// 返回true代表成功瞬移,false代表没有成功瞬移
|
||||
|
||||
// 判定能否瞬移到该点
|
||||
var ignoreSteps = core.canMoveDirectly(x, y);
|
||||
if (ignoreSteps >= 0) {
|
||||
core.clearMap('hero');
|
||||
// 获得勇士最后的朝向
|
||||
var lastDirection = core.status.route[core.status.route.length - 1];
|
||||
if (['left', 'right', 'up', 'down'].indexOf(lastDirection) >= 0)
|
||||
core.setHeroLoc('direction', lastDirection);
|
||||
// 设置坐标,并绘制
|
||||
core.setHeroLoc('x', x);
|
||||
core.setHeroLoc('y', y);
|
||||
core.drawHero();
|
||||
// 记录录像
|
||||
core.status.route.push("move:" + x + ":" + y);
|
||||
// 统计信息
|
||||
core.status.hero.statistics.moveDirectly++;
|
||||
core.status.hero.statistics.ignoreSteps += ignoreSteps;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
},
|
||||
"ui": {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user