Files
kunpolibrary/src/ecmodule/Entity.ts
T
2025-02-20 11:27:28 +08:00

278 lines
7.1 KiB
TypeScript

import { Component } from "./Component";
import { EntityId } from "./ECType";
import { EntityManager } from "./EntityManager";
export class Entity {
/**
* 实体名称
* @type {String}
*/
public name: string;
/**
* 实体ID
* @type {EntityId}
*/
public id: EntityId;
/**
* 实体标识
* @type {Set<number>}
* @memberof Entity
*/
public tags: Set<number>;
/**
* 实体状态
* @type {Map<number, number>}
* @memberof Entity
*/
public states: Map<number, number>;
/**
* 是否被激活 (添加到实体管理器时激活)
* @type {boolean}
*/
public active: boolean = false;
/**
* 所属实体管理器 (实体创建后直接赋值)
* @private
* @type {EntityManager}
*/
public entityManager: EntityManager;
/**
* 所有组件
* @type {Map<number, Component>}
* @type {number} 组件类型
* @type {Component} 组件
*/
public readonly components: Map<number, Component> = new Map();
/**
* 实体被添加到EntityManager
*/
// eslint-disable-next-line @typescript-eslint/naming-convention
public _add(): void {
this.active = true;
for (const component of this.components.values()) {
component._enter();
}
}
/**
* 实体销毁,不要手动调用
* @memberof Entity
*/
// eslint-disable-next-line @typescript-eslint/naming-convention
public _destroy(): void {
this.removeAllComponents();
this.tags && this.tags.clear();
this.states && this.states.clear();
this.active = false;
this.entityManager = null;
}
/**
* 添加标签
* @param {number[]} ...tags 标签除了表示Entity,还可以通过EntityManager获取指定标签的Entity
*/
public addTag(...tag: number[]): void {
let tags = this.tags;
if (!tags) {
tags = this.tags = new Set<number>();
}
for (let i = 0; i < tag.length; i++) {
tags.add(tag[i]);
this.active && this.entityManager && this.entityManager._addEntityTag(this.id, tag[i]);
}
}
/**
* 删除标签
* @param {number} tag 删除的标签
*/
public removeTag(tag: number): void {
if (this.tags) {
this.tags.delete(tag);
this.active && this.entityManager && this.entityManager._removeEntityTagById(this.id, tag);
}
}
/**
* 是否包含标签
* @param {number} tag 标签
* @returns {boolean} 是否包含
*/
public hasTag(...tag: number[]): boolean {
let tags = this.tags;
if (!tags) {
return false;
}
for (let i = 0; i < tag.length; i++) {
if (tags.has(tag[i])) {
return true;
}
}
return false;
}
/**
* 获取组件
* @param {number} componentType 组件类型
* @returns {T}
*/
public getComponent<T extends Component>(componentType: number): T {
return this.components.get(componentType) as T;
}
/**
* 添加组件
* @param {Component} component 组件
*/
public addComponent(component: Component): void {
if (this.hasComponent(component.type)) {
throw new Error(`组件{${component.constructor.name}类型:${component.type})已经存在,不允许添加同一类型组件`);
}
this.components.set(component.type, component);
component.entity = this;
component._add();
if (this.active) {
component._enter();
}
}
/**
* 删除组件
* @param {number} componentType 组件类型
*/
public removeComponent(componentType: number): void {
const component = this.components.get(componentType);
if (component) {
this.components.delete(componentType);
component._remove();
}
}
/**
* 删除所有组件
*/
public removeAllComponents(): void {
for (const component of this.components.values()) {
component._remove();
}
this.components.clear();
}
/**
* 是否包含组件
* @param {number} componentType 组件类型
* @returns {boolean} 是否包含组件
*/
public hasComponent(componentType: number): boolean {
return this.components.has(componentType);
}
/**
* 销毁自己
*/
public destroy(): void {
this.entityManager.destroyEntityById(this.id);
}
/**
* 添加监听
* @param eventName 监听的消息名
* @param callback 回调
* @param entityId 实体ID
* @param once 是否单次监听
*/
public addEvent(eventName: string, callback: (...args: any[]) => void, once: boolean = false): void {
this.entityManager && this.entityManager._addEvent(eventName, callback, this, once);
}
/**
* 发送消息
* @param eventName 消息名
* @param entityId 实体ID
* @param args 发送参数
*/
public sendListener(eventName: string, ...args: any[]): void {
this.entityManager && this.entityManager._sendEvent(eventName, this, ...args);
}
public removeListener(eventName: string, callback?: (...args: any[]) => void): void {
this.entityManager && this.entityManager._removeEvent(eventName, this, callback);
}
/**
* 添加状态
* 状态采用计数方式,对状态处理时需要保证addState和removeState成对存在
* @param {number} state 状态类型
* @memberof Entity
*/
public addState(state: number): void {
let states = this.states;
if (!states) {
states = this.states = new Map<number, number>();
}
states.set(state, (states.get(state) || 0) + 1);
}
/**
* 删除状态
*
* @param {number} state 状态类型
* @returns {boolean} 如果计数为0或状态不存在,则返回true
* @memberof Entity
*/
public removeState(state: number): boolean {
const states = this.states;
if (!states) {
return false;
}
let stateCount = states.get(state);
if (stateCount) {
// 处理状态计数,为0则删除状态
--stateCount;
if (stateCount == 0) {
states.delete(state);
return true;
}
states.set(state, stateCount);
return false;
}
return true;
}
/**
* 是否包含指定状态
* @param {number} state 状态
* @returns {boolean}
* @memberof Entity
*/
public hasState(state: number): boolean {
return this.states && this.states.has(state);
}
/**
* 清除状态
* @param {number} state 状态
* @memberof Entity
*/
public clearState(state: number): void {
this.states && this.states.delete(state);
}
/**
* 清除所有状态
* @memberof Entity
*/
public clearAllStates(): void {
this.states && this.states.clear();
}
}