feat: 点击地图的路径显示

This commit is contained in:
unanmed 2025-07-12 20:16:08 +08:00
parent 13adf00d07
commit fe7e765e95
4 changed files with 88 additions and 51 deletions

View File

@ -1,5 +1,12 @@
import { LayerShadowExtends } from '../legacy/shadow'; import { LayerShadowExtends } from '../legacy/shadow';
import { Props, Font, IActionEvent } from '@motajs/render'; import {
Props,
Font,
IActionEvent,
MotaOffscreenCanvas2D,
Sprite,
onTick
} from '@motajs/render';
import { WeatherController } from '../../weather'; import { WeatherController } from '../../weather';
import { defineComponent, onMounted, onUnmounted, reactive, ref } from 'vue'; import { defineComponent, onMounted, onUnmounted, reactive, ref } from 'vue';
import { Textbox, Tip } from '../components'; import { Textbox, Tip } from '../components';
@ -38,8 +45,10 @@ import {
LayerDoorAnimate, LayerDoorAnimate,
LayerGroup LayerGroup
} from '../elements'; } from '../elements';
import { isNil } from 'lodash-es';
const MainScene = defineComponent(() => { const MainScene = defineComponent(() => {
//#region 基本定义
const layerGroupExtends: ILayerGroupRenderExtends[] = [ const layerGroupExtends: ILayerGroupRenderExtends[] = [
new FloorDamageExtends(), new FloorDamageExtends(),
new FloorItemDetail(), new FloorItemDetail(),
@ -54,10 +63,6 @@ const MainScene = defineComponent(() => {
new LayerDoorAnimate(), new LayerDoorAnimate(),
new LayerShadowExtends() new LayerShadowExtends()
]; ];
const mapDrawProps: Props<'container'> = {
width: core._PX_,
height: core._PY_
};
const mainTextboxProps: Props<typeof Textbox> = { const mainTextboxProps: Props<typeof Textbox> = {
text: '', text: '',
hidden: true, hidden: true,
@ -78,6 +83,11 @@ const MainScene = defineComponent(() => {
const locked = ref(false); const locked = ref(false);
const weather = new WeatherController('main'); const weather = new WeatherController('main');
const loaded = ref(true);
onLoaded(() => {
loaded.value = true;
});
onMounted(() => { onMounted(() => {
weather.bind(map.value); weather.bind(map.value);
}); });
@ -116,6 +126,7 @@ const MainScene = defineComponent(() => {
night: 0 night: 0
}); });
//#region 状态更新
const updateStatus = () => { const updateStatus = () => {
if (!core.status || !core.status.hero || !core.status.floorId) return; if (!core.status || !core.status.hero || !core.status.floorId) return;
hideStatus.value = core.getFlag('hideStatusBar', false); hideStatus.value = core.getFlag('hideStatusBar', false);
@ -169,10 +180,62 @@ const MainScene = defineComponent(() => {
locked.value = core.status.lockControl; locked.value = core.status.lockControl;
}; };
// 监听状态栏更新事件
hook.on('statusBarUpdate', updateStatus);
hook.on('statusBarUpdate', updateDataFallback);
onUnmounted(() => {
hook.off('statusBarUpdate', updateStatus);
hook.off('statusBarUpdate', updateDataFallback);
});
//#region sprite 渲染
let lastLength = 0;
onTick(() => {
const len = core.status.stepPostfix?.length ?? 0;
if (len !== lastLength) {
mapMiscSprite.value?.update();
lastLength = len;
}
});
const mapMiscSprite = ref<Sprite>();
const renderMapMisc = (canvas: MotaOffscreenCanvas2D) => {
const step = core.status.stepPostfix;
if (!step) return;
const ctx = canvas.ctx;
ctx.save();
ctx.fillStyle = '#fff';
step.forEach(({ x, y, direction }) => {
ctx.fillRect(x * 32 + 12, y * 32 + 12, 8, 8);
if (!isNil(direction)) {
switch (direction) {
case 'down':
ctx.fillRect(x * 32 + 12, y * 32 + 20, 8, 12);
break;
case 'left':
ctx.fillRect(x * 32, y * 32 + 12, 12, 8);
break;
case 'right':
ctx.fillRect(x * 32 + 20, y * 32 + 12, 12, 8);
break;
case 'up':
ctx.fillRect(x * 32 + 12, y * 32, 8, 12);
break;
}
}
});
ctx.restore();
};
//#region 交互监听
/** /**
* registerAction fallback * registerAction fallback
*/ */
const clickData = (ev: IActionEvent) => { const clickMap = (ev: IActionEvent) => {
const bx = Math.floor(ev.offsetX / 32); const bx = Math.floor(ev.offsetX / 32);
const by = Math.floor(ev.offsetY / 32); const by = Math.floor(ev.offsetY / 32);
core.doRegisteredAction('onup', bx, by, ev.offsetX, ev.offsetY); core.doRegisteredAction('onup', bx, by, ev.offsetX, ev.offsetY);
@ -181,7 +244,7 @@ const MainScene = defineComponent(() => {
/** /**
* registerAction fallback * registerAction fallback
*/ */
const downData = (ev: IActionEvent) => { const downMap = (ev: IActionEvent) => {
const bx = Math.floor(ev.offsetX / 32); const bx = Math.floor(ev.offsetX / 32);
const by = Math.floor(ev.offsetY / 32); const by = Math.floor(ev.offsetY / 32);
core.doRegisteredAction('ondown', bx, by, ev.offsetX, ev.offsetY); core.doRegisteredAction('ondown', bx, by, ev.offsetX, ev.offsetY);
@ -190,25 +253,12 @@ const MainScene = defineComponent(() => {
/** /**
* registerAction fallback * registerAction fallback
*/ */
const moveData = (ev: IActionEvent) => { const moveMap = (ev: IActionEvent) => {
const bx = Math.floor(ev.offsetX / 32); const bx = Math.floor(ev.offsetX / 32);
const by = Math.floor(ev.offsetY / 32); const by = Math.floor(ev.offsetY / 32);
core.doRegisteredAction('onmove', bx, by, ev.offsetX, ev.offsetY); core.doRegisteredAction('onmove', bx, by, ev.offsetX, ev.offsetY);
}; };
const loaded = ref(true);
onLoaded(() => {
loaded.value = true;
});
hook.on('statusBarUpdate', updateStatus);
hook.on('statusBarUpdate', updateDataFallback);
onUnmounted(() => {
hook.off('statusBarUpdate', updateStatus);
hook.off('statusBarUpdate', updateDataFallback);
});
return () => ( return () => (
<container id="main-scene" width={MAIN_WIDTH} height={MAIN_HEIGHT}> <container id="main-scene" width={MAIN_WIDTH} height={MAIN_HEIGHT}>
{loaded.value && ( {loaded.value && (
@ -219,7 +269,14 @@ const MainScene = defineComponent(() => {
></LeftStatusBar> ></LeftStatusBar>
)} )}
<g-line line={[180, 0, 180, 480]} lineWidth={1} /> <g-line line={[180, 0, 180, 480]} lineWidth={1} />
<container id="map-draw" {...mapDrawProps} x={180} zIndex={10}> <container
id="map-draw"
loc={[180, 0, 480, 480]}
zIndex={10}
onClick={clickMap}
onDown={downMap}
onMove={moveMap}
>
<layer-group id="layer-main" ex={layerGroupExtends} ref={map}> <layer-group id="layer-main" ex={layerGroupExtends} ref={map}>
<layer layer="bg" zIndex={10}></layer> <layer layer="bg" zIndex={10}></layer>
<layer layer="bg2" zIndex={20}></layer> <layer layer="bg2" zIndex={20}></layer>
@ -238,13 +295,11 @@ const MainScene = defineComponent(() => {
corner={16} corner={16}
/> />
<sprite <sprite
nocache noevent
zIndex={170}
hidden={!locked.value}
loc={[0, 0, 480, 480]} loc={[0, 0, 480, 480]}
onClick={clickData} ref={mapMiscSprite}
onDown={downData} zIndex={170}
onMove={moveData} render={renderMapMisc}
/> />
</container> </container>
<g-line line={[180 + 480, 0, 180 + 480, 480]} lineWidth={1} /> <g-line line={[180 + 480, 0, 180 + 480, 480]} lineWidth={1} />

View File

@ -576,7 +576,6 @@ actions.prototype._sys_ondown_lockControl = function (x, y, px, py) {
actions.prototype._sys_ondown = function (x, y, px, py) { actions.prototype._sys_ondown = function (x, y, px, py) {
if (core.status.lockControl) return false; if (core.status.lockControl) return false;
core.status.downTime = new Date(); core.status.downTime = new Date();
core.deleteCanvas('route');
var pos = { var pos = {
x: Math.floor((px + core.bigmap.offsetX) / 32), x: Math.floor((px + core.bigmap.offsetX) / 32),
y: Math.floor((py + core.bigmap.offsetY) / 32) y: Math.floor((py + core.bigmap.offsetY) / 32)
@ -591,14 +590,6 @@ actions.prototype._sys_ondown = function (x, y, px, py) {
core.status.stepPostfix = []; core.status.stepPostfix = [];
core.status.stepPostfix.push(pos); core.status.stepPostfix.push(pos);
core.fillRect(
'ui',
pos.x * 32 + 12 - core.bigmap.offsetX,
pos.y * 32 + 12 - core.bigmap.offsetY,
8,
8,
'#bfbfbf'
);
clearTimeout(core.timeout.onDownTimeout); clearTimeout(core.timeout.onDownTimeout);
core.timeout.onDownTimeout = null; core.timeout.onDownTimeout = null;
@ -688,14 +679,6 @@ actions.prototype._sys_onmove = function (x, y, px, py) {
pos.x += pos0.x; pos.x += pos0.x;
pos.y += pos0.y; pos.y += pos0.y;
core.status.stepPostfix.push(pos); core.status.stepPostfix.push(pos);
core.fillRect(
'ui',
pos.x * 32 + 12 - core.bigmap.offsetX,
pos.y * 32 + 12 - core.bigmap.offsetY,
8,
8,
'#bfbfbf'
);
} }
} }
return true; return true;
@ -736,9 +719,6 @@ actions.prototype._sys_onup = function (x, y, px, py) {
var posx = core.status.stepPostfix[0].x; var posx = core.status.stepPostfix[0].x;
var posy = core.status.stepPostfix[0].y; var posy = core.status.stepPostfix[0].y;
core.status.stepPostfix = []; core.status.stepPostfix = [];
if (!core.status.lockControl) {
core.clearMap('ui');
}
// 长按 // 长按
if ( if (

View File

@ -765,6 +765,8 @@ interface GameStatus extends InitGameStatus {
* core.status.hero.atk就是当前勇士的攻击力数值 * core.status.hero.atk就是当前勇士的攻击力数值
*/ */
hero: HeroStatus; hero: HeroStatus;
stepPostfix?: DiredLoc[];
} }
interface Follower { interface Follower {

View File

@ -1,11 +1,11 @@
import { defineConfig } from 'vite'; import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue'; import vue from '@vitejs/plugin-vue';
import components from 'unplugin-vue-components/vite'; import components from 'unplugin-vue-components/vite';
import vuejsx from '@vitejs/plugin-vue-jsx' import vuejsx from '@vitejs/plugin-vue-jsx';
import { AntDesignVueResolver } from 'unplugin-vue-components/resolvers'; import { AntDesignVueResolver } from 'unplugin-vue-components/resolvers';
import path from 'path'; import path from 'path';
import postcssPresetEnv from 'postcss-preset-env'; import postcssPresetEnv from 'postcss-preset-env';
import * as glob from 'glob' import * as glob from 'glob';
const FSHOST = 'http://127.0.0.1:3000/'; const FSHOST = 'http://127.0.0.1:3000/';
@ -13,7 +13,7 @@ const custom = [
'container', 'image', 'sprite', 'shader', 'text', 'comment', 'custom', 'container', 'image', 'sprite', 'shader', 'text', 'comment', 'custom',
'layer', 'layer-group', 'animate', 'damage', 'graphics', 'icon', 'winskin', 'layer', 'layer-group', 'animate', 'damage', 'graphics', 'icon', 'winskin',
'container-custom' 'container-custom'
] ];
const aliases = glob.sync('packages/*/src').map((srcPath) => { const aliases = glob.sync('packages/*/src').map((srcPath) => {
const packageName = path.basename(path.dirname(srcPath)); const packageName = path.basename(path.dirname(srcPath));