2025-06-30 20:43:11 +08:00
|
|
|
|
import type { IComponent } from '../Types';
|
2025-06-09 14:51:26 +08:00
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 游戏组件基类
|
2025-09-30 22:26:44 +08:00
|
|
|
|
*
|
|
|
|
|
|
* ECS架构中的组件(Component)应该是纯数据容器。
|
|
|
|
|
|
* 所有游戏逻辑应该在 EntitySystem 中实现,而不是在组件内部。
|
|
|
|
|
|
*
|
2025-06-09 14:51:26 +08:00
|
|
|
|
* @example
|
2025-09-30 22:26:44 +08:00
|
|
|
|
* 推荐做法:纯数据组件
|
2025-06-09 14:51:26 +08:00
|
|
|
|
* ```typescript
|
|
|
|
|
|
* class HealthComponent extends Component {
|
|
|
|
|
|
* public health: number = 100;
|
2025-09-30 22:26:44 +08:00
|
|
|
|
* public maxHealth: number = 100;
|
|
|
|
|
|
* }
|
|
|
|
|
|
* ```
|
|
|
|
|
|
*
|
|
|
|
|
|
* @example
|
|
|
|
|
|
* 推荐做法:在 System 中处理逻辑
|
|
|
|
|
|
* ```typescript
|
|
|
|
|
|
* class HealthSystem extends EntitySystem {
|
|
|
|
|
|
* process(entities: Entity[]): void {
|
|
|
|
|
|
* for (const entity of entities) {
|
|
|
|
|
|
* const health = entity.getComponent(HealthComponent);
|
|
|
|
|
|
* if (health && health.health <= 0) {
|
|
|
|
|
|
* entity.destroy();
|
|
|
|
|
|
* }
|
2025-06-09 14:51:26 +08:00
|
|
|
|
* }
|
|
|
|
|
|
* }
|
|
|
|
|
|
* }
|
|
|
|
|
|
* ```
|
|
|
|
|
|
*/
|
|
|
|
|
|
export abstract class Component implements IComponent {
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 组件ID生成器
|
2025-09-30 22:26:44 +08:00
|
|
|
|
*
|
2025-06-09 14:51:26 +08:00
|
|
|
|
* 用于为每个组件分配唯一的ID。
|
|
|
|
|
|
*/
|
|
|
|
|
|
public static _idGenerator: number = 0;
|
2025-09-30 22:26:44 +08:00
|
|
|
|
|
2025-06-09 14:51:26 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 组件唯一标识符
|
2025-09-30 22:26:44 +08:00
|
|
|
|
*
|
2025-06-09 14:51:26 +08:00
|
|
|
|
* 在整个游戏生命周期中唯一的数字ID。
|
|
|
|
|
|
*/
|
|
|
|
|
|
public readonly id: number;
|
|
|
|
|
|
|
2025-10-10 23:38:48 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 所属实体ID
|
|
|
|
|
|
*
|
|
|
|
|
|
* 存储实体ID而非引用,避免循环引用,符合ECS数据导向设计。
|
|
|
|
|
|
*/
|
|
|
|
|
|
public entityId: number | null = null;
|
|
|
|
|
|
|
2025-06-09 14:51:26 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* 创建组件实例
|
2025-09-30 22:26:44 +08:00
|
|
|
|
*
|
2025-06-09 14:51:26 +08:00
|
|
|
|
* 自动分配唯一ID给组件。
|
|
|
|
|
|
*/
|
|
|
|
|
|
constructor() {
|
|
|
|
|
|
this.id = Component._idGenerator++;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 组件添加到实体时的回调
|
2025-09-30 22:26:44 +08:00
|
|
|
|
*
|
2025-06-09 14:51:26 +08:00
|
|
|
|
* 当组件被添加到实体时调用,可以在此方法中进行初始化操作。
|
2025-09-30 22:26:44 +08:00
|
|
|
|
*
|
|
|
|
|
|
* @remarks
|
|
|
|
|
|
* 这是一个生命周期钩子,用于组件的初始化逻辑。
|
|
|
|
|
|
* 虽然保留此方法,但建议将复杂的初始化逻辑放在 System 中处理。
|
2025-06-09 14:51:26 +08:00
|
|
|
|
*/
|
|
|
|
|
|
public onAddedToEntity(): void {
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 组件从实体移除时的回调
|
2025-09-30 22:26:44 +08:00
|
|
|
|
*
|
2025-06-09 14:51:26 +08:00
|
|
|
|
* 当组件从实体中移除时调用,可以在此方法中进行清理操作。
|
2025-09-30 22:26:44 +08:00
|
|
|
|
*
|
|
|
|
|
|
* @remarks
|
|
|
|
|
|
* 这是一个生命周期钩子,用于组件的清理逻辑。
|
|
|
|
|
|
* 虽然保留此方法,但建议将复杂的清理逻辑放在 System 中处理。
|
2025-06-09 14:51:26 +08:00
|
|
|
|
*/
|
|
|
|
|
|
public onRemovedFromEntity(): void {
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-09-26 10:09:23 +08:00
|
|
|
|
}
|