mirror of
https://github.com/unanmed/HumanBreak.git
synced 2025-10-30 02:42:57 +08:00
feat: 图块打包进图集
This commit is contained in:
parent
eea66f001b
commit
b3ed39f800
@ -27,6 +27,7 @@ export class AssetBuilder implements IAssetBuilder {
|
|||||||
this.started = true;
|
this.started = true;
|
||||||
const res = [...this.composer.add([texture])];
|
const res = [...this.composer.add([texture])];
|
||||||
const data = res[0];
|
const data = res[0];
|
||||||
|
|
||||||
if (this.output) {
|
if (this.output) {
|
||||||
if (!this.output.getTexture(data.index)) {
|
if (!this.output.getTexture(data.index)) {
|
||||||
this.output.addTexture(data.index, data.texture);
|
this.output.addTexture(data.index, data.texture);
|
||||||
|
|||||||
108
packages-user/client-base/src/material/fallback.ts
Normal file
108
packages-user/client-base/src/material/fallback.ts
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
import { materials } from './manager';
|
||||||
|
import { IBlockIdentifier, IIndexedIdentifier } from './types';
|
||||||
|
|
||||||
|
function extractClsBlocks<C extends Exclude<Cls, 'tileset'>>(
|
||||||
|
cls: C,
|
||||||
|
map: Record<string, number>,
|
||||||
|
icons: Record<string, number>
|
||||||
|
): IBlockIdentifier[] {
|
||||||
|
const max = Math.max(...Object.values(icons));
|
||||||
|
const arr = Array(max).fill(0);
|
||||||
|
for (const [key, value] of Object.entries(icons)) {
|
||||||
|
if (!(key in map)) continue;
|
||||||
|
const id = key as AllIdsOf<C>;
|
||||||
|
const num = map[id] as keyof NumberToId;
|
||||||
|
const identifier: IBlockIdentifier = {
|
||||||
|
id: id as string,
|
||||||
|
cls,
|
||||||
|
num
|
||||||
|
};
|
||||||
|
arr[value] = identifier;
|
||||||
|
}
|
||||||
|
return arr;
|
||||||
|
}
|
||||||
|
|
||||||
|
function addTileset(set: Set<number>, map?: readonly (readonly number[])[]) {
|
||||||
|
if (!map) return;
|
||||||
|
map.forEach(line => {
|
||||||
|
line.forEach(v => {
|
||||||
|
if (v >= 10000) set.add(v);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 兼容旧版加载
|
||||||
|
*/
|
||||||
|
export function fallbackLoad() {
|
||||||
|
// 基本素材
|
||||||
|
const icons = core.icons.icons;
|
||||||
|
const images = core.material.images;
|
||||||
|
const idNumMap: Record<string, number> = {};
|
||||||
|
|
||||||
|
for (const [key, value] of Object.entries(core.maps.blocksInfo)) {
|
||||||
|
idNumMap[value.id] = Number(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
const terrains = extractClsBlocks('terrains', idNumMap, icons.terrains);
|
||||||
|
const animates = extractClsBlocks('animates', idNumMap, icons.animates);
|
||||||
|
const items = extractClsBlocks('items', idNumMap, icons.items);
|
||||||
|
const enemys = extractClsBlocks('enemys', idNumMap, icons.enemys);
|
||||||
|
const npcs = extractClsBlocks('npcs', idNumMap, icons.npcs);
|
||||||
|
const enemy48 = extractClsBlocks('enemy48', idNumMap, icons.enemy48);
|
||||||
|
const npc48 = extractClsBlocks('npc48', idNumMap, icons.npc48);
|
||||||
|
|
||||||
|
// Grid
|
||||||
|
materials.addGrid(images.terrains, terrains);
|
||||||
|
materials.addGrid(images.items, items);
|
||||||
|
|
||||||
|
// Row Animates
|
||||||
|
materials.addRowAnimate(images.animates, animates, 4, 32);
|
||||||
|
materials.addRowAnimate(images.enemys, enemys, 2, 32);
|
||||||
|
materials.addRowAnimate(images.npcs, npcs, 2, 32);
|
||||||
|
materials.addRowAnimate(images.enemy48, enemy48, 4, 48);
|
||||||
|
materials.addRowAnimate(images.npc48, npc48, 4, 48);
|
||||||
|
|
||||||
|
// Autotile
|
||||||
|
for (const key of Object.keys(icons.autotile)) {
|
||||||
|
const id = key as AllIdsOf<'autotile'>;
|
||||||
|
const img = images.autotile[id];
|
||||||
|
const identifier: IBlockIdentifier = {
|
||||||
|
id,
|
||||||
|
num: idNumMap[id],
|
||||||
|
cls: 'autotile'
|
||||||
|
};
|
||||||
|
materials.addAutotile(img, identifier);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tilesets
|
||||||
|
core.tilesets.forEach((v, i) => {
|
||||||
|
const img = images.tilesets[v];
|
||||||
|
const identifier: IIndexedIdentifier = {
|
||||||
|
index: i,
|
||||||
|
alias: v
|
||||||
|
};
|
||||||
|
materials.addTileset(img, identifier);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Images
|
||||||
|
core.images.forEach((v, i) => {
|
||||||
|
const img = core.material.images.images[v];
|
||||||
|
materials.addImage(img, { index: i, alias: v });
|
||||||
|
});
|
||||||
|
|
||||||
|
materials.buildAssets();
|
||||||
|
|
||||||
|
// 地图上出现过的 tileset
|
||||||
|
const tilesetSet = new Set<number>();
|
||||||
|
core.floorIds.forEach(v => {
|
||||||
|
const floor = core.floors[v];
|
||||||
|
addTileset(tilesetSet, floor.bgmap);
|
||||||
|
addTileset(tilesetSet, floor.bg2map);
|
||||||
|
addTileset(tilesetSet, floor.map);
|
||||||
|
addTileset(tilesetSet, floor.fgmap);
|
||||||
|
addTileset(tilesetSet, floor.fg2map);
|
||||||
|
});
|
||||||
|
|
||||||
|
materials.cacheTilesetList(tilesetSet);
|
||||||
|
}
|
||||||
@ -1,3 +1,10 @@
|
|||||||
export function createMaterial() {}
|
import { loading } from '@user/data-base';
|
||||||
|
import { fallbackLoad } from './fallback';
|
||||||
|
|
||||||
|
export function createMaterial() {
|
||||||
|
loading.once('loaded', () => {
|
||||||
|
fallbackLoad();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
export * from './manager';
|
export * from './manager';
|
||||||
|
|||||||
@ -53,6 +53,14 @@ export class MaterialManager implements IMaterialManager {
|
|||||||
|
|
||||||
/** 大怪物贴图的标识符 */
|
/** 大怪物贴图的标识符 */
|
||||||
private bigImageId: number = 0;
|
private bigImageId: number = 0;
|
||||||
|
/** 当前 tileset 索引 */
|
||||||
|
private nowTilesetIndex: number = -1;
|
||||||
|
/** 当前 tileset 偏移 */
|
||||||
|
private nowTilesetOffset: number = 0;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this.assetBuilder.pipe(this.assetStore);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 添加由分割器和图块映射组成的图像源贴图
|
* 添加由分割器和图块映射组成的图像源贴图
|
||||||
@ -109,14 +117,15 @@ export class MaterialManager implements IMaterialManager {
|
|||||||
addRowAnimate(
|
addRowAnimate(
|
||||||
source: SizedCanvasImageSource,
|
source: SizedCanvasImageSource,
|
||||||
map: ArrayLike<IBlockIdentifier>,
|
map: ArrayLike<IBlockIdentifier>,
|
||||||
frames: number
|
frames: number,
|
||||||
|
height: number
|
||||||
): Iterable<IMaterialData> {
|
): Iterable<IMaterialData> {
|
||||||
return this.addMappedSource(
|
return this.addMappedSource(
|
||||||
source,
|
source,
|
||||||
map,
|
map,
|
||||||
this.tileStore,
|
this.tileStore,
|
||||||
this.rowSplitter,
|
this.rowSplitter,
|
||||||
32,
|
height,
|
||||||
(tex: ITexture<number>) => {
|
(tex: ITexture<number>) => {
|
||||||
tex.animated(new TextureColumnAnimater(), frames);
|
tex.animated(new TextureColumnAnimater(), frames);
|
||||||
}
|
}
|
||||||
@ -143,10 +152,34 @@ export class MaterialManager implements IMaterialManager {
|
|||||||
addTileset(
|
addTileset(
|
||||||
source: SizedCanvasImageSource,
|
source: SizedCanvasImageSource,
|
||||||
identifier: IIndexedIdentifier
|
identifier: IIndexedIdentifier
|
||||||
): IMaterialData {
|
): IMaterialData | null {
|
||||||
const tex = new Texture(source);
|
const tex = new Texture(source);
|
||||||
this.tilesetStore.addTexture(identifier.index, tex);
|
this.tilesetStore.addTexture(identifier.index, tex);
|
||||||
this.tilesetStore.alias(identifier.index, identifier.alias);
|
this.tilesetStore.alias(identifier.index, identifier.alias);
|
||||||
|
const width = Math.floor(source.width / 32);
|
||||||
|
const height = Math.floor(source.height / 32);
|
||||||
|
const count = width * height;
|
||||||
|
const offset = Math.ceil(count / 10000);
|
||||||
|
if (identifier.index === 0) {
|
||||||
|
this.tilesetOffsetMap.set(0, 0);
|
||||||
|
this.nowTilesetIndex = 0;
|
||||||
|
this.nowTilesetOffset = offset;
|
||||||
|
} else {
|
||||||
|
if (identifier.index - 1 !== this.nowTilesetIndex) {
|
||||||
|
logger.warn(78);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
const width = Math.floor(source.width / 32);
|
||||||
|
const height = Math.floor(source.height / 32);
|
||||||
|
const count = width * height;
|
||||||
|
const offset = Math.ceil(count / 10000);
|
||||||
|
const end = this.nowTilesetOffset + offset;
|
||||||
|
for (let i = this.nowTilesetOffset; i < end; i++) {
|
||||||
|
this.tilesetOffsetMap.set(i, identifier.index);
|
||||||
|
}
|
||||||
|
this.nowTilesetOffset = end;
|
||||||
|
this.nowTilesetIndex = identifier.index;
|
||||||
|
}
|
||||||
const data: IMaterialData = {
|
const data: IMaterialData = {
|
||||||
store: this.tilesetStore,
|
store: this.tilesetStore,
|
||||||
texture: tex,
|
texture: tex,
|
||||||
@ -173,7 +206,11 @@ export class MaterialManager implements IMaterialManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getTile(identifier: number): ITexture | null {
|
getTile(identifier: number): ITexture | null {
|
||||||
return this.tileStore.getTexture(identifier);
|
if (identifier < 10000) {
|
||||||
|
return this.tileStore.getTexture(identifier);
|
||||||
|
} else {
|
||||||
|
return this.cacheTileset(identifier);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getTileset(identifier: number): ITexture | null {
|
getTileset(identifier: number): ITexture | null {
|
||||||
@ -185,7 +222,11 @@ export class MaterialManager implements IMaterialManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getTileByAlias(alias: string): ITexture | null {
|
getTileByAlias(alias: string): ITexture | null {
|
||||||
return this.tileStore.fromAlias(alias);
|
if (/X\d{5,}/.test(alias)) {
|
||||||
|
return this.cacheTileset(parseInt(alias.slice(1)));
|
||||||
|
} else {
|
||||||
|
return this.tileStore.fromAlias(alias);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getTilesetByAlias(alias: string): ITexture | null {
|
getTilesetByAlias(alias: string): ITexture | null {
|
||||||
@ -196,6 +237,71 @@ export class MaterialManager implements IMaterialManager {
|
|||||||
return this.imageStore.fromAlias(alias);
|
return this.imageStore.fromAlias(alias);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private getTilesetOwnTexture(identifier: number) {
|
||||||
|
const texture = this.tileStore.getTexture(identifier);
|
||||||
|
if (texture) return texture;
|
||||||
|
// 如果 tileset 不存在,那么执行缓存操作
|
||||||
|
const offset = Math.floor(identifier / 10000);
|
||||||
|
const index = this.tilesetOffsetMap.get(offset - 1);
|
||||||
|
if (isNil(index)) return null;
|
||||||
|
// 获取对应的 tileset 贴图
|
||||||
|
const tileset = this.tilesetStore.getTexture(index);
|
||||||
|
if (!tileset) return null;
|
||||||
|
// 计算图块位置
|
||||||
|
const rest = identifier - offset * 10000;
|
||||||
|
const { width, height } = tileset;
|
||||||
|
const tileWidth = Math.floor(width / 32);
|
||||||
|
const tileHeight = Math.floor(height / 32);
|
||||||
|
// 如果图块位置超出了贴图范围
|
||||||
|
if (rest > tileWidth * tileHeight) return null;
|
||||||
|
// 裁剪 tileset,生成贴图
|
||||||
|
const x = rest % tileWidth;
|
||||||
|
const y = Math.floor(rest / tileWidth);
|
||||||
|
const newTexture = new Texture(tileset.source);
|
||||||
|
newTexture.clip(x * 32, y * 32, 32, 32);
|
||||||
|
return newTexture;
|
||||||
|
}
|
||||||
|
|
||||||
|
cacheTileset(identifier: number): ITexture | null {
|
||||||
|
const newTexture = this.getTilesetOwnTexture(identifier);
|
||||||
|
if (!newTexture) return null;
|
||||||
|
// 缓存贴图
|
||||||
|
this.tileStore.addTexture(identifier, newTexture);
|
||||||
|
this.idNumMap.set(`X${identifier}`, identifier);
|
||||||
|
this.numIdMap.set(identifier, `X${identifier}`);
|
||||||
|
const data = this.assetBuilder.addTexture(newTexture);
|
||||||
|
newTexture.toAsset(data);
|
||||||
|
return newTexture;
|
||||||
|
}
|
||||||
|
|
||||||
|
cacheTilesetList(
|
||||||
|
identifierList: Iterable<number>
|
||||||
|
): Iterable<ITexture | null> {
|
||||||
|
const arr = [...identifierList];
|
||||||
|
const toAdd: ITexture[] = [];
|
||||||
|
|
||||||
|
arr.forEach(v => {
|
||||||
|
const newTexture = this.getTilesetOwnTexture(v);
|
||||||
|
if (!newTexture) return;
|
||||||
|
toAdd.push(newTexture);
|
||||||
|
this.tileStore.addTexture(v, newTexture);
|
||||||
|
this.idNumMap.set(`X${v}`, v);
|
||||||
|
this.numIdMap.set(v, `X${v}`);
|
||||||
|
});
|
||||||
|
|
||||||
|
const set = new Set(toAdd);
|
||||||
|
|
||||||
|
const data = this.assetBuilder.addTextureList(toAdd);
|
||||||
|
const res = [...data];
|
||||||
|
res.forEach(v => {
|
||||||
|
v.assetMap.keys().forEach(tex => {
|
||||||
|
if (set.has(tex)) tex.toAsset(v);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
return toAdd;
|
||||||
|
}
|
||||||
|
|
||||||
buildAssets(): Iterable<IMaterialAssetData> {
|
buildAssets(): Iterable<IMaterialAssetData> {
|
||||||
this.assetBuilder.pipe(this.assetStore);
|
this.assetBuilder.pipe(this.assetStore);
|
||||||
const data = this.assetBuilder.addTextureList(this.tileStore.values());
|
const data = this.assetBuilder.addTextureList(this.tileStore.values());
|
||||||
@ -204,6 +310,7 @@ export class MaterialManager implements IMaterialManager {
|
|||||||
arr.forEach((v, i) => {
|
arr.forEach((v, i) => {
|
||||||
const alias = `asset-${i}`;
|
const alias = `asset-${i}`;
|
||||||
this.assetStore.alias(i, alias);
|
this.assetStore.alias(i, alias);
|
||||||
|
this.assetDataStore.set(i, v);
|
||||||
const data: IMaterialAssetData = {
|
const data: IMaterialAssetData = {
|
||||||
data: v,
|
data: v,
|
||||||
identifier: i,
|
identifier: i,
|
||||||
@ -234,34 +341,7 @@ export class MaterialManager implements IMaterialManager {
|
|||||||
return this.tileStore.getTexture(identifier);
|
return this.tileStore.getTexture(identifier);
|
||||||
}
|
}
|
||||||
if (identifier < 10000) return null;
|
if (identifier < 10000) return null;
|
||||||
const texture = this.tileStore.getTexture(identifier);
|
return this.cacheTileset(identifier);
|
||||||
if (texture) return texture;
|
|
||||||
// 如果 tileset 不存在,那么执行缓存操作
|
|
||||||
const offset = Math.floor(identifier / 10000);
|
|
||||||
const index = this.tilesetOffsetMap.get(offset);
|
|
||||||
if (isNil(index)) return null;
|
|
||||||
// 获取对应的 tileset 贴图
|
|
||||||
const tileset = this.tilesetStore.getTexture(index);
|
|
||||||
if (!tileset) return null;
|
|
||||||
// 计算图块位置
|
|
||||||
const rest = identifier - offset * 10000;
|
|
||||||
const { width, height } = tileset;
|
|
||||||
const tileWidth = Math.floor(width / 32);
|
|
||||||
const tileHeight = Math.floor(height / 32);
|
|
||||||
// 如果图块位置超出了贴图范围
|
|
||||||
if (rest > tileWidth * tileHeight) return null;
|
|
||||||
// 裁剪 tileset,生成贴图
|
|
||||||
const x = rest % tileWidth;
|
|
||||||
const y = Math.floor(rest / tileWidth);
|
|
||||||
const newTexture = new Texture(tileset.source);
|
|
||||||
newTexture.clip(x * 32, y * 32, 32, 32);
|
|
||||||
// 缓存贴图
|
|
||||||
this.tileStore.addTexture(identifier, newTexture);
|
|
||||||
this.idNumMap.set(`X${identifier}`, identifier);
|
|
||||||
this.numIdMap.set(identifier, `X${identifier}`);
|
|
||||||
const data = this.assetBuilder.addTexture(newTexture);
|
|
||||||
newTexture.toAsset(data);
|
|
||||||
return newTexture;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getRenderable(identifier: number): ITextureRenderable | null {
|
getRenderable(identifier: number): ITextureRenderable | null {
|
||||||
|
|||||||
@ -150,11 +150,13 @@ export interface IMaterialManager {
|
|||||||
* @param source 图像源
|
* @param source 图像源
|
||||||
* @param map 贴图字符串 id 与图块数字映射,按从上到下的顺序映射
|
* @param map 贴图字符串 id 与图块数字映射,按从上到下的顺序映射
|
||||||
* @param frames 每一行的帧数
|
* @param frames 每一行的帧数
|
||||||
|
* @param height 每一行的高度
|
||||||
*/
|
*/
|
||||||
addRowAnimate(
|
addRowAnimate(
|
||||||
source: SizedCanvasImageSource,
|
source: SizedCanvasImageSource,
|
||||||
map: ArrayLike<IBlockIdentifier>,
|
map: ArrayLike<IBlockIdentifier>,
|
||||||
frames: number
|
frames: number,
|
||||||
|
height: number
|
||||||
): Iterable<IMaterialData>;
|
): Iterable<IMaterialData>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -175,7 +177,7 @@ export interface IMaterialManager {
|
|||||||
addTileset(
|
addTileset(
|
||||||
source: SizedCanvasImageSource,
|
source: SizedCanvasImageSource,
|
||||||
identifier: IIndexedIdentifier
|
identifier: IIndexedIdentifier
|
||||||
): IMaterialData;
|
): IMaterialData | null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 添加一个图片
|
* 添加一个图片
|
||||||
@ -223,6 +225,20 @@ export interface IMaterialManager {
|
|||||||
*/
|
*/
|
||||||
getImageByAlias(alias: string): ITexture | null;
|
getImageByAlias(alias: string): ITexture | null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 缓存某个 tileset
|
||||||
|
* @param identifier tileset 的标识符,即图块数字
|
||||||
|
*/
|
||||||
|
cacheTileset(identifier: number): ITexture | null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 缓存一系列 tileset
|
||||||
|
* @param identifierList 标识符列表,即图块数字列表
|
||||||
|
*/
|
||||||
|
cacheTilesetList(
|
||||||
|
identifierList: Iterable<number>
|
||||||
|
): Iterable<ITexture | null>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 把常用素材打包成为图集形式供后续使用
|
* 把常用素材打包成为图集形式供后续使用
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -109,6 +109,7 @@
|
|||||||
"75": "Material count splitted by grid does not match alias count, some material may have no alias or some alias may not map to a texture. Splitted: $1, alias: $2.",
|
"75": "Material count splitted by grid does not match alias count, some material may have no alias or some alias may not map to a texture. Splitted: $1, alias: $2.",
|
||||||
"76": "Cannot pipe texture store when asset builder is started.",
|
"76": "Cannot pipe texture store when asset builder is started.",
|
||||||
"77": "Texture is clipped to an area of 0. Ensure that the texture contains your clip rect and clip rect's area is not zero.",
|
"77": "Texture is clipped to an area of 0. Ensure that the texture contains your clip rect and clip rect's area is not zero.",
|
||||||
|
"78": "Adding tileset source must follow index order.",
|
||||||
"1001": "Item-detail extension needs 'floor-binder' and 'floor-damage' extension as dependency.",
|
"1001": "Item-detail extension needs 'floor-binder' and 'floor-damage' extension as dependency.",
|
||||||
"1101": "Cannot add new effect to point effect instance, for there's no more reserve space for it. Please increase the max count of the instance."
|
"1101": "Cannot add new effect to point effect instance, for there's no more reserve space for it. Please increase the max count of the instance."
|
||||||
}
|
}
|
||||||
|
|||||||
@ -72,17 +72,23 @@ export class TextureGridStreamComposer implements ITextureStreamComposer<void> {
|
|||||||
this.nowCtx.drawImage(source, cx, cy, cw, ch, x, y, cw, ch);
|
this.nowCtx.drawImage(source, cx, cy, cw, ch, x, y, cw, ch);
|
||||||
this.nowMap.set(tex, { x, y, w: cw, h: ch });
|
this.nowMap.set(tex, { x, y, w: cw, h: ch });
|
||||||
|
|
||||||
const data: ITextureComposedData = {
|
|
||||||
index: this.outputIndex,
|
|
||||||
texture: this.nowTexture,
|
|
||||||
assetMap: this.nowMap
|
|
||||||
};
|
|
||||||
yield data;
|
|
||||||
|
|
||||||
if (++index === max) {
|
if (++index === max) {
|
||||||
|
const data: ITextureComposedData = {
|
||||||
|
index: this.outputIndex,
|
||||||
|
texture: this.nowTexture,
|
||||||
|
assetMap: this.nowMap
|
||||||
|
};
|
||||||
|
yield data;
|
||||||
this.nextCanvas();
|
this.nextCanvas();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const data: ITextureComposedData = {
|
||||||
|
index: this.outputIndex,
|
||||||
|
texture: this.nowTexture,
|
||||||
|
assetMap: this.nowMap
|
||||||
|
};
|
||||||
|
yield data;
|
||||||
}
|
}
|
||||||
|
|
||||||
close(): void {
|
close(): void {
|
||||||
@ -102,12 +108,12 @@ export class TextureMaxRectsStreamComposer
|
|||||||
readonly packer: MaxRectsPacker<MaxRectsRectangle>;
|
readonly packer: MaxRectsPacker<MaxRectsRectangle>;
|
||||||
|
|
||||||
private outputIndex: number = 0;
|
private outputIndex: number = 0;
|
||||||
private nowTexture: ITexture;
|
private nowTexture!: ITexture;
|
||||||
|
|
||||||
private nowCanvas: HTMLCanvasElement;
|
private nowCanvas!: HTMLCanvasElement;
|
||||||
private nowCtx: CanvasRenderingContext2D;
|
private nowCtx!: CanvasRenderingContext2D;
|
||||||
private nowMap: Map<ITexture, Readonly<IRect>>;
|
private nowMap!: Map<ITexture, Readonly<IRect>>;
|
||||||
private nowBin: number;
|
private nowBin: number = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 使用 Max Rects 算法执行贴图整合。输出的纹理的图像源将会是不同的画布。
|
* 使用 Max Rects 算法执行贴图整合。输出的纹理的图像源将会是不同的画布。
|
||||||
@ -129,16 +135,14 @@ export class TextureMaxRectsStreamComposer
|
|||||||
options
|
options
|
||||||
);
|
);
|
||||||
|
|
||||||
this.nowCanvas = document.createElement('canvas');
|
this.nextCanvas();
|
||||||
this.nowCtx = this.nowCanvas.getContext('2d')!;
|
|
||||||
this.nowMap = new Map();
|
|
||||||
this.nowBin = 0;
|
|
||||||
this.nowTexture = new Texture(this.nowCanvas);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private nextCanvas() {
|
private nextCanvas() {
|
||||||
this.nowCanvas = document.createElement('canvas');
|
this.nowCanvas = document.createElement('canvas');
|
||||||
this.nowCtx = this.nowCanvas.getContext('2d')!;
|
this.nowCtx = this.nowCanvas.getContext('2d')!;
|
||||||
|
this.nowCanvas.width = this.maxWidth;
|
||||||
|
this.nowCanvas.height = this.maxHeight;
|
||||||
this.nowMap = new Map();
|
this.nowMap = new Map();
|
||||||
this.outputIndex++;
|
this.outputIndex++;
|
||||||
this.nowTexture = new Texture(this.nowCanvas);
|
this.nowTexture = new Texture(this.nowCanvas);
|
||||||
@ -176,6 +180,7 @@ export class TextureMaxRectsStreamComposer
|
|||||||
const { x: cx, y: cy, w: cw, h: ch } = rect;
|
const { x: cx, y: cy, w: cw, h: ch } = rect;
|
||||||
this.nowCtx.drawImage(source, cx, cy, cw, ch, v.x, v.y, cw, ch);
|
this.nowCtx.drawImage(source, cx, cy, cw, ch, v.x, v.y, cw, ch);
|
||||||
});
|
});
|
||||||
|
|
||||||
const data: ITextureComposedData = {
|
const data: ITextureComposedData = {
|
||||||
index: this.outputIndex,
|
index: this.outputIndex,
|
||||||
texture: this.nowTexture,
|
texture: this.nowTexture,
|
||||||
@ -187,7 +192,7 @@ export class TextureMaxRectsStreamComposer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.nowBin = bins.length;
|
this.nowBin = bins.length - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
close(): void {
|
close(): void {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user