feat: 添加跨平台运行时、资产系统和UI适配功能 (#256)

* feat(platform-common): 添加WASM加载器和环境检测API

* feat(rapier2d): 新增Rapier2D WASM绑定包

* feat(physics-rapier2d): 添加跨平台WASM加载器

* feat(asset-system): 添加运行时资产目录和bundle格式

* feat(asset-system-editor): 新增编辑器资产管理包

* feat(editor-core): 添加构建系统和模块管理

* feat(editor-app): 重构浏览器预览使用import maps

* feat(platform-web): 添加BrowserRuntime和资产读取

* feat(engine): 添加材质系统和着色器管理

* feat(material): 新增材质系统和着色器编辑器

* feat(tilemap): 增强tilemap编辑器和动画系统

* feat(modules): 添加module.json配置

* feat(core): 添加module.json和类型定义更新

* chore: 更新依赖和构建配置

* refactor(plugins): 更新插件模板使用ModuleManifest

* chore: 添加第三方依赖库

* chore: 移除BehaviourTree-ai和ecs-astar子模块

* docs: 更新README和文档主题样式

* fix: 修复Rust文档测试和添加rapier2d WASM绑定

* fix(tilemap-editor): 修复画布高DPI屏幕分辨率适配问题

* feat(ui): 添加UI屏幕适配系统(CanvasScaler/SafeArea)

* fix(ecs-engine-bindgen): 添加缺失的ecs-framework-math依赖

* fix: 添加缺失的包依赖修复CI构建

* fix: 修复CodeQL检测到的代码问题

* fix: 修复构建错误和缺失依赖

* fix: 修复类型检查错误

* fix(material-system): 修复tsconfig配置支持TypeScript项目引用

* fix(editor-core): 修复Rollup构建配置添加tauri external

* fix: 修复CodeQL检测到的代码问题

* fix: 修复CodeQL检测到的代码问题
This commit is contained in:
YHH
2025-12-03 22:15:22 +08:00
committed by GitHub
parent caf7622aa0
commit 63f006ab62
496 changed files with 77601 additions and 4067 deletions

View File

@@ -11,6 +11,41 @@ export type ResizeAnchor =
| 'middle-left' | 'center' | 'middle-right'
| 'bottom-left' | 'bottom-center' | 'bottom-right';
/**
* Animation frame definition
* 动画帧定义
*/
export interface ITileAnimationFrame {
/** Tile ID to display for this frame (local ID within tileset) | 此帧显示的瓦片ID图块集内的本地ID */
tileId: number;
/** Frame duration in milliseconds | 帧持续时间(毫秒) */
duration: number;
}
/**
* Tile animation definition
* 瓦片动画定义
*/
export interface ITileAnimation {
/** Animation frame sequence | 动画帧序列 */
frames: ITileAnimationFrame[];
}
/**
* Individual tile metadata
* 单个瓦片元数据
*/
export interface ITileMetadata {
/** Tile ID (local ID within tileset) | 瓦片ID图块集内的本地ID */
id: number;
/** Tile class/type | 瓦片类型 */
type?: string;
/** Custom properties | 自定义属性 */
properties?: Record<string, unknown>;
/** Tile animation (if any) | 瓦片动画(如果有) */
animation?: ITileAnimation;
}
/**
* Tileset data interface
* 图块集数据接口
@@ -41,11 +76,7 @@ export interface ITilesetData {
/** Spacing between tiles in pixels | 图块间距(像素) */
spacing?: number;
/** Individual tile metadata | 单个图块元数据 */
tiles?: Array<{
id: number;
type?: string;
properties?: Record<string, unknown>;
}>;
tiles?: ITileMetadata[];
}
/**
@@ -69,6 +100,14 @@ export interface ITilemapLayerData {
offsetX?: number;
/** Layer Y offset in pixels | 图层Y偏移像素 */
offsetY?: number;
/** Material asset path for this layer (.mat file) | 此图层的材质资源路径(.mat 文件) */
materialPath?: string;
/** Runtime material ID (set after loading) | 运行时材质ID加载后设置 */
materialId?: number;
/** Tint color in hex format | 着色颜色(十六进制格式) */
color?: string;
/** Hidden in game (visible only in editor) | 游戏中隐藏(仅在编辑器中可见) */
hiddenInGame?: boolean;
/** Custom layer properties | 自定义图层属性 */
properties?: Record<string, unknown>;
}
@@ -440,6 +479,40 @@ export class TilemapComponent extends Component implements IResourceComponent {
return layer;
}
/**
* Duplicate a layer
* 复制图层
* @param index Layer index to duplicate | 要复制的图层索引
* @returns The duplicated layer data, or null if index is invalid | 复制的图层数据,如果索引无效则返回 null
*/
duplicateLayer(index: number): ITilemapLayerData | null {
if (index < 0 || index >= this._layers.length) {
return null;
}
const sourceLayer = this._layers[index];
const sourceData = this._layersData.get(sourceLayer.id);
if (!sourceData) {
return null;
}
const id = `layer_${Date.now()}_${Math.random().toString(36).substring(2, 11)}`;
const newLayer: ITilemapLayerData = {
id,
name: `${sourceLayer.name} (副本)`,
visible: sourceLayer.visible,
opacity: sourceLayer.opacity,
data: Array.from(sourceData)
};
// Insert after the source layer
this._layers.splice(index + 1, 0, newLayer);
this._layersData.set(id, new Uint32Array(sourceData));
this.renderDirty = true;
return newLayer;
}
/**
* Remove a layer by index (cannot remove last layer)
* 按索引移除图层(不能移除最后一个图层)
@@ -527,6 +600,96 @@ export class TilemapComponent extends Component implements IResourceComponent {
}
}
/**
* Set layer color (tint)
* 设置图层颜色(着色)
*/
setLayerColor(index: number, color: string): void {
if (index >= 0 && index < this._layers.length) {
this._layers[index].color = color;
this.renderDirty = true;
}
}
/**
* Get layer color
* 获取图层颜色
*/
getLayerColor(index: number): string {
if (index >= 0 && index < this._layers.length) {
return this._layers[index].color ?? '#ffffff';
}
return '#ffffff';
}
/**
* Set layer hidden in game
* 设置图层在游戏中隐藏
*/
setLayerHiddenInGame(index: number, hidden: boolean): void {
if (index >= 0 && index < this._layers.length) {
this._layers[index].hiddenInGame = hidden;
}
}
/**
* Get layer hidden in game
* 获取图层在游戏中是否隐藏
*/
getLayerHiddenInGame(index: number): boolean {
if (index >= 0 && index < this._layers.length) {
return this._layers[index].hiddenInGame ?? false;
}
return false;
}
/**
* Set layer material path
* 设置图层材质路径
* @param index Layer index | 图层索引
* @param materialPath Material asset path (.mat file) | 材质资源路径(.mat 文件)
*/
setLayerMaterial(index: number, materialPath: string): void {
if (index >= 0 && index < this._layers.length) {
this._layers[index].materialPath = materialPath;
this._layers[index].materialId = undefined;
this.renderDirty = true;
}
}
/**
* Get layer material path
* 获取图层材质路径
* @param index Layer index | 图层索引
* @returns Material path or undefined | 材质路径或 undefined
*/
getLayerMaterial(index: number): string | undefined {
return this._layers[index]?.materialPath;
}
/**
* Set layer material ID (runtime)
* 设置图层材质ID运行时
* @param index Layer index | 图层索引
* @param materialId Runtime material ID | 运行时材质ID
*/
setLayerMaterialId(index: number, materialId: number): void {
if (index >= 0 && index < this._layers.length) {
this._layers[index].materialId = materialId;
this.renderDirty = true;
}
}
/**
* Get layer material ID
* 获取图层材质ID
* @param index Layer index | 图层索引
* @returns Material ID or 0 (default) | 材质ID 或 0默认
*/
getLayerMaterialId(index: number): number {
return this._layers[index]?.materialId ?? 0;
}
// ===== Tile Operations | 瓦片操作 =====
/**
@@ -591,6 +754,22 @@ export class TilemapComponent extends Component implements IResourceComponent {
return this._layersData.get(layer.id);
}
/**
* Set raw tile data array for a layer
* 设置图层的原始图块数据数组
* @param layerIndex Layer index | 图层索引
* @param data Uint32Array of tile indices | 图块索引的Uint32Array
*/
setLayerData(layerIndex: number, data: Uint32Array): void {
const layer = this._layers[layerIndex];
if (!layer) return;
// Copy data to both the layer object and the internal map
layer.data = Array.from(data);
this._layersData.set(layer.id, new Uint32Array(data));
this.renderDirty = true;
}
/**
* Get merged tile data from all visible layers
* 获取所有可见图层合并后的图块数据
@@ -846,8 +1025,8 @@ export class TilemapComponent extends Component implements IResourceComponent {
// Parse anchor to get X and Y alignment
// 解析锚点获取X和Y方向的对齐方式
let xAnchor: 'start' | 'center' | 'end' = 'start';
let yAnchor: 'start' | 'center' | 'end' = 'end'; // 'end' means bottom in Y-up system
let xAnchor: 'start' | 'center' | 'end';
let yAnchor: 'start' | 'center' | 'end';
if (anchor.includes('left')) xAnchor = 'start';
else if (anchor.includes('right')) xAnchor = 'end';
@@ -1002,6 +1181,18 @@ export class TilemapComponent extends Component implements IResourceComponent {
}
}
// 收集所有图层材质引用
// Collect all layer material references
for (const layer of this._layers) {
if (layer.materialPath) {
refs.push({
path: layer.materialPath,
type: 'data',
runtimeId: layer.materialId
});
}
}
return refs;
}
@@ -1021,6 +1212,17 @@ export class TilemapComponent extends Component implements IResourceComponent {
}
}
// 为每个图层设置材质 ID
// Set material ID for each layer
for (const layer of this._layers) {
if (layer.materialPath) {
const materialId = pathToId.get(layer.materialPath);
if (materialId !== undefined) {
layer.materialId = materialId;
}
}
}
// 标记渲染数据为脏,需要重新构建
// Mark render data as dirty, needs rebuild
this.renderDirty = true;