From a3826bfa6a7b45e89c9336edd2c5dca7de0a5a1b Mon Sep 17 00:00:00 2001 From: unanmed <1319491857@qq.com> Date: Fri, 18 Sep 2026 15:55:02 +0800 Subject: [PATCH] refactor(04-03): rebind hero renderer to IHeroLocation and existing hooks - manager.ts / types.ts: heroMap, addHero, removeHero keyed by IHeroLocation - hero.ts: bind IHeroLocation, read getCurrentFaceDirection, use ObjectAnimDirection - MapHeroHook subscribes IHeroLocationHooks / IObjectMoverHooks with existing member names (D-21) - IMapHeroRenderer drops the 8 external drive members per D-20; D-18 / D-22 members preserved - hero.image read converged to one minimal compile bridge annotated for D-18 --- .../src/render/map/extension/hero.ts | 125 +++++++++++------- .../src/render/map/extension/manager.ts | 13 +- .../src/render/map/extension/types.ts | 71 +--------- 3 files changed, 88 insertions(+), 121 deletions(-) diff --git a/packages-user/client-modules/src/render/map/extension/hero.ts b/packages-user/client-modules/src/render/map/extension/hero.ts index dc0c003..af8c0a7 100644 --- a/packages-user/client-modules/src/render/map/extension/hero.ts +++ b/packages-user/client-modules/src/render/map/extension/hero.ts @@ -2,15 +2,14 @@ import { degradeFace, FaceDirection, getFaceMovement, - // @ts-expect-error 需要重构 - HeroAnimateDirection, - // @ts-expect-error 需要重构 - IHeroMoveController, - // @ts-expect-error 需要重构 - IHeroMoveControllerHooks, - nextFaceDirection + IObjectMover, + IObjectMoverHooks, + nextFaceDirection, + ObjectAnimDirection, + ObjectMoveStep, + ObjectMoveType } from '@user/data-common'; -import { IMapLayer } from '@user/data-base'; +import { IHeroLocation, IHeroLocationHooks, IMapLayer } from '@user/data-base'; import { IMapRenderer, IMapRendererTicker, IMovingBlock } from '../types'; import { isNil } from 'lodash-es'; import { IHookController, logger } from '@motajs/common'; @@ -50,15 +49,17 @@ interface HeroRenderEntity { /** 移动的 `Promise`,移动完成时兑现,如果停止,则一直是兑现状态 */ promise: Promise; /** 勇士移动的动画方向 */ - animateDirection: HeroAnimateDirection; + animateDirection: ObjectAnimDirection; } export class MapHeroRenderer implements IMapHeroRenderer { private static readonly splitter: ITextureSplitter = new TextureRowSplitter(); - /** 勇士钩子 */ - readonly controller: IHookController; + /** 勇士位置钩子 */ + readonly locationController: IHookController; + /** 勇士移动钩子 */ + readonly moverController: IHookController>; /** 勇士每个朝向的贴图对象 */ readonly textureMap: Map = new Map(); /** 勇士渲染实体,与 `entities[0]` 同引用 */ @@ -76,17 +77,20 @@ export class MapHeroRenderer implements IMapHeroRenderer { constructor( readonly renderer: IMapRenderer, readonly layer: IMapLayer, - readonly hero: IHeroMoveController + readonly hero: IHeroLocation ) { - this.controller = hero.addHook(new MapHeroHook(this)); - this.controller.load(); + const hook = new MapHeroHook(this); + this.locationController = hero.addHook(hook); + this.locationController.load(); + this.moverController = hero.mover.addHook(hook); + this.moverController.load(); const moving = this.addHeroMoving(renderer, layer, hero); const heroEntity: HeroRenderEntity = { block: moving, identifier: '', targetX: hero.x, targetY: hero.y, - direction: hero.direction, + direction: hero.getCurrentFaceDirection(), nextDirection: FaceDirection.Unknown, moving: false, animating: false, @@ -94,7 +98,7 @@ export class MapHeroRenderer implements IMapHeroRenderer { lastAnimateTime: 0, animateFrame: 0, promise: Promise.resolve(), - animateDirection: HeroAnimateDirection.Forward + animateDirection: ObjectAnimDirection.Forward }; this.heroEntity = heroEntity; this.entities.push(heroEntity); @@ -110,19 +114,23 @@ export class MapHeroRenderer implements IMapHeroRenderer { private addHeroMoving( renderer: IMapRenderer, layer: IMapLayer, - hero: IHeroMoveController + hero: IHeroLocation ) { - if (isNil(hero.image)) { + // @ts-expect-error 需要重构(贴图别名来源属 D-18,待用户先改数据端后处理) + const imageAlias = hero.image; + if (isNil(imageAlias)) { logger.warn(88); return renderer.addMovingBlock(layer, 0, hero.x, hero.y); } - const image = this.renderer.manager.getImageByAlias(hero.image); + const image = this.renderer.manager.getImageByAlias(imageAlias); if (!image) { - logger.warn(89, hero.image); + logger.warn(89, imageAlias); return renderer.addMovingBlock(layer, 0, hero.x, hero.y); } this.updateHeroTexture(image); - const tex = this.textureMap.get(degradeFace(hero.direction)); + const tex = this.textureMap.get( + degradeFace(hero.getCurrentFaceDirection()) + ); if (!tex) { return renderer.addMovingBlock(layer, 0, hero.x, hero.y); } @@ -167,7 +175,7 @@ export class MapHeroRenderer implements IMapHeroRenderer { if (v.animating) { const dt = time - v.lastAnimateTime; if (dt > v.animateInterval) { - if (v.animateDirection === HeroAnimateDirection.Forward) { + if (v.animateDirection === ObjectAnimDirection.Forward) { v.animateFrame++; } else { v.animateFrame--; @@ -190,7 +198,9 @@ export class MapHeroRenderer implements IMapHeroRenderer { setImage(image: ITexture): void { this.updateHeroTexture(image); - const tex = this.textureMap.get(degradeFace(this.hero.direction)); + const tex = this.textureMap.get( + degradeFace(this.hero.getCurrentFaceDirection()) + ); if (!tex) return; this.heroEntity.block.setTexture(tex); } @@ -369,7 +379,7 @@ export class MapHeroRenderer implements IMapHeroRenderer { lastAnimateTime: 0, animateFrame: 0, promise: Promise.resolve(), - animateDirection: HeroAnimateDirection.Forward + animateDirection: ObjectAnimDirection.Forward }; moving.useSpecifiedFrame(0); this.entities.push(entity); @@ -434,7 +444,7 @@ export class MapHeroRenderer implements IMapHeroRenderer { follower.block.setAlpha(alpha); } - setHeroAnimateDirection(direction: HeroAnimateDirection): void { + setHeroAnimateDirection(direction: ObjectAnimDirection): void { this.heroEntity.animateDirection = direction; } @@ -450,11 +460,14 @@ export class MapHeroRenderer implements IMapHeroRenderer { } destroy() { - this.controller.unload(); + this.locationController.unload(); + this.moverController.unload(); } } -class MapHeroHook implements Partial { +class MapHeroHook implements Partial< + IHeroLocationHooks & IObjectMoverHooks +> { constructor(readonly hero: MapHeroRenderer) {} onSetImage(image: ImageIds): void { @@ -466,33 +479,55 @@ class MapHeroHook implements Partial { this.hero.setImage(texture); } - onSetPosition(x: number, y: number): void { + onSetPos(x: number, y: number): void { + if (this.hero.hero.mover.moving) return; this.hero.setPosition(x, y); } - onTurnHero(direction: FaceDirection): void { - this.hero.turn(direction); - } - - onStartMove(): void { + async onMoveStart(): Promise { this.hero.startMove(); } - onMoveHero(direction: FaceDirection, time: number): Promise { - return this.hero.move(direction, time); + async onMoveEnd(): Promise { + await this.hero.waitMoveEnd(); } - onEndMove(): Promise { - return this.hero.waitMoveEnd(); - } - - onJumpHero( - x: number, - y: number, - time: number, - waitFollower: boolean + async onStepEnd( + _code: number, + step: Readonly, + tile: IHeroLocation, + mover: IObjectMover ): Promise { - return this.hero.jumpTo(x, y, time, waitFollower); + this.hero.setHeroAnimateDirection(mover.currAnimDir); + switch (step.type) { + case ObjectMoveType.Dir: + return this.hero.move(step.move, mover.currentSpeed); + case ObjectMoveType.DirFace: + this.hero.turn(step.face); + return this.hero.move(step.move, mover.currentSpeed); + case ObjectMoveType.Special: + return this.hero.move(mover.moveDirection, mover.currentSpeed); + case ObjectMoveType.Face: + this.hero.turn(step.value); + break; + case ObjectMoveType.Teleport: + this.hero.setPosition(tile.x, tile.y); + break; + case ObjectMoveType.Jump: + return this.hero.jumpTo( + tile.x, + tile.y, + mover.currentSpeed, + false + ); + case ObjectMoveType.AnimDir: + case ObjectMoveType.Speed: + break; + } + } + + onSetFaceDir(dir: FaceDirection): void { + this.hero.turn(dir); } onSetAlpha(alpha: number): void { diff --git a/packages-user/client-modules/src/render/map/extension/manager.ts b/packages-user/client-modules/src/render/map/extension/manager.ts index 46825aa..a261e8a 100644 --- a/packages-user/client-modules/src/render/map/extension/manager.ts +++ b/packages-user/client-modules/src/render/map/extension/manager.ts @@ -1,6 +1,4 @@ -// @ts-expect-error 需要重构 -import { IHeroMoveController } from '@user/data-base'; -import { IMapLayer } from '@user/data-base'; +import { IHeroLocation, IMapLayer } from '@user/data-base'; import { IMapDoorRenderer, IMapExtensionManager, @@ -15,7 +13,7 @@ import { IOnMapTextRenderer } from './types'; export class MapExtensionManager implements IMapExtensionManager { /** 勇士状态至勇士渲染器的映射 */ - readonly heroMap: Map = new Map(); + readonly heroMap: Map = new Map(); /** 地图图层到门渲染器的映射 */ readonly doorMap: Map = new Map(); /** 单例的文字渲染拓展(独立图层) */ @@ -23,10 +21,7 @@ export class MapExtensionManager implements IMapExtensionManager { constructor(readonly renderer: IMapRenderer) {} - addHero( - state: IHeroMoveController, - layer: IMapLayer - ): IMapHeroRenderer | null { + addHero(state: IHeroLocation, layer: IMapLayer): IMapHeroRenderer | null { if (this.heroMap.has(state)) { logger.error(45, 'hero renderer'); return null; @@ -36,7 +31,7 @@ export class MapExtensionManager implements IMapExtensionManager { return heroRenderer; } - removeHero(state: IHeroMoveController): void { + removeHero(state: IHeroLocation): void { const renderer = this.heroMap.get(state); if (!renderer) return; renderer.destroy(); diff --git a/packages-user/client-modules/src/render/map/extension/types.ts b/packages-user/client-modules/src/render/map/extension/types.ts index ffeb09a..a72b983 100644 --- a/packages-user/client-modules/src/render/map/extension/types.ts +++ b/packages-user/client-modules/src/render/map/extension/types.ts @@ -1,18 +1,11 @@ import { ITexture, Font } from '@motajs/render'; -import { - FaceDirection, - // @ts-expect-error 需要重构 - HeroAnimateDirection, - // @ts-expect-error 需要重构 - IHeroMoveController -} from '@user/data-common'; -import { IMapLayer } from '@user/data-base'; +import { IHeroLocation, IMapLayer } from '@user/data-base'; import { IMapRenderResult } from '../types'; export interface IMapExtensionManager { /** 勇士状态至勇士渲染器的映射 */ - readonly heroMap: Map; + readonly heroMap: Map; /** 地图图层到门渲染器的映射 */ readonly doorMap: Map; /** 单例的文字渲染拓展(独立图层) */ @@ -23,16 +16,13 @@ export interface IMapExtensionManager { * @param state 勇士状态 * @param layer 勇士所在图层 */ - addHero( - state: IHeroMoveController, - layer: IMapLayer - ): IMapHeroRenderer | null; + addHero(state: IHeroLocation, layer: IMapLayer): IMapHeroRenderer | null; /** * 移除勇士渲染拓展 * @param state 勇士状态 */ - removeHero(state: IHeroMoveController): void; + removeHero(state: IHeroLocation): void; /** * 添加开门动画拓展 @@ -86,47 +76,6 @@ export interface IMapHeroRenderer { */ removeAllFollowers(): void; - /** - * 设置勇士位置 - */ - setPosition(x: number, y: number): void; - - /** - * 开始移动,在移动前需要调用此方法切换勇士状态 - */ - startMove(): void; - - /** - * 等待勇士移动停止后,将移动状态切换为停止 - * @param waitFollower 是否也等待跟随者移动结束 - */ - waitMoveEnd(waitFollower: boolean): Promise; - - /** - * 立刻停止移动,勇士和跟随者瞬移到目标点 - */ - stopMove(): void; - - /** - * 勇士朝某个方向移动 - * @param direction 移动方向 - */ - move(direction: FaceDirection, time: number): Promise; - - /** - * 跳跃勇士至目标点 - * @param x 目标点横坐标 - * @param y 目标点纵坐标 - * @param time 跳跃时长 - * @param waitFollower 是否等待跟随者也跳跃完毕 - */ - jumpTo( - x: number, - y: number, - time: number, - waitFollower: boolean - ): Promise; - /** * 设置勇士不透明度 * @param alpha 不透明度 @@ -140,18 +89,6 @@ export interface IMapHeroRenderer { */ setFollowerAlpha(identifier: string, alpha: number): void; - /** - * 设置勇士移动的动画播放方向,一般后退会使用反向播放的动画,前进使用正向播放的动画 - * @param direction 动画方向 - */ - setHeroAnimateDirection(direction: HeroAnimateDirection): void; - - /** - * 设置勇士朝向 - * @param direction 勇士朝向,不填表示顺时针旋转 - */ - turn(direction?: FaceDirection): void; - /** * 摧毁这个勇士渲染拓展,释放相关资源 */