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 { Props, Font, IActionEvent } from '@motajs/render';
import {
Props,
Font,
IActionEvent,
MotaOffscreenCanvas2D,
Sprite,
onTick
} from '@motajs/render';
import { WeatherController } from '../../weather';
import { defineComponent, onMounted, onUnmounted, reactive, ref } from 'vue';
import { Textbox, Tip } from '../components';
@ -38,8 +45,10 @@ import {
LayerDoorAnimate,
LayerGroup
} from '../elements';
import { isNil } from 'lodash-es';
const MainScene = defineComponent(() => {
//#region 基本定义
const layerGroupExtends: ILayerGroupRenderExtends[] = [
new FloorDamageExtends(),
new FloorItemDetail(),
@ -54,10 +63,6 @@ const MainScene = defineComponent(() => {
new LayerDoorAnimate(),
new LayerShadowExtends()
];
const mapDrawProps: Props<'container'> = {
width: core._PX_,
height: core._PY_
};
const mainTextboxProps: Props<typeof Textbox> = {
text: '',
hidden: true,
@ -78,6 +83,11 @@ const MainScene = defineComponent(() => {
const locked = ref(false);
const weather = new WeatherController('main');
const loaded = ref(true);
onLoaded(() => {
loaded.value = true;
});
onMounted(() => {
weather.bind(map.value);
});
@ -116,6 +126,7 @@ const MainScene = defineComponent(() => {
night: 0
});
//#region 状态更新
const updateStatus = () => {
if (!core.status || !core.status.hero || !core.status.floorId) return;
hideStatus.value = core.getFlag('hideStatusBar', false);
@ -169,10 +180,62 @@ const MainScene = defineComponent(() => {
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
*/
const clickData = (ev: IActionEvent) => {
const clickMap = (ev: IActionEvent) => {
const bx = Math.floor(ev.offsetX / 32);
const by = Math.floor(ev.offsetY / 32);
core.doRegisteredAction('onup', bx, by, ev.offsetX, ev.offsetY);
@ -181,7 +244,7 @@ const MainScene = defineComponent(() => {
/**
* registerAction fallback
*/
const downData = (ev: IActionEvent) => {
const downMap = (ev: IActionEvent) => {
const bx = Math.floor(ev.offsetX / 32);
const by = Math.floor(ev.offsetY / 32);
core.doRegisteredAction('ondown', bx, by, ev.offsetX, ev.offsetY);
@ -190,25 +253,12 @@ const MainScene = defineComponent(() => {
/**
* registerAction fallback
*/
const moveData = (ev: IActionEvent) => {
const moveMap = (ev: IActionEvent) => {
const bx = Math.floor(ev.offsetX / 32);
const by = Math.floor(ev.offsetY / 32);
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 () => (
<container id="main-scene" width={MAIN_WIDTH} height={MAIN_HEIGHT}>
{loaded.value && (
@ -219,7 +269,14 @@ const MainScene = defineComponent(() => {
></LeftStatusBar>
)}
<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 layer="bg" zIndex={10}></layer>
<layer layer="bg2" zIndex={20}></layer>
@ -238,13 +295,11 @@ const MainScene = defineComponent(() => {
corner={16}
/>
<sprite
nocache
zIndex={170}
hidden={!locked.value}
noevent
loc={[0, 0, 480, 480]}
onClick={clickData}
onDown={downData}
onMove={moveData}
ref={mapMiscSprite}
zIndex={170}
render={renderMapMisc}
/>
</container>
<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) {
if (core.status.lockControl) return false;
core.status.downTime = new Date();
core.deleteCanvas('route');
var pos = {
x: Math.floor((px + core.bigmap.offsetX) / 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.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);
core.timeout.onDownTimeout = null;
@ -688,14 +679,6 @@ actions.prototype._sys_onmove = function (x, y, px, py) {
pos.x += pos0.x;
pos.y += pos0.y;
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;
@ -736,9 +719,6 @@ actions.prototype._sys_onup = function (x, y, px, py) {
var posx = core.status.stepPostfix[0].x;
var posy = core.status.stepPostfix[0].y;
core.status.stepPostfix = [];
if (!core.status.lockControl) {
core.clearMap('ui');
}
// 长按
if (

View File

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

View File

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