mirror of
https://github.com/motajs/template.git
synced 2026-06-11 00:31:11 +08:00
refactor: 修改 mover 名称
This commit is contained in:
parent
2c89a4ac37
commit
c48f91c25c
4
dev.md
4
dev.md
@ -98,7 +98,7 @@
|
||||
- 只进行必要的非空判断,非必要时直接使用非空断言 `!`。
|
||||
- 除非参数要求传入函数等情况,不建议在函数内定义局部函数。
|
||||
- 语句尽量不换行,除非必要,尤其注意三元运算符与 `private readonly` 类成员。
|
||||
- 任何时候都不应该写 `getter` 和 `setter`。
|
||||
- 一般不建议写 `getter` 和 `setter`,但某些场景下还是可以使用的。
|
||||
|
||||
## 双端分离
|
||||
|
||||
@ -133,4 +133,4 @@
|
||||
| `@user/data-common | Layer 0 | 公共层,定义 `IDataCommon` 及公共无依赖接口 |
|
||||
| `@user/data-base` | Layer 1 | 数据层,定义 `IStateBase` 及可存档游戏数据(地图、怪物、玩家属性等) |
|
||||
| `@user/data-system` | Layer 2 | 执行层,定义 `ICoreState`,依赖数据层实现玩家控制、战斗计算等影响游戏进程的动作 |
|
||||
| `@user/data-state` | — | 数据端的顶层模块,指导 Layer 2 的执行行为,不直接参与执行 |
|
||||
| `@user/data-state` | Layer 3 | 数据端的顶层模块,一般仅用于初始化以及仅供渲染端调用的顶层模块 |
|
||||
|
||||
@ -3,8 +3,8 @@ import {
|
||||
FaceDirection,
|
||||
getFaceMovement,
|
||||
HeroAnimateDirection,
|
||||
IHeroMover,
|
||||
IHeroMovingHooks,
|
||||
IHeroMoveController,
|
||||
IHeroMoveControllerHooks,
|
||||
nextFaceDirection
|
||||
} from '@user/data-base';
|
||||
import { IMapLayer } from '@user/data-base';
|
||||
@ -55,7 +55,7 @@ export class MapHeroRenderer implements IMapHeroRenderer {
|
||||
new TextureRowSplitter();
|
||||
|
||||
/** 勇士钩子 */
|
||||
readonly controller: IHookController<IHeroMovingHooks>;
|
||||
readonly controller: IHookController<IHeroMoveControllerHooks>;
|
||||
/** 勇士每个朝向的贴图对象 */
|
||||
readonly textureMap: Map<FaceDirection, IMaterialFramedData> = new Map();
|
||||
/** 勇士渲染实体,与 `entities[0]` 同引用 */
|
||||
@ -73,7 +73,7 @@ export class MapHeroRenderer implements IMapHeroRenderer {
|
||||
constructor(
|
||||
readonly renderer: IMapRenderer,
|
||||
readonly layer: IMapLayer,
|
||||
readonly hero: IHeroMover
|
||||
readonly hero: IHeroMoveController
|
||||
) {
|
||||
this.controller = hero.addHook(new MapHeroHook(this));
|
||||
this.controller.load();
|
||||
@ -107,7 +107,7 @@ export class MapHeroRenderer implements IMapHeroRenderer {
|
||||
private addHeroMoving(
|
||||
renderer: IMapRenderer,
|
||||
layer: IMapLayer,
|
||||
hero: IHeroMover
|
||||
hero: IHeroMoveController
|
||||
) {
|
||||
if (isNil(hero.image)) {
|
||||
logger.warn(88);
|
||||
@ -451,7 +451,7 @@ export class MapHeroRenderer implements IMapHeroRenderer {
|
||||
}
|
||||
}
|
||||
|
||||
class MapHeroHook implements Partial<IHeroMovingHooks> {
|
||||
class MapHeroHook implements Partial<IHeroMoveControllerHooks> {
|
||||
constructor(readonly hero: MapHeroRenderer) {}
|
||||
|
||||
onSetImage(image: ImageIds): void {
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { IHeroMover } from '@user/data-base';
|
||||
import { IHeroMoveController } from '@user/data-base';
|
||||
import { IMapLayer } from '@user/data-base';
|
||||
import {
|
||||
IMapDoorRenderer,
|
||||
@ -14,7 +14,7 @@ import { IOnMapTextRenderer } from './types';
|
||||
|
||||
export class MapExtensionManager implements IMapExtensionManager {
|
||||
/** 勇士状态至勇士渲染器的映射 */
|
||||
readonly heroMap: Map<IHeroMover, IMapHeroRenderer> = new Map();
|
||||
readonly heroMap: Map<IHeroMoveController, IMapHeroRenderer> = new Map();
|
||||
/** 地图图层到门渲染器的映射 */
|
||||
readonly doorMap: Map<IMapLayer, IMapDoorRenderer> = new Map();
|
||||
/** 单例的文字渲染拓展(独立图层) */
|
||||
@ -22,7 +22,10 @@ export class MapExtensionManager implements IMapExtensionManager {
|
||||
|
||||
constructor(readonly renderer: IMapRenderer) {}
|
||||
|
||||
addHero(state: IHeroMover, layer: IMapLayer): IMapHeroRenderer | null {
|
||||
addHero(
|
||||
state: IHeroMoveController,
|
||||
layer: IMapLayer
|
||||
): IMapHeroRenderer | null {
|
||||
if (this.heroMap.has(state)) {
|
||||
logger.error(45, 'hero renderer');
|
||||
return null;
|
||||
@ -32,7 +35,7 @@ export class MapExtensionManager implements IMapExtensionManager {
|
||||
return heroRenderer;
|
||||
}
|
||||
|
||||
removeHero(state: IHeroMover): void {
|
||||
removeHero(state: IHeroMoveController): void {
|
||||
const renderer = this.heroMap.get(state);
|
||||
if (!renderer) return;
|
||||
renderer.destroy();
|
||||
|
||||
@ -2,7 +2,7 @@ import { ITexture, Font } from '@motajs/render';
|
||||
import {
|
||||
FaceDirection,
|
||||
HeroAnimateDirection,
|
||||
IHeroMover
|
||||
IHeroMoveController
|
||||
} from '@user/data-base';
|
||||
import { IMapLayer } from '@user/data-base';
|
||||
|
||||
@ -10,7 +10,7 @@ import { IMapRenderResult } from '../types';
|
||||
|
||||
export interface IMapExtensionManager {
|
||||
/** 勇士状态至勇士渲染器的映射 */
|
||||
readonly heroMap: Map<IHeroMover, IMapHeroRenderer>;
|
||||
readonly heroMap: Map<IHeroMoveController, IMapHeroRenderer>;
|
||||
/** 地图图层到门渲染器的映射 */
|
||||
readonly doorMap: Map<IMapLayer, IMapDoorRenderer>;
|
||||
/** 单例的文字渲染拓展(独立图层) */
|
||||
@ -21,13 +21,16 @@ export interface IMapExtensionManager {
|
||||
* @param state 勇士状态
|
||||
* @param layer 勇士所在图层
|
||||
*/
|
||||
addHero(state: IHeroMover, layer: IMapLayer): IMapHeroRenderer | null;
|
||||
addHero(
|
||||
state: IHeroMoveController,
|
||||
layer: IMapLayer
|
||||
): IMapHeroRenderer | null;
|
||||
|
||||
/**
|
||||
* 移除勇士渲染拓展
|
||||
* @param state 勇士状态
|
||||
*/
|
||||
removeHero(state: IHeroMover): void;
|
||||
removeHero(state: IHeroMoveController): void;
|
||||
|
||||
/**
|
||||
* 添加开门动画拓展
|
||||
|
||||
@ -87,6 +87,24 @@ export class HeroAttribute<THero> implements IHeroAttribute<THero> {
|
||||
this.finalAttribute[name] = value;
|
||||
}
|
||||
|
||||
*catchCalculateProgress<K extends keyof THero>(name: K) {
|
||||
const modifierList = this.modifier.get(name);
|
||||
if (!modifierList) return;
|
||||
|
||||
const baseValue = this.attribute[name];
|
||||
let value = baseValue;
|
||||
for (const modifier of modifierList as IHeroModifier<THero[K]>[]) {
|
||||
const nextValue = modifier.modify(value, baseValue, name);
|
||||
// 部署之后就没必要弹这个警告了,额外判断反而可能会有一定的性能损失,直接 tree-shaking 优化掉
|
||||
if (import.meta.env.DEV && this.isSameReference(value, nextValue)) {
|
||||
const modiferName = modifier.constructor.name;
|
||||
logger.warn(109, modiferName, String(name));
|
||||
}
|
||||
value = nextValue;
|
||||
yield [modifier, value] as [IHeroModifier<THero[K]>, THero[K]];
|
||||
}
|
||||
}
|
||||
|
||||
getBaseAttribute<K extends keyof THero>(name: K): THero[K] {
|
||||
return this.attribute[name];
|
||||
}
|
||||
|
||||
@ -1,14 +1,18 @@
|
||||
import { Hookable, HookController, IHookController } from '@motajs/common';
|
||||
import { isNil } from 'lodash-es';
|
||||
import { getFaceMovement, nextFaceDirection } from '@user/data-common';
|
||||
import { IHeroFollower, IHeroMover, IHeroMovingHooks } from './types';
|
||||
import {
|
||||
IHeroFollower,
|
||||
IHeroMoveController,
|
||||
IHeroMoveControllerHooks
|
||||
} from './types';
|
||||
import { FaceDirection } from '@user/data-common';
|
||||
|
||||
const DEFAULT_HERO_IMAGE: ImageIds = 'hero.png';
|
||||
|
||||
export class HeroMover
|
||||
extends Hookable<IHeroMovingHooks>
|
||||
implements IHeroMover
|
||||
export class HeroMoveController
|
||||
extends Hookable<IHeroMoveControllerHooks>
|
||||
implements IHeroMoveController
|
||||
{
|
||||
x: number = 0;
|
||||
y: number = 0;
|
||||
@ -22,8 +26,8 @@ export class HeroMover
|
||||
readonly followers: IHeroFollower[] = [];
|
||||
|
||||
protected createController(
|
||||
hook: Partial<IHeroMovingHooks>
|
||||
): IHookController<IHeroMovingHooks> {
|
||||
hook: Partial<IHeroMoveControllerHooks>
|
||||
): IHookController<IHeroMoveControllerHooks> {
|
||||
return new HookController(this, hook);
|
||||
}
|
||||
|
||||
|
||||
@ -2,7 +2,7 @@ import { HeroAttribute } from './attribute';
|
||||
import {
|
||||
IHeroAttribute,
|
||||
IHeroModifier,
|
||||
IHeroMover,
|
||||
IHeroMoveController,
|
||||
IHeroState,
|
||||
IHeroStateSave,
|
||||
IModifierStateSave,
|
||||
@ -16,11 +16,11 @@ export class HeroState<THero> implements IHeroState<THero> {
|
||||
private readonly registry: Map<string, () => IHeroModifier> = new Map();
|
||||
|
||||
constructor(
|
||||
public mover: IHeroMover,
|
||||
public mover: IHeroMoveController,
|
||||
public attribute: IHeroAttribute<THero>
|
||||
) {}
|
||||
|
||||
attachMover(mover: IHeroMover): void {
|
||||
attachMover(mover: IHeroMoveController): void {
|
||||
this.mover = mover;
|
||||
}
|
||||
|
||||
@ -28,7 +28,7 @@ export class HeroState<THero> implements IHeroState<THero> {
|
||||
this.attribute = attribute;
|
||||
}
|
||||
|
||||
getHeroMover(): IHeroMover {
|
||||
getHeroMover(): IHeroMoveController {
|
||||
return this.mover;
|
||||
}
|
||||
|
||||
|
||||
@ -4,10 +4,10 @@ import { FaceDirection, ISaveableContent } from '@user/data-common';
|
||||
//#region 勇士属性
|
||||
|
||||
export interface IHeroModifier<
|
||||
T = unknown,
|
||||
K = unknown,
|
||||
V = unknown,
|
||||
S = unknown
|
||||
> extends ISaveableContent<S> {
|
||||
Save = unknown
|
||||
> extends ISaveableContent<Save> {
|
||||
/** 修饰器类型 */
|
||||
readonly type: string;
|
||||
/** 修饰器优先级 */
|
||||
@ -40,12 +40,12 @@ export interface IHeroModifier<
|
||||
* @param baseValue 该属性值的基础属性值
|
||||
* @param name 属性名称
|
||||
*/
|
||||
modify(value: T, baseValue: T, name: PropertyKey): T;
|
||||
modify(value: K, baseValue: K, name: PropertyKey): K;
|
||||
|
||||
/**
|
||||
* 深拷贝此修饰器
|
||||
*/
|
||||
clone(): IHeroModifier<T, V>;
|
||||
clone(): IHeroModifier<K, V>;
|
||||
}
|
||||
|
||||
export interface IModifierStateSave {
|
||||
@ -129,7 +129,7 @@ export interface IHeroAttribute<THero> extends IReadonlyHeroAttribute<THero> {
|
||||
*/
|
||||
addModifier<K extends keyof THero>(
|
||||
name: K,
|
||||
modifier: IHeroModifier<THero[K], unknown>
|
||||
modifier: IHeroModifier<THero[K]>
|
||||
): void;
|
||||
|
||||
/**
|
||||
@ -139,7 +139,7 @@ export interface IHeroAttribute<THero> extends IReadonlyHeroAttribute<THero> {
|
||||
*/
|
||||
deleteModifier<K extends keyof THero>(
|
||||
name: K,
|
||||
modifier: IHeroModifier<THero[K], unknown>
|
||||
modifier: IHeroModifier<THero[K]>
|
||||
): void;
|
||||
|
||||
/**
|
||||
@ -147,6 +147,15 @@ export interface IHeroAttribute<THero> extends IReadonlyHeroAttribute<THero> {
|
||||
* @param cloneModifier 是否同时复制修饰器,默认复制
|
||||
*/
|
||||
clone(cloneModifier?: boolean): IHeroAttribute<THero>;
|
||||
|
||||
/**
|
||||
* 获取勇士指定属性计算过程的可迭代对象,一般用于调试。
|
||||
* 此方法仅输出计算过程及结果,不会修改内部存储的最终属性。
|
||||
* @param name 属性名称
|
||||
*/
|
||||
catchCalculateProgress<K extends keyof THero>(
|
||||
name: K
|
||||
): Iterable<[IHeroModifier<THero[K]>, THero[K]]>;
|
||||
}
|
||||
|
||||
//#endregion
|
||||
@ -169,7 +178,7 @@ export interface IHeroFollower {
|
||||
alpha: number;
|
||||
}
|
||||
|
||||
export interface IHeroMovingHooks extends IHookBase {
|
||||
export interface IHeroMoveControllerHooks extends IHookBase {
|
||||
/**
|
||||
* 当设置勇士的坐标时触发
|
||||
* @param x 勇士横坐标
|
||||
@ -253,7 +262,7 @@ export interface IHeroMovingHooks extends IHookBase {
|
||||
onSetFollowerAlpha(identifier: string, alpha: number): void;
|
||||
}
|
||||
|
||||
export interface IHeroMover extends IHookable<IHeroMovingHooks> {
|
||||
export interface IHeroMoveController extends IHookable<IHeroMoveControllerHooks> {
|
||||
/** 勇士横坐标 */
|
||||
readonly x: number;
|
||||
/** 勇士纵坐标 */
|
||||
@ -372,7 +381,7 @@ export interface IHeroState<THero> extends ISaveableContent<
|
||||
IHeroStateSave<THero>
|
||||
> {
|
||||
/** 勇士移动对象 */
|
||||
readonly mover: IHeroMover;
|
||||
readonly mover: IHeroMoveController;
|
||||
/** 勇士属性对象 */
|
||||
readonly attribute: IReadonlyHeroAttribute<THero>;
|
||||
|
||||
@ -380,12 +389,12 @@ export interface IHeroState<THero> extends ISaveableContent<
|
||||
* 绑定勇士移动对象
|
||||
* @param mover 勇士移动对象
|
||||
*/
|
||||
attachMover(mover: IHeroMover): void;
|
||||
attachMover(mover: IHeroMoveController): void;
|
||||
|
||||
/**
|
||||
* 获取勇士移动对象
|
||||
*/
|
||||
getHeroMover(): IHeroMover;
|
||||
getHeroMover(): IHeroMoveController;
|
||||
|
||||
/**
|
||||
* 绑定勇士属性对象
|
||||
|
||||
@ -17,7 +17,7 @@ import {
|
||||
} from '@user/data-common';
|
||||
import {
|
||||
EnemyManager,
|
||||
HeroMover,
|
||||
HeroMoveController,
|
||||
IEnemyManager,
|
||||
HeroAttribute,
|
||||
HeroState,
|
||||
@ -69,23 +69,23 @@ import { logger } from '@motajs/common';
|
||||
import { ISaveSystem, SaveSystem } from './save';
|
||||
|
||||
export class CoreState implements ICoreState {
|
||||
// Layer 0 公共层
|
||||
// Layer 0 公共层,最底层的接口,不会依赖任何其他内容,一般是工具性接口及不需要存档的数据
|
||||
readonly roleFace: IRoleFaceBinder;
|
||||
readonly faceManager: IFaceManager;
|
||||
readonly tileStore: ITileStore<LegacyTileData>;
|
||||
|
||||
// Layer 1 数据层,所有可存档内容都在这
|
||||
// Layer 1 数据层,所有可存档内容都在这,一般用于数据存储
|
||||
readonly maps: IMapStore;
|
||||
readonly hero: IHeroState<IHeroAttr>;
|
||||
readonly enemyManager: IEnemyManager<IEnemyAttr>;
|
||||
readonly flags: IFlagSystem;
|
||||
|
||||
// Layer 2 执行层,游戏逻辑对象都在这
|
||||
// Layer 2 执行层,游戏逻辑对象都在这,包括一些需要操作数据层的逻辑系统等
|
||||
readonly enemyContext: IEnemyContext<IEnemyAttr, IHeroAttr>;
|
||||
readonly triggerRegistry: ITriggerRegistry;
|
||||
readonly triggerCollector: ITriggerCollector;
|
||||
|
||||
// 用户层内容,也就是最顶层的内容,一般仅用于初始化
|
||||
// Layer 3 用户层,也就是最顶层的内容,一般仅用于初始化以及仅供渲染端调用的顶层模块
|
||||
readonly loadProgress: ILoadProgressTotal;
|
||||
readonly dataLoader: IMotaDataLoader;
|
||||
readonly saveSystem: ISaveSystem;
|
||||
@ -129,7 +129,7 @@ export class CoreState implements ICoreState {
|
||||
this.maps = new MapStore(tileStore, this);
|
||||
|
||||
// 勇士
|
||||
const heroMover = new HeroMover();
|
||||
const heroMover = new HeroMoveController();
|
||||
const heroAttribute = new HeroAttribute(HERO_DEFAULT_ATTRIBUTE);
|
||||
const heroState = new HeroState(heroMover, heroAttribute);
|
||||
this.hero = heroState;
|
||||
@ -179,7 +179,7 @@ export class CoreState implements ICoreState {
|
||||
|
||||
//#endregion
|
||||
|
||||
//#region 顶层初始化
|
||||
//#region L3 初始化
|
||||
|
||||
// 存档系统
|
||||
this.saveSystem = new SaveSystem();
|
||||
@ -209,8 +209,12 @@ export class CoreState implements ICoreState {
|
||||
core.floors as Record<FloorIds, ResolvedFloor>
|
||||
);
|
||||
});
|
||||
|
||||
//#endregion
|
||||
}
|
||||
|
||||
//#region 私有方法
|
||||
|
||||
/**
|
||||
* 初始化图块存储对象
|
||||
* @param data 旧样板图块定义对象
|
||||
@ -355,6 +359,10 @@ export class CoreState implements ICoreState {
|
||||
this.maps.compareWith(reference);
|
||||
}
|
||||
|
||||
//#endregion
|
||||
|
||||
//#region 存档方法
|
||||
|
||||
addSaveableContent(id: string, content: ISaveableContent<unknown>): void {
|
||||
if (this.saveables.has(id)) {
|
||||
logger.warn(112, id);
|
||||
@ -385,4 +393,6 @@ export class CoreState implements ICoreState {
|
||||
this.executors.set(content, executor);
|
||||
}
|
||||
}
|
||||
|
||||
//#endregion
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user