2025-12-16 12:46:14 +08:00
|
|
|
|
import type { IComponentRegistry, IScene } from '@esengine/ecs-framework';
|
2025-12-13 19:44:08 +08:00
|
|
|
|
import type { IRuntimeModule, IRuntimePlugin, ModuleManifest, SystemContext } from '@esengine/engine-core';
|
|
|
|
|
|
import { TransformTypeToken, CanvasElementToken } from '@esengine/engine-core';
|
2025-12-08 21:10:57 +08:00
|
|
|
|
import { AssetManagerToken } from '@esengine/asset-system';
|
2025-12-19 17:48:18 +08:00
|
|
|
|
import { RenderSystemToken, EngineIntegrationToken, TextureServiceToken, CoordinateServiceToken } from '@esengine/ecs-engine-bindgen';
|
2025-12-08 21:10:57 +08:00
|
|
|
|
import { Physics2DQueryToken } from '@esengine/physics-rapier2d';
|
2025-12-05 23:03:31 +08:00
|
|
|
|
import { ParticleSystemComponent } from './ParticleSystemComponent';
|
2025-12-13 19:44:08 +08:00
|
|
|
|
import { ClickFxComponent } from './ClickFxComponent';
|
2025-12-05 23:03:31 +08:00
|
|
|
|
import { ParticleUpdateSystem } from './systems/ParticleSystem';
|
2025-12-13 19:44:08 +08:00
|
|
|
|
import { ClickFxSystem } from './systems/ClickFxSystem';
|
2025-12-07 01:00:35 +08:00
|
|
|
|
import { ParticleLoader, ParticleAssetType } from './loaders/ParticleLoader';
|
2025-12-08 21:10:57 +08:00
|
|
|
|
import { ParticleUpdateSystemToken } from './tokens';
|
2025-12-05 23:03:31 +08:00
|
|
|
|
|
2025-12-13 19:44:08 +08:00
|
|
|
|
export type { SystemContext, ModuleManifest, IRuntimeModule, IRuntimePlugin };
|
2025-12-05 23:03:31 +08:00
|
|
|
|
|
2025-12-08 21:10:57 +08:00
|
|
|
|
// 重新导出 tokens | Re-export tokens
|
|
|
|
|
|
export { ParticleUpdateSystemToken } from './tokens';
|
2025-12-05 23:03:31 +08:00
|
|
|
|
|
|
|
|
|
|
class ParticleRuntimeModule implements IRuntimeModule {
|
|
|
|
|
|
private _updateSystem: ParticleUpdateSystem | null = null;
|
2025-12-07 01:00:35 +08:00
|
|
|
|
private _loaderRegistered = false;
|
2025-12-05 23:03:31 +08:00
|
|
|
|
|
2025-12-16 12:46:14 +08:00
|
|
|
|
registerComponents(registry: IComponentRegistry): void {
|
2025-12-05 23:03:31 +08:00
|
|
|
|
registry.register(ParticleSystemComponent);
|
2025-12-13 19:44:08 +08:00
|
|
|
|
registry.register(ClickFxComponent);
|
2025-12-05 23:03:31 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
createSystems(scene: IScene, context: SystemContext): void {
|
2025-12-08 21:10:57 +08:00
|
|
|
|
// 从服务注册表获取依赖 | Get dependencies from service registry
|
|
|
|
|
|
const assetManager = context.services.get(AssetManagerToken);
|
|
|
|
|
|
const transformType = context.services.get(TransformTypeToken);
|
|
|
|
|
|
const engineIntegration = context.services.get(EngineIntegrationToken);
|
2025-12-19 17:48:18 +08:00
|
|
|
|
const textureService = context.services.get(TextureServiceToken);
|
|
|
|
|
|
const coordinateService = context.services.get(CoordinateServiceToken);
|
2025-12-08 21:10:57 +08:00
|
|
|
|
const physics2DQuery = context.services.get(Physics2DQueryToken);
|
|
|
|
|
|
const renderSystem = context.services.get(RenderSystemToken);
|
2025-12-05 23:03:31 +08:00
|
|
|
|
|
2025-12-13 19:44:08 +08:00
|
|
|
|
// 注册粒子资产加载器到上下文的 assetManager
|
|
|
|
|
|
// Register particle asset loader to context assetManager
|
|
|
|
|
|
if (!this._loaderRegistered && assetManager) {
|
2025-12-07 01:00:35 +08:00
|
|
|
|
const loader = new ParticleLoader();
|
2025-12-13 19:44:08 +08:00
|
|
|
|
assetManager.registerLoader(ParticleAssetType, loader);
|
2025-12-07 01:00:35 +08:00
|
|
|
|
this._loaderRegistered = true;
|
2025-12-13 19:44:08 +08:00
|
|
|
|
console.log('[ParticleRuntimeModule] Registered ParticleLoader to context assetManager');
|
2025-12-07 01:00:35 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-12-05 23:03:31 +08:00
|
|
|
|
this._updateSystem = new ParticleUpdateSystem();
|
|
|
|
|
|
|
2025-12-13 19:44:08 +08:00
|
|
|
|
// 设置资产管理器 | Set asset manager
|
|
|
|
|
|
if (assetManager) {
|
|
|
|
|
|
this._updateSystem.setAssetManager(assetManager);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-12-05 23:03:31 +08:00
|
|
|
|
// 设置 Transform 组件类型 | Set Transform component type
|
2025-12-08 21:10:57 +08:00
|
|
|
|
if (transformType) {
|
|
|
|
|
|
this._updateSystem.setTransformType(transformType);
|
2025-12-05 23:03:31 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-12-07 01:00:35 +08:00
|
|
|
|
// 设置引擎集成(用于加载纹理)| Set engine integration (for loading textures)
|
2025-12-08 21:10:57 +08:00
|
|
|
|
if (engineIntegration) {
|
|
|
|
|
|
this._updateSystem.setEngineIntegration(engineIntegration);
|
2025-12-07 01:00:35 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-12-19 17:48:18 +08:00
|
|
|
|
// 设置纹理服务(用于加载默认纹理)| Set texture service (for loading default texture)
|
|
|
|
|
|
if (textureService) {
|
|
|
|
|
|
this._updateSystem.setTextureService(textureService);
|
2025-12-05 23:03:31 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-12-08 09:38:37 +08:00
|
|
|
|
// 设置 2D 物理查询(用于粒子与场景碰撞)| Set 2D physics query (for particle-scene collision)
|
2025-12-08 21:10:57 +08:00
|
|
|
|
if (physics2DQuery) {
|
|
|
|
|
|
this._updateSystem.setPhysics2DQuery(physics2DQuery);
|
2025-12-08 09:38:37 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-12-05 23:03:31 +08:00
|
|
|
|
scene.addSystem(this._updateSystem);
|
2025-12-08 21:10:57 +08:00
|
|
|
|
|
2025-12-13 19:44:08 +08:00
|
|
|
|
// 添加点击特效系统 | Add click FX system
|
2025-12-16 12:46:14 +08:00
|
|
|
|
// ClickFxSystem 不再需要 AssetManager,资产由 ParticleUpdateSystem 统一加载
|
|
|
|
|
|
// ClickFxSystem no longer needs AssetManager, assets are loaded by ParticleUpdateSystem
|
2025-12-13 19:44:08 +08:00
|
|
|
|
const clickFxSystem = new ClickFxSystem();
|
|
|
|
|
|
|
2025-12-19 17:48:18 +08:00
|
|
|
|
// 设置坐标服务(用于屏幕坐标转世界坐标)
|
|
|
|
|
|
// Set coordinate service (for screen to world coordinate conversion)
|
|
|
|
|
|
if (coordinateService) {
|
|
|
|
|
|
clickFxSystem.setCoordinateService(coordinateService);
|
2025-12-13 19:44:08 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 从服务注册表获取 Canvas 元素(用于计算相对坐标)
|
|
|
|
|
|
// Get canvas element from service registry (for calculating relative coordinates)
|
|
|
|
|
|
const canvas = context.services.get(CanvasElementToken);
|
|
|
|
|
|
if (canvas) {
|
|
|
|
|
|
clickFxSystem.setCanvas(canvas);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
scene.addSystem(clickFxSystem);
|
|
|
|
|
|
|
2025-12-08 21:10:57 +08:00
|
|
|
|
// 注册粒子更新系统到服务注册表 | Register particle update system to service registry
|
|
|
|
|
|
context.services.register(ParticleUpdateSystemToken, this._updateSystem);
|
2025-12-05 23:03:31 +08:00
|
|
|
|
|
|
|
|
|
|
// 注册渲染数据提供者 | Register render data provider
|
2025-12-08 21:10:57 +08:00
|
|
|
|
if (renderSystem) {
|
2025-12-05 23:03:31 +08:00
|
|
|
|
const renderDataProvider = this._updateSystem.getRenderDataProvider();
|
2025-12-08 21:10:57 +08:00
|
|
|
|
renderSystem.addRenderDataProvider(renderDataProvider);
|
2025-12-05 23:03:31 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 获取粒子更新系统
|
|
|
|
|
|
* Get particle update system
|
|
|
|
|
|
*/
|
|
|
|
|
|
get updateSystem(): ParticleUpdateSystem | null {
|
|
|
|
|
|
return this._updateSystem;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const manifest: ModuleManifest = {
|
|
|
|
|
|
id: 'particle',
|
|
|
|
|
|
name: '@esengine/particle',
|
|
|
|
|
|
displayName: 'Particle System',
|
|
|
|
|
|
version: '1.0.0',
|
|
|
|
|
|
description: 'Particle system for 2D effects',
|
|
|
|
|
|
category: 'Rendering',
|
|
|
|
|
|
icon: 'Sparkles',
|
|
|
|
|
|
isCore: false,
|
2025-12-07 01:00:35 +08:00
|
|
|
|
defaultEnabled: true,
|
2025-12-05 23:03:31 +08:00
|
|
|
|
isEngineModule: true,
|
|
|
|
|
|
canContainContent: true,
|
|
|
|
|
|
dependencies: ['core', 'math', 'sprite'],
|
2025-12-13 19:44:08 +08:00
|
|
|
|
exports: { components: ['ParticleSystemComponent', 'ClickFxComponent'] },
|
2025-12-05 23:03:31 +08:00
|
|
|
|
editorPackage: '@esengine/particle-editor',
|
|
|
|
|
|
requiresWasm: false
|
|
|
|
|
|
};
|
|
|
|
|
|
|
2025-12-13 19:44:08 +08:00
|
|
|
|
export const ParticlePlugin: IRuntimePlugin = {
|
2025-12-05 23:03:31 +08:00
|
|
|
|
manifest,
|
|
|
|
|
|
runtimeModule: new ParticleRuntimeModule()
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
export { ParticleRuntimeModule };
|