feat: 勇士贴图打包

This commit is contained in:
unanmed 2025-11-19 18:28:59 +08:00
parent efe6931799
commit 37cd85cd1e
9 changed files with 154 additions and 232 deletions

View File

@ -1,3 +1,4 @@
import { ITexture } from '@motajs/render-assets';
import { materials } from './ins';
import { IBlockIdentifier, IIndexedIdentifier } from './types';
@ -118,8 +119,16 @@ export function fallbackLoad() {
addAutotile(autotileSet, floor.fg2map);
});
const heroTextures: ITexture[] = [];
data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d.main.heroImages.forEach(v => {
const tex = materials.getImageByAlias(v);
if (tex) heroTextures.push(tex);
});
materials.buildAssets();
materials.cacheAutotileList(autotileSet);
materials.cacheTilesetList(tilesetSet);
materials.buildListToAsset(heroTextures);
}

View File

@ -430,13 +430,32 @@ export class MaterialManager implements IMaterialManager {
return [];
}
this.built = true;
const data = this.assetBuilder.addTextureList(this.tileStore.values());
return this.buildListToAsset(this.tileStore.values());
}
buildToAsset(texture: ITexture): IMaterialAssetData {
const data = this.assetBuilder.addTexture(texture);
const assetData: IMaterialAssetData = {
data: data,
identifier: data.index,
alias: `asset-${data.index}`,
store: this.assetStore
};
this.checkAssetDirty(data);
return assetData;
}
buildListToAsset(
texture: Iterable<ITexture>
): Iterable<IMaterialAssetData> {
const data = this.assetBuilder.addTextureList(texture);
const arr = [...data];
const res: IMaterialAssetData[] = [];
arr.forEach(v => {
const alias = `asset-${v.index}`;
this.assetStore.alias(v.index, alias);
if (!this.assetDataStore.has(v.index)) {
this.assetDataStore.set(v.index, v);
}
const data: IMaterialAssetData = {
data: v,
identifier: v.index,
@ -448,6 +467,9 @@ export class MaterialManager implements IMaterialManager {
}
res.push(data);
});
arr.forEach(v => {
this.checkAssetDirty(v);
});
return res;
}

View File

@ -397,6 +397,18 @@ export interface IMaterialManager
*/
buildAssets(): Iterable<IMaterialAssetData>;
/**
*
* @param texture
*/
buildToAsset(texture: ITexture): IMaterialAssetData;
/**
*
* @param texture
*/
buildListToAsset(texture: Iterable<ITexture>): Iterable<IMaterialAssetData>;
/**
*
* @param identifier

View File

@ -261,7 +261,6 @@ const MainScene = defineComponent(() => {
return () => (
<container id="main-scene" width={MAIN_WIDTH} height={MAIN_HEIGHT}>
<sprite
hidden
render={testRender}
loc={[180, 0, 480, 480]}
zIndex={1000}

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>;
}

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;
}

View File

@ -18,13 +18,6 @@ var data_comment_c456ea59_6018_45ef_8bcc_211a24c627dc = {
"_docs": "楼层列表",
"_data": "在这里按顺序放所有的楼层;其顺序直接影响到楼层传送器、浏览地图和上/下楼器的顺序"
},
"plugin": {
"_leaf": true,
"_type": "textarea",
"_range": "thiseval instanceof Array",
"_docs": "插件列表",
"_data": "在这里按顺序放所有的插件,顺序会影响到插件的加载,越靠前越早加载"
},
"floorPartitions": {
"_leaf": true,
"_type": "event",
@ -128,6 +121,19 @@ var data_comment_c456ea59_6018_45ef_8bcc_211a24c627dc = {
"_docs": "使用字体",
"_data": "在此存放所有可能使用的字体 \n 字体名不能使用中文,不能带空格或特殊字符"
},
"heroImages": {
"_leaf": true,
"_type": "material",
"_range": "editor.mode.checkImages(thiseval, './project/images/')",
"_directory": "./project/images/",
"_transform": (function (one) {
if (one.endsWith('.png') || one.endsWith('.jpg') || one.endsWith('.jpeg') || one.endsWith('.gif') || one.endsWith('.webp'))
return one;
return null;
}).toString(),
"_docs": "勇士贴图",
"_data": "在这里填写游戏中所有可能使用到的勇士贴图,贴图需要先在全塔属性-使用图片中注册。如果一个贴图不会被用作勇士贴图,请不要填写进去!",
},
"nameMap": {
"_leaf": true,
"_type": "event",

View File

@ -382,7 +382,12 @@ var data_a1e2fb4a_e986_4524_b0da_9b7ba7c0874d =
],
"font": "normal"
},
"splitImages": []
"splitImages": [],
"heroImages": [
"hero.png",
"hero1.png",
"hero2.png"
]
},
"firstData": {
"title": "人类:开天辟地",

View File

@ -69,6 +69,11 @@ interface MainData {
*/
readonly splitImages: SplitImageData;
/**
*
*/
readonly heroImages: readonly ImageIds[];
readonly plugin: string[];
}