feat: 默认帧数

This commit is contained in:
unanmed 2025-11-25 23:49:39 +08:00
parent 7fcefd62c4
commit 1c27014ab3
5 changed files with 90 additions and 34 deletions

View File

@ -1,6 +1,7 @@
import { ITexture } from '@motajs/render-assets';
import { materials } from './ins';
import { IBlockIdentifier, IIndexedIdentifier } from './types';
import { isNil } from 'lodash-es';
function extractClsBlocks<C extends Exclude<Cls, 'tileset'>>(
cls: C,
@ -52,7 +53,11 @@ export function fallbackLoad() {
const idNumMap: Record<string, number> = {};
for (const [key, value] of Object.entries(core.maps.blocksInfo)) {
idNumMap[value.id] = Number(key);
const num = Number(key);
idNumMap[value.id] = Number(num);
if (!isNil(value.animate)) {
materials.setDefaultFrame(num, value.animate - 1);
}
}
const terrains = extractClsBlocks('terrains', idNumMap, icons.terrains);

View File

@ -65,6 +65,8 @@ export class MaterialManager implements IMaterialManager {
readonly numIdMap: Map<number, string> = new Map();
/** 图块数字到图块类型的映射 */
readonly clsMap: Map<number, BlockCls> = new Map();
/** 图块的默认帧数 */
readonly defaultFrames: Map<number, number> = new Map();
/** 网格切分器 */
readonly gridSplitter: TextureGridSplitter = new TextureGridSplitter();
@ -218,7 +220,19 @@ export class MaterialManager implements IMaterialManager {
return data;
}
getTile(identifier: number): IMaterialFramedData | null {
setDefaultFrame(identifier: number, defaultFrame: number): void {
this.defaultFrames.set(identifier, defaultFrame);
const bigImageData = this.bigImageData.get(identifier);
if (bigImageData) {
bigImageData.defaultFrame = defaultFrame;
}
}
getDefaultFrame(identifier: number): number {
return this.defaultFrames.get(identifier) ?? -1;
}
getTile(identifier: number): Readonly<IMaterialFramedData> | null {
if (identifier < 10000) {
const cls = this.clsMap.get(identifier) ?? BlockCls.Unknown;
if (
@ -233,7 +247,8 @@ export class MaterialManager implements IMaterialManager {
texture,
cls,
offset: 32,
frames: getTextureFrame(cls, texture)
frames: getTextureFrame(cls, texture),
defaultFrame: this.defaultFrames.get(identifier) ?? -1
};
} else {
const texture = this.cacheTileset(identifier);
@ -242,7 +257,8 @@ export class MaterialManager implements IMaterialManager {
texture,
cls: BlockCls.Tileset,
offset: 32,
frames: 1
frames: 1,
defaultFrame: -1
};
}
}
@ -255,7 +271,7 @@ export class MaterialManager implements IMaterialManager {
return this.imageStore.getTexture(identifier);
}
getTileByAlias(alias: string): IMaterialFramedData | null {
getTileByAlias(alias: string): Readonly<IMaterialFramedData> | null {
if (/X\d{5,}/.test(alias)) {
return this.getTile(parseInt(alias.slice(1)));
} else {
@ -537,7 +553,8 @@ export class MaterialManager implements IMaterialManager {
texture: image,
cls,
offset: image.width / 4,
frames
frames,
defaultFrame: this.defaultFrames.get(identifier) ?? -1
};
this.bigImageData.set(identifier, store);
const data: IBigImageReturn = {
@ -551,17 +568,17 @@ export class MaterialManager implements IMaterialManager {
return this.bigImageData.has(identifier);
}
getBigImage(identifier: number): IMaterialFramedData | null {
getBigImage(identifier: number): Readonly<IMaterialFramedData> | null {
return this.bigImageData.get(identifier) ?? null;
}
getBigImageByAlias(alias: string): IMaterialFramedData | null {
getBigImageByAlias(alias: string): Readonly<IMaterialFramedData> | null {
const identifier = this.idNumMap.get(alias);
if (isNil(identifier)) return null;
return this.bigImageData.get(identifier) ?? null;
}
getIfBigImage(identifier: number): IMaterialFramedData | null {
getIfBigImage(identifier: number): Readonly<IMaterialFramedData> | null {
const bigImage = this.bigImageData.get(identifier);
if (bigImage) return bigImage;
else return this.getTile(identifier);

View File

@ -90,13 +90,15 @@ export interface IBigImageReturn {
export interface IMaterialFramedData {
/** 贴图对象 */
readonly texture: ITexture;
texture: ITexture;
/** 图块类型 */
readonly cls: BlockCls;
cls: BlockCls;
/** 贴图总帧数 */
readonly frames: number;
frames: number;
/** 每帧的横向偏移量 */
readonly offset: number;
offset: number;
/** 默认帧数 */
defaultFrame: number;
}
export interface IMaterialAsset
@ -160,7 +162,7 @@ export interface IAutotileProcessor {
* @returns
*/
renderWith(
tile: IMaterialFramedData,
tile: Readonly<IMaterialFramedData>,
connection: number
): ITextureRenderable | null;
@ -171,7 +173,7 @@ export interface IAutotileProcessor {
* @returns
*/
renderWithoutCheck(
tile: IMaterialFramedData,
tile: Readonly<IMaterialFramedData>,
connection: number
): ITextureRenderable | null;
@ -193,7 +195,7 @@ export interface IAutotileProcessor {
* @returns
*/
renderAnimatedWith(
tile: IMaterialFramedData,
tile: Readonly<IMaterialFramedData>,
connection: number
): Generator<ITextureRenderable, void>;
}
@ -203,7 +205,7 @@ export interface IMaterialGetter {
*
* @param identifier
*/
getTile(identifier: number): IMaterialFramedData | null;
getTile(identifier: number): Readonly<IMaterialFramedData> | null;
/**
*
@ -221,14 +223,14 @@ export interface IMaterialGetter {
* `bigImage`
* @param identifier
*/
getBigImage(identifier: number): IMaterialFramedData | null;
getBigImage(identifier: number): Readonly<IMaterialFramedData> | null;
/**
* `bigImage` `bigImage`
* `null`
* @param identifier
*/
getIfBigImage(identifier: number): IMaterialFramedData | null;
getIfBigImage(identifier: number): Readonly<IMaterialFramedData> | null;
/**
*
@ -254,7 +256,7 @@ export interface IMaterialAliasGetter {
* id
* @param alias id
*/
getTileByAlias(alias: string): IMaterialFramedData | null;
getTileByAlias(alias: string): Readonly<IMaterialFramedData> | null;
/**
*
@ -284,7 +286,7 @@ export interface IMaterialAliasGetter {
* `bigImage`
* @param alias id
*/
getBigImageByAlias(alias: string): IMaterialFramedData | null;
getBigImageByAlias(alias: string): Readonly<IMaterialFramedData> | null;
}
export interface IMaterialManager
@ -364,6 +366,19 @@ export interface IMaterialManager
identifier: IIndexedIdentifier
): IMaterialData;
/**
*
* @param identifier
* @param defaultFrame
*/
setDefaultFrame(identifier: number, defaultFrame: number): void;
/**
* -1 使
* @param identifier
*/
getDefaultFrame(identifier: number): number;
/**
* tileset使 {@link cacheTilesetList}
* @param identifier tileset

View File

@ -14,5 +14,4 @@ void main() {
// todo: 透明像素应该如何解决??
if (alpha < 0.1) discard;
outColor = vec4(texColor.rgb, alpha);
// outColor = vec4(texColor.a * 0.001, v_texCoord.x * 6.0, v_texCoord.y * 0.0, v_texCoord.a);
}

View File

@ -44,6 +44,8 @@ export interface IMapDataGetter {
}
interface BlockMapPos {
/** 图块的图块数字 */
readonly num: number;
/** 地图中的横坐标 */
readonly mapX: number;
/** 地图中的纵坐标 */
@ -77,11 +79,15 @@ interface VertexArrayOfBlock {
const enum VertexUpdate {
/** 更新顶点位置信息 */
Position = 0b01,
Position = 0b001,
/** 更新贴图信息 */
Texture = 0b10,
Texture = 0b010,
/** 是否更新默认帧数 */
Frame = 0b100,
/** 除帧数外全部更新 */
NoFrame = 0b011,
/** 全部更新 */
All = 0b11
All = 0b111
}
/**
@ -153,6 +159,7 @@ export class MapVertexGenerator
staticCount * INSTANCED_COUNT,
count * INSTANCED_COUNT
);
// 不透明度默认是 1帧数默认是 -1
for (let i = 0; i < count; i++) {
const start = i * INSTANCED_COUNT;
this.instancedArray[start + 9] = 1;
@ -405,6 +412,12 @@ export class MapVertexGenerator
instancedArray[startIndex + 14] = offsetIndex;
instancedArray[startIndex + 15] = assetIndex;
}
if (update & VertexUpdate.Frame) {
const defaultFrame = this.renderer.manager.getDefaultFrame(
index.num
);
instancedArray[startIndex + 12] = defaultFrame;
}
}
/**
@ -473,11 +486,14 @@ export class MapVertexGenerator
if (!vertex) return;
const bx = mx - block.dataX;
const by = my - block.dataY;
const mapIndex = my * this.mapWidth + mx;
const num = mapArray[mapIndex];
const newIndex: BlockIndex = {
layer,
num,
mapX: mx,
mapY: my,
mapIndex: my * this.mapWidth + mx,
mapIndex,
blockX: bx,
blockY: by,
blockIndex: by * block.width + bx
@ -489,6 +505,7 @@ export class MapVertexGenerator
vertex,
newIndex,
tile,
// 周围一圈的自动元件应该只更新贴图,不需要更新位置和默认帧数
VertexUpdate.Texture,
false
);
@ -525,6 +542,7 @@ export class MapVertexGenerator
return;
}
// todo: 这样的话,如果更新了指定分块,那么本来设置的帧数也会重置为默认帧数,如何修改?
if (tile.cls === BlockCls.Autotile) {
// 如果图块是自动元件
this.updateAutotile(
@ -532,6 +550,7 @@ export class MapVertexGenerator
vertex,
index,
tile,
// 图块变了,所以全部要更新
VertexUpdate.All,
dynamic
);
@ -560,6 +579,7 @@ export class MapVertexGenerator
assetIndex,
offsetIndex,
tile.frames,
// 图块变了,所以全部要更新
VertexUpdate.All,
dynamic
);
@ -590,6 +610,7 @@ export class MapVertexGenerator
const dIndex = dy * block.width + dx;
const index: BlockIndex = {
layer,
num,
mapX: x,
mapY: y,
mapIndex: y * this.mapWidth + x,
@ -790,8 +811,10 @@ export class MapVertexGenerator
const mapX = nx + block.dataX;
const mapY = ny + block.dataY;
const mapIndex = mapY * this.mapWidth + mapX;
const num = array[mapIndex];
const index: BlockIndex = {
layer,
num,
blockX: nx,
blockY: ny,
blockIndex: ny * block.width + nx,
@ -799,13 +822,7 @@ export class MapVertexGenerator
mapY,
mapIndex
};
this.updateVertexArray(
array,
vertex,
index,
array[mapIndex],
false
);
this.updateVertexArray(array, vertex, index, num, false);
}
}
});
@ -823,6 +840,7 @@ export class MapVertexGenerator
};
const index: IndexedBlockMapPos = {
layer: block.layer,
num: block.tile,
mapX: block.x,
mapY: block.y,
blockIndex: block.index
@ -833,7 +851,9 @@ export class MapVertexGenerator
logger.error(40, block.tile.toString());
return;
}
const update = updateTexture ? VertexUpdate.All : VertexUpdate.Position;
const update = updateTexture
? VertexUpdate.NoFrame
: VertexUpdate.Position;
if (cls === BlockCls.Autotile) {
// 自动元件使用全部不连接
const renderable = this.renderer.autotile.renderWithoutCheck(