2025-11-25 22:23:19 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* Tilemap asset loader
|
|
|
|
|
|
* 瓦片地图资产加载器
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
import {
|
2025-12-03 16:20:34 +08:00
|
|
|
|
IAssetLoader,
|
|
|
|
|
|
IAssetContent,
|
|
|
|
|
|
IAssetParseContext,
|
|
|
|
|
|
AssetContentType
|
2025-11-25 22:23:19 +08:00
|
|
|
|
} from '@esengine/asset-system';
|
2025-12-01 22:28:51 +08:00
|
|
|
|
import { TilemapAssetType } from '../constants';
|
2025-11-25 22:23:19 +08:00
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* Tilemap data interface
|
|
|
|
|
|
* 瓦片地图数据接口
|
|
|
|
|
|
*/
|
|
|
|
|
|
export interface ITilemapAsset {
|
|
|
|
|
|
/** 名称 */
|
|
|
|
|
|
name: string;
|
|
|
|
|
|
/** 版本 */
|
|
|
|
|
|
version: number;
|
|
|
|
|
|
/** 宽度(瓦片数) */
|
|
|
|
|
|
width: number;
|
|
|
|
|
|
/** 高度(瓦片数) */
|
|
|
|
|
|
height: number;
|
|
|
|
|
|
/** 瓦片宽度(像素) */
|
|
|
|
|
|
tileWidth: number;
|
|
|
|
|
|
/** 瓦片高度(像素) */
|
|
|
|
|
|
tileHeight: number;
|
|
|
|
|
|
/** 瓦片集资源GUID */
|
|
|
|
|
|
tileset: string;
|
|
|
|
|
|
/** 瓦片数据(行主序,0表示空) */
|
|
|
|
|
|
data: number[];
|
|
|
|
|
|
/** 图层(可选) */
|
|
|
|
|
|
layers?: Array<{
|
|
|
|
|
|
name: string;
|
|
|
|
|
|
visible: boolean;
|
|
|
|
|
|
opacity: number;
|
|
|
|
|
|
data?: number[];
|
2025-12-03 16:20:34 +08:00
|
|
|
|
/** 材质路径 */
|
|
|
|
|
|
materialPath?: string;
|
2025-11-25 22:23:19 +08:00
|
|
|
|
}>;
|
|
|
|
|
|
/** 碰撞数据(可选) */
|
|
|
|
|
|
collisionData?: number[];
|
|
|
|
|
|
/** 自定义属性 */
|
|
|
|
|
|
properties?: Record<string, unknown>;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* Tilemap loader implementation
|
|
|
|
|
|
* 瓦片地图加载器实现
|
|
|
|
|
|
*/
|
|
|
|
|
|
export class TilemapLoader implements IAssetLoader<ITilemapAsset> {
|
2025-11-29 23:00:48 +08:00
|
|
|
|
readonly supportedType = TilemapAssetType;
|
2025-11-25 22:23:19 +08:00
|
|
|
|
readonly supportedExtensions = ['.tilemap.json', '.tilemap'];
|
2025-12-03 16:20:34 +08:00
|
|
|
|
readonly contentType: AssetContentType = 'text';
|
2025-11-25 22:23:19 +08:00
|
|
|
|
|
|
|
|
|
|
/**
|
2025-12-03 16:20:34 +08:00
|
|
|
|
* Parse tilemap asset from text content
|
|
|
|
|
|
* 从文本内容解析瓦片地图资产
|
2025-11-25 22:23:19 +08:00
|
|
|
|
*/
|
2025-12-03 16:20:34 +08:00
|
|
|
|
async parse(content: IAssetContent, _context: IAssetParseContext): Promise<ITilemapAsset> {
|
|
|
|
|
|
if (!content.text) {
|
|
|
|
|
|
throw new Error('Tilemap content is empty');
|
2025-11-25 22:23:19 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-12-03 16:20:34 +08:00
|
|
|
|
const jsonData = JSON.parse(content.text) as ITilemapAsset;
|
2025-11-25 22:23:19 +08:00
|
|
|
|
|
2025-12-03 16:20:34 +08:00
|
|
|
|
// 验证必要字段
|
|
|
|
|
|
// Validate required fields
|
|
|
|
|
|
if (!jsonData.width || !jsonData.height || !jsonData.data) {
|
|
|
|
|
|
throw new Error('Invalid tilemap format: missing required fields');
|
2025-11-25 22:23:19 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-12-03 16:20:34 +08:00
|
|
|
|
return jsonData;
|
2025-11-25 22:23:19 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* Dispose loaded asset
|
|
|
|
|
|
* 释放已加载的资产
|
|
|
|
|
|
*/
|
|
|
|
|
|
dispose(asset: ITilemapAsset): void {
|
|
|
|
|
|
(asset as any).data = null;
|
|
|
|
|
|
(asset as any).layers = null;
|
|
|
|
|
|
(asset as any).collisionData = null;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|