From 8a95b1cc8b41bae82eb8c8da76d9e085d7a4ae8e Mon Sep 17 00:00:00 2001 From: qdzwxe Date: Thu, 28 Sep 2023 16:46:25 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E7=9E=AC=E7=A7=BB=E8=B7=AF=E5=BE=84?= =?UTF-8?q?=E6=94=BE=E8=BF=9B=E5=8D=95=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/libs/control.js | 15 ++++--- public/libs/maps.js | 13 +++--- src/core/main/game.ts | 16 ++++++- src/core/main/setting.ts | 43 +++--------------- src/data/settings.json | 3 +- src/plugin/fx/drawRoute.ts | 90 ++++++++++++++++++++++++++++++++++++++ 6 files changed, 128 insertions(+), 52 deletions(-) create mode 100644 src/plugin/fx/drawRoute.ts diff --git a/public/libs/control.js b/public/libs/control.js index c0d724e..e17e178 100644 --- a/public/libs/control.js +++ b/public/libs/control.js @@ -976,7 +976,7 @@ control.prototype.tryMoveDirectly = function (destX, destY) { [destX, destY + 1, 'up'], [destX + 1, destY, 'left'] ]; - const { ans: canMoveDirectlyArray, route } = core.canMoveDirectlyArray( + const { canMoveDirectlyArray, route } = core.canMoveDirectlyArray( dirs, canMoveArray ); @@ -999,12 +999,13 @@ 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) - ); + if (route) + mota.game.hook.emit( + 'beforeMoveDirectly', + x, + y, + core.routeToMoveSteps(x, y, dx, dy, route) + ); return true; } } diff --git a/public/libs/maps.js b/public/libs/maps.js index cf055a8..bf6c2c7 100644 --- a/public/libs/maps.js +++ b/public/libs/maps.js @@ -880,7 +880,7 @@ maps.prototype._canMoveHero_checkCannotInOut = function ( ////// 能否瞬间移动 ////// maps.prototype.canMoveDirectly = function (destX, destY) { - return this.canMoveDirectlyArray([[destX, destY]]).ans[0]; + return this.canMoveDirectlyArray([[destX, destY]]).ignoreSteps[0]; }; maps.prototype.canMoveDirectlyArray = function (locs, canMoveArray) { @@ -891,7 +891,7 @@ maps.prototype.canMoveDirectlyArray = function (locs, canMoveArray) { fromY = core.getHeroLoc('y'); if (!this._canMoveDirectly_checkGlobal()) { for (var i = 0; i < number; ++i) ans.push(-1); - return ans; + return { canMoveDirectlyArray: ans }; } for (var i = 0; i < number; ++i) { if (locs[i][0] == fromX && locs[i][1] == fromY) { @@ -907,14 +907,14 @@ maps.prototype.canMoveDirectlyArray = function (locs, canMoveArray) { number--; } else ans.push(null); } - if (number == 0) return ans; + if (number == 0) return { canMoveDirectlyArray: ans }; // 检查起点事件 if (!this._canMoveDirectly_checkStartPoint(fromX, fromY)) { for (var i in ans) { if (ans[i] == null) ans[i] = -1; } - return ans; + return { canMoveDirectlyArray: ans }; } return this._canMoveDirectly_bfs( @@ -1008,7 +1008,8 @@ maps.prototype._canMoveDirectly_bfs = function ( ans[i] = visited[nindex]; } number--; - if (number == 0) return { ans, route }; + if (number == 0) + return { canMoveDirectlyArray: ans, route }; } } queue.queue({ depth: depth + 1, x: nx, y: ny }); @@ -1018,7 +1019,7 @@ maps.prototype._canMoveDirectly_bfs = function ( for (var i in ans) { if (ans[i] == null) ans[i] = -1; } - return { ans, route }; + return { canMoveDirectlyArray: ans, route }; }; maps.prototype._canMoveDirectly_checkNextPoint = function (blocksObj, x, y) { diff --git a/src/core/main/game.ts b/src/core/main/game.ts index d85c64c..7dd4e2f 100644 --- a/src/core/main/game.ts +++ b/src/core/main/game.ts @@ -1,3 +1,5 @@ +import { drawRoute } from '../../plugin/fx/drawRoute'; +import { nextFrame } from '../../plugin/utils'; import { EmitableEvent, EventEmitter } from '../common/eventEmitter'; export interface GameEvent extends EmitableEvent { @@ -5,9 +7,19 @@ export interface GameEvent extends EmitableEvent { beforeMoveDirectly: ( x: number, y: number, - moveSteps: { direction: Dir; step: number }[], - ctxName: string + moveSteps: DiredLoc[] ) => void; } export const hook = new EventEmitter(); + +hook.on('beforeMoveDirectly', (x, y, moveSteps) => { + // if (!storage.getValue('directMovePath', true)) return; + const paint = [ // 先粗后细 + { color: '#333', width: 6, length: 12, size: 10 }, + { color: '#FFD700', width: 4, length: 14, size: 8 } + ]; + const ctx = drawRoute({ x, y }, moveSteps, paint); + ctx.canvas.style.transition = 'all 0.6s ease-in'; + nextFrame(() => (ctx.canvas.style.opacity = '0')); +}); \ No newline at end of file diff --git a/src/core/main/setting.ts b/src/core/main/setting.ts index 1b19cb4..0c067b3 100644 --- a/src/core/main/setting.ts +++ b/src/core/main/setting.ts @@ -312,6 +312,9 @@ function handleScreenSetting( core.setLocalStorage('smoothView', n); } else if (key === 'criticalGem') { core.setLocalStorage('criticalGem', n); + } else if (key === 'directMoveRoute') { + // 瞬移绘制路径 + core.setLocalStorage('directMoveRoute', n); } } @@ -385,6 +388,7 @@ mainSetting new MotaSetting() .register('paraLight', '野外阴影', true) .register('frag', '打怪特效', true) + .register('directMoveRoute', '瞬移路径', true) ); interface SettingStorage { @@ -400,6 +404,7 @@ interface SettingStorage { betterLoad: boolean; autoScale: boolean; paraLight: boolean; + directMoveRoute: boolean; } const storage = new GameStorage( @@ -420,7 +425,8 @@ loading.once('coreInit', () => { 'utils.betterLoad': !!storage.getValue('betterLoad', true), 'utils.autoScale': !!storage.getValue('autoScale', true), 'fx.paraLight': !!storage.getValue('paraLight', true), - 'fx.frag': !!storage.getValue('frag', true) + 'fx.frag': !!storage.getValue('frag', true), + 'fx.directMoveRoute': !!storage.getValue('directMoveRoute', true) }); }); @@ -429,38 +435,3 @@ hook.on('reset', () => { 'action.autoSkill': flags.autoSkill ?? true }); }); - -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; - for (let m = 0; m < moveSteps.length; m++) { - 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 { - const nextDir = moveSteps[m + 1].direction; - const cx = x * 32 + 16, - cy = y * 32 + 16; - 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 + core.utils.scan[nextDir].x * 11, - cy + core.utils.scan[nextDir].y * 11 - ); - ctx.stroke(); - } - } - ctx.canvas.style.transition = 'all 0.6s ease-in'; - nextFrame(() => (ctx.canvas.style.opacity = '0')); -}); diff --git a/src/data/settings.json b/src/data/settings.json index ccf6533..581c28c 100644 --- a/src/data/settings.json +++ b/src/data/settings.json @@ -60,6 +60,7 @@ "paraLight": [ "是否开启野外的平行光阴影,在野外将会显示平行光阴影,模拟太阳光,拥有不错的视觉效果" ], - "frag": ["开启后,在打败怪物后会触发怪物碎裂特效。"] + "frag": ["开启后,在打败怪物后会触发怪物碎裂特效。"], + "directMoveRoute": ["开启后,瞬移时能显示对应行走路径。"] } } diff --git a/src/plugin/fx/drawRoute.ts b/src/plugin/fx/drawRoute.ts new file mode 100644 index 0000000..ef74676 --- /dev/null +++ b/src/plugin/fx/drawRoute.ts @@ -0,0 +1,90 @@ +interface DrawRouteConfig { + /** 颜色 */ + color: string; + /** 绘制线宽 */ + width: number; + /** 绘制线长 */ + length: number; + /** 绘制起点与终点的正方形大小 */ + size: number; +} + +/** + * 绘制瞬移路径 + * @param loc 起点坐标 + * @param moveSteps 移动方向与步数 + * @param config 绘制选项 + * @returns 画布上下文 + */ +export function drawRoute( + loc: Loc, + moveSteps: DiredLoc[], + config: DrawRouteConfig[] +): CanvasRenderingContext2D { + // 计算绘制区域的宽高,并尽可能小的创建route2层 + let sx = Math.min(core.bigmap.width * 32, loc.x * 32), + sy = Math.min(core.bigmap.height * 32, loc.y * 32), + dx = loc.x * 32, + dy = loc.y * 32; + moveSteps.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.deleteCanvas('route2'); + const ctx = core.createCanvas( + 'route2', + sx - core.bigmap.offsetX, + sy - core.bigmap.offsetY, + dx - sx + 32, + dy - sy + 32, + 15 + ); + // 单独画起点 + for (const p of config) { + ctx.fillStyle = p.color; + ctx.fillRect( + loc.x * 32 + 16 - p.size / 2 - sx, + loc.y * 32 + 16 - p.size / 2 - sy, + p.size, + p.size + ); + } + for (let m = 0; m < moveSteps.length; m++) { + const currDir = moveSteps[m].direction; + loc.x += core.utils.scan[currDir].x; + loc.y += core.utils.scan[currDir].y; + for (const p of config) { + if (m === moveSteps.length - 1) { + // 终点 + ctx.fillStyle = p.color; + ctx.fillRect( + loc.x * 32 + 16 - p.size / 2 - sx, + loc.y * 32 + 16 - p.size / 2 - sy, + p.size, + p.size + ); + } else { + const nextDir = moveSteps[m + 1].direction; + const cx = loc.x * 32 + 16 - sx, + cy = loc.y * 32 + 16 - sy; + ctx.strokeStyle = p.color; + ctx.lineWidth = p.width; + const position = (32 - p.length) / 2; + ctx.beginPath(); + ctx.moveTo( + cx - core.utils.scan[currDir].x * position, + cy - core.utils.scan[currDir].y * position + ); + ctx.lineTo(cx, cy); + ctx.lineTo( + cx + core.utils.scan[nextDir].x * position, + cy + core.utils.scan[nextDir].y * position + ); + ctx.stroke(); + } + } + } + return ctx; +}