2025-02-20 11:27:28 +08:00

278 lines
7.1 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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();
}
}