mirror of
https://github.com/unanmed/HumanBreak.git
synced 2025-11-11 11:52:57 +08:00
Compare commits
2 Commits
5279eaf696
...
fd07268931
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fd07268931 | ||
| 637647dc17 |
30
packages-user/client-base/src/material/asset.ts
Normal file
30
packages-user/client-base/src/material/asset.ts
Normal file
@ -0,0 +1,30 @@
|
||||
import { ITextureComposedData } from '@motajs/render-assets';
|
||||
import { IMaterialAsset } from './types';
|
||||
|
||||
export class MaterialAsset implements IMaterialAsset {
|
||||
/** 标记列表 */
|
||||
private readonly marks: Map<symbol, number> = new Map();
|
||||
/** 脏标记,所有值小于此标记的都视为需要更新 */
|
||||
private dirtyFlag: number = 0;
|
||||
|
||||
constructor(readonly data: ITextureComposedData) {}
|
||||
|
||||
dirty(): void {
|
||||
this.dirtyFlag++;
|
||||
}
|
||||
|
||||
mark(): symbol {
|
||||
const symbol = Symbol();
|
||||
this.marks.set(symbol, this.dirtyFlag);
|
||||
return symbol;
|
||||
}
|
||||
|
||||
unmark(mark: symbol): void {
|
||||
this.marks.delete(mark);
|
||||
}
|
||||
|
||||
dirtySince(mark: symbol): boolean {
|
||||
const value = this.marks.get(mark) ?? -1;
|
||||
return value < this.dirtyFlag;
|
||||
}
|
||||
}
|
||||
@ -171,6 +171,10 @@ export class AutotileProcessor implements IAutotileProcessor {
|
||||
return this.fromStaticRenderable(tile.static(), connection);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据静态可渲染对象获取自动元件的帧列表
|
||||
* @param renderable 静态可渲染对象
|
||||
*/
|
||||
private getStaticRectList(
|
||||
renderable: ITextureRenderable
|
||||
): AutotileFrameList {
|
||||
@ -194,11 +198,17 @@ export class AutotileProcessor implements IAutotileProcessor {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 对自动元件连接执行偏移操作,偏移至自动元件在图像源中的所在矩形范围
|
||||
* @param ox 横向偏移量
|
||||
* @param oy 纵向偏移量
|
||||
* @param connection 自动元件连接信息
|
||||
*/
|
||||
private getConnectedRect(
|
||||
ox: number,
|
||||
oy: number,
|
||||
connection: ConnectedAutotile
|
||||
): ConnectedAutotile | null {
|
||||
): ConnectedAutotile {
|
||||
const { lt, rt, rb, lb } = connection;
|
||||
|
||||
return {
|
||||
|
||||
@ -7,4 +7,10 @@ export function createMaterial() {
|
||||
});
|
||||
}
|
||||
|
||||
export * from './autotile';
|
||||
export * from './builder';
|
||||
export * from './fallback';
|
||||
export * from './ins';
|
||||
export * from './manager';
|
||||
export * from './types';
|
||||
export * from './utils';
|
||||
|
||||
@ -19,12 +19,14 @@ import {
|
||||
IMaterialAssetData,
|
||||
BlockCls,
|
||||
IBigImageData,
|
||||
IAssetBuilder
|
||||
IAssetBuilder,
|
||||
IMaterialAsset
|
||||
} from './types';
|
||||
import { logger } from '@motajs/common';
|
||||
import { getClsByString } from './utils';
|
||||
import { isNil } from 'lodash-es';
|
||||
import { AssetBuilder } from './builder';
|
||||
import { MaterialAsset } from './asset';
|
||||
|
||||
export class MaterialManager implements IMaterialManager {
|
||||
readonly tileStore: ITextureStore = new TextureStore();
|
||||
@ -34,7 +36,8 @@ export class MaterialManager implements IMaterialManager {
|
||||
readonly bigImageStore: ITextureStore = new TextureStore();
|
||||
|
||||
/** 图集信息存储 */
|
||||
readonly assetDataStore: Map<number, ITextureComposedData> = new Map();
|
||||
readonly assetDataStore: Map<number, IMaterialAsset> = new Map();
|
||||
|
||||
/** 大怪物数据 */
|
||||
readonly bigImageData: Map<number, ITexture> = new Map();
|
||||
/** tileset 中 `Math.floor(id / 10000) + 1` 映射到 tileset 对应索引的映射,用于处理图块超出 10000 的 tileset */
|
||||
@ -60,6 +63,9 @@ export class MaterialManager implements IMaterialManager {
|
||||
/** 是否已经构建过素材 */
|
||||
private built: boolean = false;
|
||||
|
||||
/** 标记列表 */
|
||||
private readonly markList: symbol[] = [];
|
||||
|
||||
constructor() {
|
||||
this.assetBuilder.pipe(this.assetStore);
|
||||
}
|
||||
@ -264,6 +270,23 @@ export class MaterialManager implements IMaterialManager {
|
||||
return newTexture;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查图集状态,如果已存在图集则标记为脏,否则新增图集
|
||||
* @param data 图集数据
|
||||
*/
|
||||
private checkAssetDirty(data: ITextureComposedData) {
|
||||
const asset = this.assetDataStore.get(data.index);
|
||||
if (asset) {
|
||||
// 如果不是新图集,需要标记为脏
|
||||
asset.dirty();
|
||||
} else {
|
||||
// 如果有新图集,需要添加
|
||||
const alias = `asset-${data.index}`;
|
||||
this.assetStore.alias(data.index, alias);
|
||||
this.assetDataStore.set(data.index, new MaterialAsset(data));
|
||||
}
|
||||
}
|
||||
|
||||
cacheTileset(identifier: number): ITexture | null {
|
||||
const newTexture = this.getTilesetOwnTexture(identifier);
|
||||
if (!newTexture) return null;
|
||||
@ -273,6 +296,7 @@ export class MaterialManager implements IMaterialManager {
|
||||
this.numIdMap.set(identifier, `X${identifier}`);
|
||||
const data = this.assetBuilder.addTexture(newTexture);
|
||||
newTexture.toAsset(data);
|
||||
this.checkAssetDirty(data);
|
||||
return newTexture;
|
||||
}
|
||||
|
||||
@ -295,10 +319,11 @@ export class MaterialManager implements IMaterialManager {
|
||||
|
||||
const data = this.assetBuilder.addTextureList(toAdd);
|
||||
const res = [...data];
|
||||
res.forEach(v => {
|
||||
v.assetMap.keys().forEach(tex => {
|
||||
if (set.has(tex)) tex.toAsset(v);
|
||||
res.forEach(data => {
|
||||
data.assetMap.keys().forEach(tex => {
|
||||
if (set.has(tex)) tex.toAsset(data);
|
||||
});
|
||||
this.checkAssetDirty(data);
|
||||
});
|
||||
|
||||
return toAdd;
|
||||
@ -313,13 +338,13 @@ export class MaterialManager implements IMaterialManager {
|
||||
const data = this.assetBuilder.addTextureList(this.tileStore.values());
|
||||
const arr = [...data];
|
||||
const res: IMaterialAssetData[] = [];
|
||||
arr.forEach((v, i) => {
|
||||
const alias = `asset-${i}`;
|
||||
this.assetStore.alias(i, alias);
|
||||
this.assetDataStore.set(i, v);
|
||||
arr.forEach(v => {
|
||||
const alias = `asset-${v.index}`;
|
||||
this.assetStore.alias(v.index, alias);
|
||||
this.assetDataStore.set(v.index, new MaterialAsset(v));
|
||||
const data: IMaterialAssetData = {
|
||||
data: v,
|
||||
identifier: i,
|
||||
identifier: v.index,
|
||||
alias,
|
||||
store: this.assetStore
|
||||
};
|
||||
@ -331,11 +356,11 @@ export class MaterialManager implements IMaterialManager {
|
||||
return res;
|
||||
}
|
||||
|
||||
getAsset(identifier: number): ITextureComposedData | null {
|
||||
getAsset(identifier: number): IMaterialAsset | null {
|
||||
return this.assetDataStore.get(identifier) ?? null;
|
||||
}
|
||||
|
||||
getAssetByAlias(alias: string): ITextureComposedData | null {
|
||||
getAssetByAlias(alias: string): IMaterialAsset | null {
|
||||
const id = this.assetStore.identifierOf(alias);
|
||||
if (isNil(id)) return null;
|
||||
return this.assetDataStore.get(id) ?? null;
|
||||
@ -406,4 +431,14 @@ export class MaterialManager implements IMaterialManager {
|
||||
if (isNil(identifier)) return null;
|
||||
return this.bigImageData.get(identifier) ?? null;
|
||||
}
|
||||
|
||||
getIfBigImage(identifier: number): ITexture | null {
|
||||
const bigImage = this.bigImageData.get(identifier) ?? null;
|
||||
if (bigImage) return bigImage;
|
||||
if (identifier < 10000) {
|
||||
return this.tileStore.getTexture(identifier);
|
||||
} else {
|
||||
return this.cacheTileset(identifier);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -90,6 +90,37 @@ export interface IBigImageData {
|
||||
readonly store: ITextureStore;
|
||||
}
|
||||
|
||||
export interface IAssetDirtyMarker {
|
||||
/**
|
||||
* 标记为脏,即进行了一次更新
|
||||
*/
|
||||
dirty(): void;
|
||||
}
|
||||
|
||||
export interface IAssetDirtyTracker {
|
||||
/**
|
||||
* 对图集状态进行标记
|
||||
*/
|
||||
mark(): symbol;
|
||||
|
||||
/**
|
||||
* 取消指定标记符号
|
||||
* @param mark 标记符号
|
||||
*/
|
||||
unmark(mark: symbol): void;
|
||||
|
||||
/**
|
||||
* 从指定标记符号开始,图集是否发生了变动
|
||||
* @param mark 标记符号
|
||||
*/
|
||||
dirtySince(mark: symbol): boolean;
|
||||
}
|
||||
|
||||
export interface IMaterialAsset extends IAssetDirtyTracker, IAssetDirtyMarker {
|
||||
/** 图集的贴图数据 */
|
||||
readonly data: ITextureComposedData;
|
||||
}
|
||||
|
||||
export interface IAutotileProcessor {
|
||||
/** 该自动元件处理器使用的素材管理器 */
|
||||
readonly manager: IMaterialManager;
|
||||
@ -162,7 +193,98 @@ export interface IAutotileProcessor {
|
||||
): Generator<IAutotileRenderable, void> | null;
|
||||
}
|
||||
|
||||
export interface IMaterialManager {
|
||||
export interface IMaterialGetter {
|
||||
/**
|
||||
* 根据图块数字获取图块,可以获取额外素材,会自动将未缓存的额外素材缓存
|
||||
* @param identifier 图块的图块数字
|
||||
*/
|
||||
getTile(identifier: number): ITexture | null;
|
||||
|
||||
/**
|
||||
* 根据图块标识符获取图块类型
|
||||
* @param identifier 图块标识符,即图块数字
|
||||
*/
|
||||
getBlockCls(identifier: number): BlockCls;
|
||||
|
||||
/**
|
||||
* 判断一个图块是否包含 `bigImage` 贴图,即是否是大怪物
|
||||
* @param identifier 图块标识符,即图块数字
|
||||
*/
|
||||
isBigImage(identifier: number): boolean;
|
||||
|
||||
/**
|
||||
* 根据图块标识符获取一个图块的 `bigImage` 贴图
|
||||
* @param identifier 图块标识符,即图块数字
|
||||
*/
|
||||
getBigImage(identifier: number): ITexture | null;
|
||||
|
||||
/**
|
||||
* 根据图块标识符,首先判断是否是 `bigImage` 贴图,如果是,则返回 `bigImage` 贴图,
|
||||
* 否则返回普通贴图。如果图块不存在,则返回 `null`
|
||||
* @param identifier 图块标识符,即图块数字
|
||||
*/
|
||||
getIfBigImage(identifier: number): ITexture | null;
|
||||
|
||||
/**
|
||||
* 根据标识符获取图集信息
|
||||
* @param identifier 图集的标识符
|
||||
*/
|
||||
getAsset(identifier: number): IMaterialAsset | null;
|
||||
|
||||
/**
|
||||
* 根据额外素材索引获取额外素材
|
||||
* @param identifier 额外素材的索引
|
||||
*/
|
||||
getTileset(identifier: number): ITexture | null;
|
||||
|
||||
/**
|
||||
* 根据图片的索引获取图片
|
||||
* @param identifier 图片的索引
|
||||
*/
|
||||
getImage(identifier: number): ITexture | null;
|
||||
}
|
||||
|
||||
export interface IMaterialAliasGetter {
|
||||
/**
|
||||
* 根据图块 id 获取图块,可以获取额外素材,会自动将未缓存的额外素材缓存
|
||||
* @param alias 图块 id
|
||||
*/
|
||||
getTileByAlias(alias: string): ITexture | null;
|
||||
|
||||
/**
|
||||
* 根据额外素材名称获取额外素材
|
||||
* @param alias 额外素材名称
|
||||
*/
|
||||
getTilesetByAlias(alias: string): ITexture | null;
|
||||
|
||||
/**
|
||||
* 根据图片名称获取图片
|
||||
* @param alias 图片名称
|
||||
*/
|
||||
getImageByAlias(alias: string): ITexture | null;
|
||||
|
||||
/**
|
||||
* 根据别名获取图集信息
|
||||
* @param alias 图集的别名
|
||||
*/
|
||||
getAssetByAlias(alias: string): IMaterialAsset | null;
|
||||
|
||||
/**
|
||||
* 根据图块别名获取图块类型
|
||||
* @param alias 图块别名,即图块的 id
|
||||
*/
|
||||
getBlockClsByAlias(alias: string): BlockCls;
|
||||
|
||||
/**
|
||||
* 根据图块别名获取一个图块的 `bigImage` 贴图
|
||||
* @param alias 图块别名,即图块的 id
|
||||
*/
|
||||
getBigImageByAlias(alias: string): ITexture | null;
|
||||
}
|
||||
|
||||
export interface IMaterialManager
|
||||
extends IMaterialGetter,
|
||||
IMaterialAliasGetter {
|
||||
/** 贴图存储,把 terrains 等内容单独分开存储 */
|
||||
readonly tileStore: ITextureStore;
|
||||
/** tilesets 贴图存储,每个 tileset 是一个贴图对象 */
|
||||
@ -174,6 +296,9 @@ export interface IMaterialManager {
|
||||
/** bigImage 存储,存储大怪物数据 */
|
||||
readonly bigImageStore: ITextureStore;
|
||||
|
||||
/** 图集信息存储 */
|
||||
readonly assetDataStore: Iterable<[number, IMaterialAsset]>;
|
||||
|
||||
/** 图块类型映射 */
|
||||
readonly clsMap: Map<number, BlockCls>;
|
||||
|
||||
@ -231,42 +356,6 @@ export interface IMaterialManager {
|
||||
identifier: IIndexedIdentifier
|
||||
): IMaterialData;
|
||||
|
||||
/**
|
||||
* 根据图块数字获取图块,可以获取额外素材,会自动将未缓存的额外素材缓存
|
||||
* @param identifier 图块的图块数字
|
||||
*/
|
||||
getTile(identifier: number): ITexture | null;
|
||||
|
||||
/**
|
||||
* 根据额外素材索引获取额外素材
|
||||
* @param identifier 额外素材的索引
|
||||
*/
|
||||
getTileset(identifier: number): ITexture | null;
|
||||
|
||||
/**
|
||||
* 根据图片的索引获取图片
|
||||
* @param identifier 图片的索引
|
||||
*/
|
||||
getImage(identifier: number): ITexture | null;
|
||||
|
||||
/**
|
||||
* 根据图块 id 获取图块,可以获取额外素材,会自动将未缓存的额外素材缓存
|
||||
* @param alias 图块 id
|
||||
*/
|
||||
getTileByAlias(alias: string): ITexture | null;
|
||||
|
||||
/**
|
||||
* 根据额外素材名称获取额外素材
|
||||
* @param alias 额外素材名称
|
||||
*/
|
||||
getTilesetByAlias(alias: string): ITexture | null;
|
||||
|
||||
/**
|
||||
* 根据图片名称获取图片
|
||||
* @param alias 图片名称
|
||||
*/
|
||||
getImageByAlias(alias: string): ITexture | null;
|
||||
|
||||
/**
|
||||
* 缓存某个 tileset
|
||||
* @param identifier tileset 的标识符,即图块数字
|
||||
@ -286,18 +375,6 @@ export interface IMaterialManager {
|
||||
*/
|
||||
buildAssets(): Iterable<IMaterialAssetData>;
|
||||
|
||||
/**
|
||||
* 根据标识符获取图集信息
|
||||
* @param identifier 图集的标识符
|
||||
*/
|
||||
getAsset(identifier: number): ITextureComposedData | null;
|
||||
|
||||
/**
|
||||
* 根据别名获取图集信息
|
||||
* @param alias 图集的别名
|
||||
*/
|
||||
getAssetByAlias(alias: string): ITextureComposedData | null;
|
||||
|
||||
/**
|
||||
* 根据图块标识符在图集中获取对应的可渲染对象
|
||||
* @param identifier 图块标识符,即图块数字
|
||||
@ -310,18 +387,6 @@ export interface IMaterialManager {
|
||||
*/
|
||||
getRenderableByAlias(alias: string): ITextureRenderable | null;
|
||||
|
||||
/**
|
||||
* 根据图块标识符获取图块类型
|
||||
* @param identifier 图块标识符,即图块数字
|
||||
*/
|
||||
getBlockCls(identifier: number): BlockCls;
|
||||
|
||||
/**
|
||||
* 根据图块别名获取图块类型
|
||||
* @param alias 图块别名,即图块的 id
|
||||
*/
|
||||
getBlockClsByAlias(alias: string): BlockCls;
|
||||
|
||||
/**
|
||||
* 根据图块别名获取图块标识符,即图块数字
|
||||
* @param alias 图块别名,即图块的 id
|
||||
@ -340,24 +405,6 @@ export interface IMaterialManager {
|
||||
* @param image `bigImage` 对应的贴图对象
|
||||
*/
|
||||
setBigImage(identifier: number, image: ITexture): IBigImageData;
|
||||
|
||||
/**
|
||||
* 判断一个图块是否包含 `bigImage` 贴图,即是否是大怪物
|
||||
* @param identifier 图块标识符,即图块数字
|
||||
*/
|
||||
isBigImage(identifier: number): boolean;
|
||||
|
||||
/**
|
||||
* 根据图块标识符获取一个图块的 `bigImage` 贴图
|
||||
* @param identifier 图块标识符,即图块数字
|
||||
*/
|
||||
getBigImage(identifier: number): ITexture | null;
|
||||
|
||||
/**
|
||||
* 根据图块别名获取一个图块的 `bigImage` 贴图
|
||||
* @param alias 图块别名,即图块的 id
|
||||
*/
|
||||
getBigImageByAlias(alias: string): ITexture | null;
|
||||
}
|
||||
|
||||
export interface IAssetBuilder {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user