feat: fading path of direct move

This commit is contained in:
qdzwxe 2023-09-26 18:32:10 +08:00
parent 95f3ad0aba
commit 0fed6b09c3
5 changed files with 86 additions and 67 deletions

View File

@ -976,7 +976,11 @@ control.prototype.tryMoveDirectly = function (destX, destY) {
[destX, destY + 1, 'up'],
[destX + 1, destY, 'left']
];
var canMoveDirectlyArray = core.canMoveDirectlyArray(dirs, canMoveArray);
const { ans: canMoveDirectlyArray, route } = core.canMoveDirectlyArray(
dirs,
canMoveArray
);
let { x, y } = core.getHeroLoc();
for (let i = 0; i < dirs.length; ++i) {
var d = dirs[i];
@ -995,6 +999,12 @@ control.prototype.tryMoveDirectly = function (destX, destY) {
if (dir) {
core.moveHero(dir, function () {});
}
mota.game.hook.emit(
'beforeMoveDirectly',
x,
y,
core.routeToMoveSteps(x, y, dx, dy, route)
);
return true;
}
}

View File

@ -880,7 +880,7 @@ maps.prototype._canMoveHero_checkCannotInOut = function (
////// 能否瞬间移动 //////
maps.prototype.canMoveDirectly = function (destX, destY) {
return this.canMoveDirectlyArray([[destX, destY]])[0];
return this.canMoveDirectlyArray([[destX, destY]]).ans[0];
};
maps.prototype.canMoveDirectlyArray = function (locs, canMoveArray) {
@ -954,54 +954,71 @@ maps.prototype._canMoveDirectly_bfs = function (
locs,
number,
ans,
canMoveArray
canMoveArray = this.generateMovableArray()
) {
canMoveArray = canMoveArray || this.generateMovableArray();
var blocksObj = this.getMapBlocksObj();
// 滑冰
var bgMap = this.getBgMapArray();
const blocksObj = this.getMapBlocksObj(),
// 滑冰
bgMap = this.getBgMapArray();
let visited = {},
route = {};
let queue = new PriorityQueue({
comparator: function (a, b) {
return a.depth - b.depth;
}
});
var visited = [],
queue = [];
visited[sx + ',' + sy] = 0;
queue.push(sx + ',' + sy);
route[sx + ',' + sy] = '';
queue.queue({ depth: 0, x: sx, y: sy });
while (queue.length > 0) {
var now = queue.shift().split(','),
x = parseInt(now[0]),
y = parseInt(now[1]);
for (var direction in core.utils.scan) {
while (queue.length != 0) {
const curr = queue.dequeue();
const { depth, x, y } = curr;
const now = x + ',' + y;
for (const direction in core.utils.scan) {
if (!core.inArray(canMoveArray[x][y], direction)) continue;
var nx = x + core.utils.scan[direction].x,
ny = y + core.utils.scan[direction].y,
nindex = nx + ',' + ny;
const nx = x + core.utils.scan[direction].x;
const ny = y + core.utils.scan[direction].y;
const nindex = nx + ',' + ny;
if (visited[nindex]) continue;
if (
nx < 0 ||
nx >= core.bigmap.width ||
ny < 0 ||
ny >= core.bigmap.height ||
route[nx + ',' + ny] != null
)
continue;
if (core.onSki(bgMap[ny][nx])) continue;
if (!this._canMoveDirectly_checkNextPoint(blocksObj, nx, ny))
continue;
// 不可通行
if (core.noPass(nx, ny)) continue;
route[nx + ',' + ny] = direction;
visited[nindex] = visited[now] + 1;
// if (nx == ex && ny == ey) return visited[nindex];
for (var i in ans) {
for (const i in ans) {
if (locs[i][0] == nx && locs[i][1] == ny && ans[i] == null) {
// 不可以绿点为终点
var block = blocksObj[nx + ',' + ny];
const block = blocksObj[nindex];
if (block && !block.disable && block.event.trigger) {
ans[i] = -1;
} else {
ans[i] = visited[nindex];
}
number--;
if (number == 0) return ans;
if (number == 0) return { ans, route };
}
}
queue.push(nindex);
queue.queue({ depth: depth + 1, x: nx, y: ny });
}
}
for (var i in ans) {
if (ans[i] == null) ans[i] = -1;
}
return ans;
return { ans, route };
};
maps.prototype._canMoveDirectly_checkNextPoint = function (blocksObj, x, y) {
@ -1040,7 +1057,17 @@ maps.prototype.automaticRoute = function (destX, destY) {
// BFS找寻最短路径
var route = this._automaticRoute_bfs(startX, startY, destX, destY);
if (route[destX + ',' + destY] == null) return [];
// 路径数组转换
return this.routeToMoveSteps(startX, startY, destX, destY, route);
};
// 路径数组转换
maps.prototype.routeToMoveSteps = function (
startX,
startY,
destX,
destY,
route
) {
var ans = [],
nowX = destX,
nowY = destY;
@ -1083,7 +1110,7 @@ maps.prototype._automaticRoute_bfs = function (startX, startY, destX, destY) {
route[nx + ',' + ny] != null
)
continue;
//
//
if (nx == destX && ny == destY) {
route[nx + ',' + ny] = direction;
break;

View File

@ -177,7 +177,7 @@ var functions_d6ad677b_427a_4623_b50f_a445a3b0ef8a = {
else core.setWeather();
checkLoopMap();
core.deleteCanvas('route2');
// ...可以新增一些其他内容,比如创建个画布在右上角显示什么内容等等
},
afterChangeFloor: function (floorId) {

View File

@ -2,11 +2,11 @@ import { EmitableEvent, EventEmitter } from '../common/eventEmitter';
export interface GameEvent extends EmitableEvent {
reset: () => void;
moveDirectly: (
beforeMoveDirectly: (
x: number,
y: number,
moveSteps: Array<{ direction: string; step: number }>,
ctx: CanvasRenderingContext2D
moveSteps: { direction: Dir; step: number }[],
ctxName: string
) => void;
}

View File

@ -430,55 +430,37 @@ hook.on('reset', () => {
});
});
hook.on('moveDirectly', (x, y, moveSteps, ctx) => {
// 计算绘制区域的宽高并尽可能小的创建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);
// sy = Math.min(sy, t.y * 32);
// dy = Math.max(dy, t.y * 32);
// });
// core.status.automaticRoute.offsetX = sx;
// core.status.automaticRoute.offsetY = sy;
// var ctx = core.createCanvas(
// 'route',
// sx - core.bigmap.offsetX,
// sy - core.bigmap.offsetY,
// dx - sx + 32,
// dy - sy + 32,
// 95
// );
hook.on('beforeMoveDirectly', (x, y, moveSteps, ctxName = 'route2') => {
core.deleteCanvas(ctxName);
const ctx = core.createCanvas(ctxName, 0, 0, 480, 480, 15);
ctx.clearRect(0, 0, 480, 480);
ctx.fillStyle = '#bfbfbf';
ctx.strokeStyle = '#bfbfbf';
ctx.lineWidth = 4;
const scan: { [key: string]: { [key: string]: number } } = {
up: { x: 0, y: -1 },
left: { x: -1, y: 0 },
down: { x: 0, y: 1 },
right: { x: 1, y: 0 }
};
for (let m = 0; m < moveSteps.length; m++) {
if (m == moveSteps.length - 1) {
if (m === 0) ctx.fillRect(x * 32 + 10, y * 32 + 10, 12, 12);
const currDir = moveSteps[m].direction;
x += core.utils.scan[currDir].x;
y += core.utils.scan[currDir].y;
if (m === moveSteps.length - 1)
ctx.fillRect(x * 32 + 10, y * 32 + 10, 12, 12);
} else {
ctx.beginPath();
else {
const nextDir = moveSteps[m + 1].direction;
const cx = x * 32 + 16,
cy = y * 32 + 16;
const currDir = moveSteps[m].direction,
nextDir = moveSteps[m + 1].direction;
ctx.moveTo(cx - scan[currDir].x * 11, cy - scan[currDir].y * 11);
ctx.beginPath();
ctx.moveTo(
cx - core.utils.scan[currDir].x * 11,
cy - core.utils.scan[currDir].y * 11
);
ctx.lineTo(cx, cy);
ctx.lineTo(cx + scan[nextDir].x * 11, cy + scan[nextDir].y * 11);
ctx.lineTo(
cx + core.utils.scan[nextDir].x * 11,
cy + core.utils.scan[nextDir].y * 11
);
ctx.stroke();
x += scan[currDir].x;
y += scan[currDir].y;
}
}
ctx.canvas.style.transition = 'all 1s linear';
ctx.canvas.style.transition = 'all 0.6s ease-in';
nextFrame(() => (ctx.canvas.style.opacity = '0'));
});