feat: 勇士贴图打包

This commit is contained in:
AncTe committed 2025-11-19 18:28:59 +08:00
1 parent efe6931799
commit 37cd85cd1e
9 files changed
+154 -232

No files matched your search

+83 -3
View File
@@ -1,6 +1,11 @@
import { IHookable, IHookBase, IHookController } from '@motajs/common';
import { IMapLayer } from '../map';
export interface ICoreState {
/** 地图状态 */
readonly layer: ILayerState;
}
export interface ILayerStateHooks extends IHookBase {
/**
* 当设置背景图块时执行,如果设置的背景图块与原先一样,则不会执行
@@ -136,7 +141,82 @@ export interface ILayerState extends IHookable<ILayerStateHooks> {
getBackground(): number;
}
export interface ICoreState {
/** 地图状态 */
readonly layer: ILayerState;
export const enum HeroDirection {
Left,
Up,
Right,
Down
}
export interface IHeroStateHooks extends IHookBase {
/**
* 当设置勇士的坐标时触发
* @param controller 钩子控制器
* @param x 勇士横坐标
* @param y 勇士纵坐标
*/
onSetPosition(
controller: IHookController<this>,
x: number,
y: number
): void;
/**
* 当移动勇士时触发
* @param controller 钩子控制器
* @param direction 移动方向
* @param time 移动动画时长
*/
onMoveHero(
controller: IHookController<this>,
direction: HeroDirection,
time: number
): Promise<void>;
/**
* 当勇士跳跃时触发
* @param controller 钩子控制器
* @param x 目标点横坐标
* @param y 目标点纵坐标
* @param time 跳跃动画时长
*/
onJumpHero(
controller: IHookController<this>,
x: number,
y: number,
time: number
): Promise<void>;
}
export interface IHeroState extends IHookable<IHeroStateHooks> {
/** 勇士横坐标 */
readonly x: number;
/** 勇士纵坐标 */
readonly y: number;
/** 勇士朝向 */
readonly direction: HeroDirection;
/**
* 设置勇士位置
* @param x 横坐标
* @param y 纵坐标
*/
setPosition(x: number, y: number): void;
/**
* 移动勇士
* @param dir 移动方向
* @param time 移动动画时长,默认 100ms
* @returns 移动的 `Promise`,当相关的移动动画结束后兑现
*/
move(dir: HeroDirection, time?: number): Promise<void>;
/**
* 跳跃勇士至目标点
* @param x 目标点横坐标
* @param y 目标点纵坐标
* @param time 跳跃动画时长,默认 500ms
* @returns 跳跃的 `Promise`,当相关的移动动画结束后兑现
*/
jumpHero(x: number, y: number, time?: number): Promise<void>;
}
+1 -217
View File
@@ -1,6 +1,3 @@
import { logger } from '@motajs/common';
import { EventEmitter } from 'eventemitter3';
import { cloneDeep } from 'lodash-es';
import { HeroSkill, NightSpecial } from '../mechanism';
/**
@@ -21,7 +18,7 @@ export function getHeroStatusOn(
name: keyof HeroStatus | 'all' | (keyof HeroStatus)[],
floorId?: FloorIds
) {
// @ts-ignore
// @ts-expect-error 推导错误
return getHeroStatusOf(core.status.hero, name, floorId);
}
@@ -129,216 +126,3 @@ export interface IHeroStatusDefault {
def: number;
hp: number;
}
interface HeroStateEvent {
set: [key: string | number | symbol, value: any];
}
type HeroStatusCalculate = (
hero: HeroState<any>,
key: string | number | symbol,
value: any
) => any;
export class HeroState<
T extends object = IHeroStatusDefault
> extends EventEmitter<HeroStateEvent> {
readonly status: T;
readonly computedStatus: T;
readonly buffable: Set<keyof T> = new Set();
readonly buffMap: Map<keyof T, number> = new Map();
private static cal: HeroStatusCalculate = (_0, _1, value) => value;
constructor(init: T) {
super();
this.status = init;
this.computedStatus = cloneDeep(init);
}
/**
* 设置某个属性的值
* @param key 要设置的属性
* @param value 属性值
* @returns 是否设置成功
*/
setStatus<K extends keyof T>(key: K, value: T[K]): boolean {
this.status[key] = value;
this.emit('set', key, value);
return this.refreshStatus(key);
}
/**
* 增加或减少一个属性的值,只对数字型的属性有效
* @param key 要修改的属性
* @param value 属性的增量
* @returns 是否设置成功
*/
addStatus<K extends SelectKey<T, number>>(key: K, value: number): boolean {
if (typeof this.status[key] !== 'number') {
logger.warn(14, String(key));
return false;
}
return this.setStatus<K>(key, (this.status[key] + value) as T[K]);
}
/**
* 获取某个属性的原始值
* @param key 要获取的属性
* @returns 属性的值
*/
getStatus<K extends keyof T>(key: K): T[K] {
return this.status[key];
}
/**
* 获取一个属性计算后的值,也就是2.x所说的勇士真实属性
* @param key 要获取的属性值
*/
getComputedStatus<K extends keyof T>(key: K): T[K] {
return this.computedStatus[key];
}
/**
* 标记某个属性为可以被buff加成
*/
markBuffable(key: SelectKey<T, number>): void {
if (typeof this.status[key] !== 'number') {
logger.warn(12, String(key));
return;
}
this.buffable.add(key);
this.buffMap.set(key, 1);
}
/**
* 设置某个属性的buff值
* @param key 要设置buff的属性
* @param value buff值
* @returns 是否设置成功
*/
setBuff(key: SelectKey<T, number>, value: number): boolean {
if (!this.buffable.has(key) || typeof this.status[key] !== 'number') {
logger.warn(13, String(key));
return false;
}
this.buffMap.set(key, value);
return this.refreshStatus(key);
}
/**
* 增加或减少一个buff值
* @param key 要修改的buff属性
* @param value buff增量
* @returns 是否修改成功
*/
addBuff(key: SelectKey<T, number>, value: number): boolean {
if (!this.buffable.has(key) || typeof this.status[key] !== 'number') {
logger.warn(13, String(key));
return false;
}
return this.setBuff(key, this.buffMap.get(key)! + value);
}
/**
* 刷新某个或所有属性,重新进行计算
* @param key 要刷新的属性名,不填表示刷新所有属性
* @returns 是否计算成功
*/
refreshStatus(key?: keyof T): boolean {
if (key === void 0) {
for (const [key, value] of Object.entries(this.status)) {
// @ts-ignore
this.computedStatus[key] = HeroState.cal(this, key, value);
}
return true;
}
this.computedStatus[key] = HeroState.cal(this, key, this.status[key]);
return true;
}
/**
* 计算所有可以buff加成的属性
* @returns 是否计算成功
*/
refreshBuffable(): boolean {
for (const key of this.buffable) {
this.computedStatus[key] = HeroState.cal(
this,
key,
this.status[key]
);
}
return true;
}
/**
* 复写属性计算函数,默认函数不进行计算,直接将原属性返回
* @param fn 计算函数,传入两个参数,key表示属性名,value表示属性值,返回值表示计算结果
*/
static overrideCalculate(fn: HeroStatusCalculate) {
this.cal = fn;
}
}
interface IHeroItem {
items: Map<AllIdsOf<'items'>, number>;
/**
* 设置勇士拥有的物品数量
* @param item 物品id
* @param value 物品数量
* @returns 是否设置成功
*/
setItem(item: AllIdsOf<'items'>, value: number): boolean;
/**
* 增加或减少勇士拥有的物品数量
* @param item 物品id
* @param value 物品数量增量
* @returns 是否设置成功
*/
addItem(item: AllIdsOf<'items'>, value: number): boolean;
/**
* 使用一个物品
* @param item 物品id
* @returns 是否使用成功
*/
useItem(item: AllIdsOf<'items'>, x?: number, y?: number): boolean;
/**
* 获得一个物品
* @param item 物品id
* @param num 获得的数量
*/
getItem(item: AllIdsOf<'items'>, num: number): void;
/**
* 获得一个物品
* @param item 物品id
* @param x 物品所在x坐标
* @param y 物品所在y坐标
* @param floorId 物品所在楼层
* @param num 获得的数量
*/
getItem(
item: AllIdsOf<'items'>,
x: number,
y: number,
floorId?: FloorIds,
num?: number
): void;
/**
* 获取某个物品的数量
* @param item 物品id
*/
itemCount(item: AllIdsOf<'items'>): number;
/**
* 判断勇士是否拥有这个物品
* @param item 物品id
*/
hasItem(item: AllIdsOf<'items'>): boolean;
}