119 lines
4.1 KiB
TypeScript
119 lines
4.1 KiB
TypeScript
|
|
import { EntitySystem, Matcher, ECSSystem, Time, Entity } from '@esengine/ecs-framework';
|
|||
|
|
import { ParticleSystemComponent } from '../ParticleSystemComponent';
|
|||
|
|
import { ParticleRenderDataProvider } from '../rendering/ParticleRenderDataProvider';
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Transform 组件接口(避免直接依赖 engine-core)
|
|||
|
|
* Transform component interface (avoid direct dependency on engine-core)
|
|||
|
|
*/
|
|||
|
|
interface ITransformComponent {
|
|||
|
|
worldPosition?: { x: number; y: number; z: number };
|
|||
|
|
position: { x: number; y: number; z: number };
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 粒子更新系统
|
|||
|
|
* Particle update system
|
|||
|
|
*
|
|||
|
|
* Updates all ParticleSystemComponents with their entity's world position.
|
|||
|
|
* 使用实体的世界坐标更新所有粒子系统组件。
|
|||
|
|
*/
|
|||
|
|
@ECSSystem('ParticleUpdate', { updateOrder: 100 })
|
|||
|
|
export class ParticleUpdateSystem extends EntitySystem {
|
|||
|
|
private _transformType: (new (...args: any[]) => ITransformComponent) | null = null;
|
|||
|
|
private _renderDataProvider: ParticleRenderDataProvider;
|
|||
|
|
|
|||
|
|
constructor() {
|
|||
|
|
super(Matcher.empty().all(ParticleSystemComponent));
|
|||
|
|
this._renderDataProvider = new ParticleRenderDataProvider();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 设置 Transform 组件类型
|
|||
|
|
* Set Transform component type
|
|||
|
|
*
|
|||
|
|
* @param transformType - Transform component class | Transform 组件类
|
|||
|
|
*/
|
|||
|
|
setTransformType(transformType: new (...args: any[]) => ITransformComponent): void {
|
|||
|
|
this._transformType = transformType;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 获取渲染数据提供者
|
|||
|
|
* Get render data provider
|
|||
|
|
*/
|
|||
|
|
getRenderDataProvider(): ParticleRenderDataProvider {
|
|||
|
|
return this._renderDataProvider;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
protected override process(entities: readonly Entity[]): void {
|
|||
|
|
const deltaTime = Time.deltaTime;
|
|||
|
|
|
|||
|
|
for (const entity of entities) {
|
|||
|
|
if (!entity.enabled) continue;
|
|||
|
|
|
|||
|
|
const particle = entity.getComponent(ParticleSystemComponent) as ParticleSystemComponent | null;
|
|||
|
|
if (!particle) continue;
|
|||
|
|
|
|||
|
|
let worldX = 0;
|
|||
|
|
let worldY = 0;
|
|||
|
|
let transform: ITransformComponent | null = null;
|
|||
|
|
|
|||
|
|
// 获取 Transform 位置 | Get Transform position
|
|||
|
|
if (this._transformType) {
|
|||
|
|
transform = entity.getComponent(this._transformType as any) as ITransformComponent | null;
|
|||
|
|
if (transform) {
|
|||
|
|
const pos = transform.worldPosition ?? transform.position;
|
|||
|
|
worldX = pos.x;
|
|||
|
|
worldY = pos.y;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 更新粒子系统 | Update particle system
|
|||
|
|
if (particle.isPlaying) {
|
|||
|
|
particle.update(deltaTime, worldX, worldY);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 更新渲染数据提供者的 Transform 引用 | Update render data provider's Transform reference
|
|||
|
|
if (transform) {
|
|||
|
|
this._renderDataProvider.register(particle, transform);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 标记渲染数据需要更新 | Mark render data as dirty
|
|||
|
|
this._renderDataProvider.markDirty();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
protected override onAdded(entity: Entity): void {
|
|||
|
|
const particle = entity.getComponent(ParticleSystemComponent) as ParticleSystemComponent | null;
|
|||
|
|
if (particle) {
|
|||
|
|
particle.initialize();
|
|||
|
|
|
|||
|
|
// 注册到渲染数据提供者 | Register to render data provider
|
|||
|
|
if (this._transformType) {
|
|||
|
|
const transform = entity.getComponent(this._transformType as any) as ITransformComponent | null;
|
|||
|
|
if (transform) {
|
|||
|
|
this._renderDataProvider.register(particle, transform);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
protected override onRemoved(entity: Entity): void {
|
|||
|
|
const particle = entity.getComponent(ParticleSystemComponent) as ParticleSystemComponent | null;
|
|||
|
|
if (particle) {
|
|||
|
|
// 从渲染数据提供者注销 | Unregister from render data provider
|
|||
|
|
this._renderDataProvider.unregister(particle);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 系统销毁时清理
|
|||
|
|
* Cleanup on system destroy
|
|||
|
|
*/
|
|||
|
|
public override destroy(): void {
|
|||
|
|
super.destroy();
|
|||
|
|
this._renderDataProvider.dispose();
|
|||
|
|
}
|
|||
|
|
}
|