@dao3fun/component
v3.3.1
Published
模拟Cocos Creator的组件系统,以模块化的方式构建和扩展节点,每个节点都可以附加多个功能组件,从而实现灵活且高效的游戏开发流程。
Readme
轻量级的神岛实体组件系统(ECS)框架
轻量级的实体组件系统(ECS)框架,专为 神岛引擎(Box3)设计,提供了一套完整的组件系统解决方案,帮助开发者构建可维护、可扩展的游戏项目。
更多详细信息请查看 https://docs.box3lab.com/arenapro/package/componentGuide/component/。
特性
- 🚀 高性能的组件更新系统
- 📊 内置性能监控和分析
- 🎯 基于装饰器的组件注册机制
- 🔄 事件驱动的观察者模式
- 🌐 支持服务端和客户端
核心概念
EntityNode
节点是最基础的场景元素容器,具有事件功能,相当于游戏世界的原子单位。
const node = new EntityNode(world.querySelector('#实体名称')!);
node.addComponent(new MovementComponent());Component
所有组件类的基类,提供组件的基本功能和接口。
@apclass('MovementComponent')
class MovementComponent extends Component {
update(deltaTime: number) {
// 实现更新逻辑
}
}事件系统
提供强大的事件处理机制:
// 使用全局事件总线
Emitter.on('gameStart', (event) => {
console.log('游戏开始');
});
// 游戏世界事件
GameWorldEvent.on(world.onPlayerJoin, ({ entity }) => {
console.log(`玩家 ${entity.player.name} 加入游戏`);
});性能监控
内置性能监控系统,帮助识别和解决性能问题:
// 启用全局性能监控
EntityNode.isMonitoringEnabled = true;
// 监听全局性能警告
EntityNode.onPerformanceWarning(({ component, executionTime, currentFPS }) => {
console.warn(
`组件 ${component.constructor.name} 执行时间过长: ${executionTime}ms`
);
});性能优化建议
- 合理使用组件的
enable属性 - 避免在
update方法中进行重复计算 - 利用性能监控数据优化组件逻辑
- 及时清理不需要的事件监听器
- 生产环境下可禁用性能监控
如何正确管理组件的事件监听?
class EventManagerComponent extends Component {
start(): void {
// 添加事件监听
GameWorldEvent.on(world.onPlayerJoin, this.handlePlayerJoin, this);
this.node.on('customEvent', this.handleCustomEvent, this);
}
onDestroy(): void {
// 清理事件监听
GameWorldEvent.off(world.onPlayerJoin, this.handlePlayerJoin, this);
this.node.off('customEvent', this.handleCustomEvent, this);
}
private handlePlayerJoin(): void {
// 处理玩家加入事件
}
private handleCustomEvent(): void {
// 处理自定义事件
}
}组件之间如何共享数据?
- 通过事件系统:适用于松耦合场景
// 发送方
this.node.emit('scoreChange', 100);
// 接收方
this.node.on('scoreChange', (score: number) => {
// 处理数据
});- 通过全局单例:适用于全局状态管理
class GameDataManager extends Component {
private static instance: GameDataManager;
public gameData = {
score: 0,
level: 1,
};
onLoad(): void {
GameDataManager.instance = this;
}
static getInstance(): GameDataManager {
return GameDataManager.instance;
}
}如何处理组件的异常情况?
class SafeComponent extends Component {
start(): void {
try {
this.initializeComponent();
} catch (error) {
console.error('组件初始化失败:', error);
// 优雅降级处理
this.handleError(error);
}
}
private handleError(error: Error): void {
// 1. 记录错误
console.error('组件错误:', error);
// 2. 尝试恢复
this.tryRecover();
// 3. 如果无法恢复,禁用组件
if (!this.canRecover()) {
this.enabled = false;
}
}
}组件配置如何管理?
- 使用配置接口
interface PlayerConfig {
speed: number;
jumpForce: number;
maxHealth: number;
}
class PlayerComponent extends Component {
private config: PlayerConfig = {
speed: 1,
jumpForce: 10,
maxHealth: 100,
};
// 通过 addComponent 时可以传入配置
// node.addComponent(PlayerComponent, { config: customConfig });
}如何处理组件的依赖关系?
class DependentComponent extends Component {
start(): void {
// 检查必要组件
const requiredComp = this.node.getComponent(RequiredComponent);
if (!requiredComp) {
console.error('缺少依赖组件 RequiredComponent');
this.enabled = false;
return;
}
// 自动添加依赖组件
if (!this.node.getComponent(AutoAddComponent)) {
this.node.addComponent(AutoAddComponent);
}
}
}如何实现组件的热重载?
class HotReloadableComponent extends Component<GameEntity> {
private state = {};
onDisable(): void {
// 保存状态
this.saveState();
}
onEnable(): void {
// 恢复状态
this.restoreState();
}
private saveState(): void {
// 保存需要在重载时保持的状态
this.state = {
position: this.node.entity.position.clone(),
data: this.getCurrentData(),
};
}
private restoreState(): void {
// 恢复之前保存的状态
if (this.state) {
this.node.entity.position = this.state.position;
this.setCurrentData(this.state.data);
}
}
}