Files
esengine/source/src/ECS/Entity.ts

509 lines
16 KiB
TypeScript
Raw Normal View History

2020-07-22 20:07:14 +08:00
module es {
2020-11-26 20:02:53 +08:00
export class EntityComparer implements IComparer<Entity> {
public compare(self: Entity, other: Entity): number {
let compare = self.updateOrder - other.updateOrder;
if (compare == 0)
compare = self.id - other.id;
return compare;
}
}
2020-11-27 11:07:43 +08:00
export class Entity implements IEqualityComparable {
2020-11-26 20:02:53 +08:00
public static entityComparer: IComparer<Entity> = new EntityComparer();
2020-07-22 20:07:14 +08:00
/**
*
*/
public scene: Scene;
/**
*
*/
public name: string;
/**
*
*/
public readonly id: number;
/**
* //
*/
public readonly transform: Transform;
/**
*
*/
public readonly components: ComponentList;
2020-07-28 16:25:20 +08:00
/**
* entity update方法的频率12
*/
public updateInterval: number = 1;
2021-05-07 16:23:15 +08:00
public componentBits: Bits;
2020-07-28 16:25:20 +08:00
constructor(name: string, id: number) {
2020-07-28 16:25:20 +08:00
this.components = new ComponentList(this);
this.transform = new Transform(this);
2021-05-07 16:23:15 +08:00
this.componentBits = new Bits();
2020-07-28 16:25:20 +08:00
this.name = name;
this.id = id;
2020-07-28 16:25:20 +08:00
}
public _isDestroyed: boolean;
/**
* destroytrue
*/
public get isDestroyed() {
return this._isDestroyed;
}
private _tag: number = 0;
2020-07-22 20:07:14 +08:00
/**
* 使使
*/
public get tag(): number {
return this._tag;
}
2020-07-22 20:07:14 +08:00
/**
* 使使
* @param value
*/
public set tag(value: number) {
this.setTag(value);
}
2020-07-28 16:25:20 +08:00
private _enabled: boolean = true;
2020-07-22 20:07:14 +08:00
/**
* /
*/
public get enabled() {
return this._enabled;
}
2020-07-22 20:07:14 +08:00
/**
* /
* @param value
*/
public set enabled(value: boolean) {
this.setEnabled(value);
}
2020-07-08 18:12:17 +08:00
2020-07-28 16:25:20 +08:00
private _updateOrder: number = 0;
2020-07-22 20:07:14 +08:00
/**
* updateOrder还用于对scene.entities上的标签列表进行排序
*/
public get updateOrder() {
return this._updateOrder;
}
2020-06-08 23:04:57 +08:00
2020-07-22 20:07:14 +08:00
/**
* updateOrder还用于对scene.entities上的标签列表进行排序
* @param value
*/
public set updateOrder(value: number) {
this.setUpdateOrder(value);
}
2020-07-09 14:16:10 +08:00
2020-07-22 20:07:14 +08:00
public get parent(): Transform {
return this.transform.parent;
2020-06-08 18:26:05 +08:00
}
2020-07-22 20:07:14 +08:00
public set parent(value: Transform) {
this.transform.setParent(value);
}
2020-06-08 11:49:45 +08:00
2020-07-22 20:07:14 +08:00
public get childCount() {
return this.transform.childCount;
}
2020-06-09 22:32:18 +08:00
2020-07-22 20:07:14 +08:00
public get position(): Vector2 {
return this.transform.position;
}
2020-06-09 22:32:18 +08:00
2020-07-22 20:07:14 +08:00
public set position(value: Vector2) {
this.transform.setPosition(value.x, value.y);
}
2020-06-19 18:16:42 +08:00
public get localPosition(): Vector2 {
return this.transform.localPosition;
}
2020-07-28 16:25:20 +08:00
public set localPosition(value: Vector2) {
this.transform.setLocalPosition(value);
}
2020-07-22 20:07:14 +08:00
public get rotation(): number {
return this.transform.rotation;
}
2020-06-09 22:32:18 +08:00
2020-07-22 20:07:14 +08:00
public set rotation(value: number) {
this.transform.setRotation(value);
}
2020-07-09 14:16:10 +08:00
public get rotationDegrees(): number {
return this.transform.rotationDegrees;
}
2020-07-28 16:25:20 +08:00
public set rotationDegrees(value: number) {
this.transform.setRotationDegrees(value);
}
public get localRotation(): number {
return this.transform.localRotation;
}
2020-07-28 16:25:20 +08:00
public set localRotation(value: number) {
this.transform.setLocalRotation(value);
}
public get localRotationDegrees(): number {
return this.transform.localRotationDegrees;
}
2020-07-28 16:25:20 +08:00
public set localRotationDegrees(value: number) {
this.transform.setLocalRotationDegrees(value);
}
2020-06-08 16:23:48 +08:00
2020-07-22 20:07:14 +08:00
public get scale(): Vector2 {
return this.transform.scale;
}
2020-06-08 16:23:48 +08:00
2020-07-22 20:07:14 +08:00
public set scale(value: Vector2) {
this.transform.setScale(value);
}
2020-06-08 16:23:48 +08:00
public get localScale(): Vector2 {
return this.transform.localScale;
}
2020-07-28 16:25:20 +08:00
public set localScale(value: Vector2) {
this.transform.setLocalScale(value);
}
public get worldInverseTransform(): Matrix2D {
return this.transform.worldInverseTransform;
}
public get localToWorldTransform(): Matrix2D {
return this.transform.localToWorldTransform;
}
public get worldToLocalTransform(): Matrix2D {
return this.transform.worldToLocalTransform;
}
public onTransformChanged(comp: transform.Component) {
2020-07-22 20:07:14 +08:00
// 通知我们的子项改变了位置
this.components.onEntityTransformChanged(comp);
2020-06-08 16:23:48 +08:00
}
2020-06-08 11:49:45 +08:00
public setParent(parent: Entity);
public setParent(parent: Transform);
public setParent(parent: Transform | Entity) {
if (parent instanceof Transform) {
this.transform.setParent(parent);
} else if (parent instanceof Entity) {
this.transform.setParent(parent.transform);
}
return this;
}
public setPosition(x: number, y: number) {
this.transform.setPosition(x, y);
return this;
}
public setLocalPosition(localPosition: Vector2) {
this.transform.setLocalPosition(localPosition);
return this;
}
public setRotation(radians: number) {
this.transform.setRotation(radians);
return this;
}
public setRotationDegrees(degrees: number) {
this.transform.setRotationDegrees(degrees);
return this;
}
public setLocalRotation(radians: number) {
this.transform.setLocalRotation(radians);
return this;
}
public setLocalRotationDegrees(degrees: number) {
this.transform.setLocalRotationDegrees(degrees);
return this;
}
public setScale(scale: number);
public setScale(scale: Vector2);
public setScale(scale: Vector2 | number) {
if (scale instanceof Vector2) {
this.transform.setScale(scale);
} else {
this.transform.setScale(new Vector2(scale));
}
return this;
}
public setLocalScale(scale: number);
public setLocalScale(scale: Vector2);
public setLocalScale(scale: Vector2 | number) {
if (scale instanceof Vector2) {
this.transform.setLocalScale(scale);
} else {
this.transform.setLocalScale(new Vector2(scale));
}
return this;
}
2020-07-22 20:07:14 +08:00
/**
*
* @param tag
*/
public setTag(tag: number): Entity {
if (this._tag != tag) {
// 我们只有在已经有场景的情况下才会调用entityTagList。如果我们还没有场景我们会被添加到entityTagList
if (this.scene)
this.scene.entities.removeFromTagList(this);
this._tag = tag;
if (this.scene)
this.scene.entities.addToTagList(this);
2020-06-09 22:32:18 +08:00
}
2020-07-22 20:07:14 +08:00
return this;
}
2020-06-09 22:32:18 +08:00
2020-07-22 20:07:14 +08:00
/**
*
* @param isEnabled
*/
public setEnabled(isEnabled: boolean) {
if (this._enabled != isEnabled) {
this._enabled = isEnabled;
if (this._enabled)
this.components.onEntityEnabled();
else
this.components.onEntityDisabled();
}
2020-06-08 11:49:45 +08:00
2020-07-22 20:07:14 +08:00
return this;
2020-06-08 11:49:45 +08:00
}
2020-07-22 20:07:14 +08:00
/**
* updateOrder还用于对scene.entities上的标签列表进行排序
* @param updateOrder
*/
public setUpdateOrder(updateOrder: number) {
if (this._updateOrder != updateOrder) {
this._updateOrder = updateOrder;
if (this.scene) {
this.scene.entities.markEntityListUnsorted();
this.scene.entities.markTagUnsorted(this.tag);
2020-07-22 20:07:14 +08:00
}
return this;
}
}
2020-06-08 23:04:57 +08:00
2020-07-22 20:07:14 +08:00
/**
*
*/
public destroy() {
this._isDestroyed = true;
this.scene.identifierPool.checkIn(this.id);
2020-07-22 20:07:14 +08:00
this.scene.entities.remove(this);
this.transform.parent = null;
// 销毁所有子项
for (let i = this.transform.childCount - 1; i >= 0; i--) {
let child = this.transform.getChild(i);
child.entity.destroy();
}
}
2020-06-08 23:04:57 +08:00
2020-07-22 20:07:14 +08:00
/**
* 下面的生命周期方法将被调用在组件上:OnRemovedFromEntity
*/
public detachFromScene() {
this.scene.entities.remove(this);
this.components.deregisterAllComponents();
2020-06-08 16:23:48 +08:00
2020-07-22 20:07:14 +08:00
for (let i = 0; i < this.transform.childCount; i++)
this.transform.getChild(i).entity.detachFromScene();
}
2020-07-22 20:07:14 +08:00
/**
*
* @param newScene
*/
public attachToScene(newScene: Scene) {
this.scene = newScene;
newScene.entities.add(this);
this.components.registerAllComponents();
for (let i = 0; i < this.transform.childCount; i++) {
this.transform.getChild(i).entity.attachToScene(newScene);
}
}
2020-07-22 20:07:14 +08:00
/**
*
*/
public onAddedToScene() {
}
2020-06-16 00:04:28 +08:00
2020-07-22 20:07:14 +08:00
/**
*
*/
public onRemovedFromScene() {
// 如果已经被销毁了,移走我们的组件。如果我们只是分离,我们需要保持我们的组件在实体上。
if (this._isDestroyed)
this.components.removeAllComponents();
}
2020-07-08 18:12:17 +08:00
2020-07-22 20:07:14 +08:00
/**
*
*/
public update() {
this.components.update();
}
/**
*
* @param componentType
*/
2021-03-29 17:28:58 +08:00
public createComponent<T extends Component>(componentType: new (...args) => T): T {
let component = new componentType();
this.addComponent(component);
return component;
}
2020-07-22 20:07:14 +08:00
/**
*
* @param component
*/
public addComponent<T extends Component>(component: T): T {
component.entity = this;
this.components.add(component);
component.initialize();
return component;
}
2020-07-22 20:07:14 +08:00
/**
* T的第一个组件并返回它null
* @param type
*/
2021-03-29 17:28:58 +08:00
public getComponent<T extends Component>(type: new (...args) => T): T {
2021-01-26 10:49:25 +08:00
return this.components.getComponent(type, false);
2020-07-22 20:07:14 +08:00
}
2021-04-02 19:17:44 +08:00
/**
* T的第一个并已加入场景的组件并返回它null
* @param type
* @returns
*/
public getComponentInScene<T extends Component>(type: new (...args) => T): T {
return this.components.getComponent(type, true);
}
2021-03-26 12:53:09 +08:00
/**
* T类型的组件false
* @param type
* @param outComponent
* @returns
*/
2021-03-29 17:28:58 +08:00
public tryGetComponent<T extends Component>(type: new (...args) => T, outComponent: Ref<T>): boolean {
2021-03-26 12:53:09 +08:00
outComponent.value = this.components.getComponent<T>(type, false);
return outComponent.value != null;
}
2020-07-22 20:07:14 +08:00
/**
*
* @param type
*/
2021-04-01 15:48:30 +08:00
public hasComponent<T extends Component>(type: new (...args) => T) {
2020-07-22 20:07:14 +08:00
return this.components.getComponent<T>(type, false) != null;
}
2020-07-22 20:07:14 +08:00
/**
* T的第一个组件并返回它
* @param type
*/
2021-04-01 15:48:30 +08:00
public getOrCreateComponent<T extends Component>(type: new (...args) => T) {
let comp = this.components.getComponent<T>(type, true);
2020-07-22 20:07:14 +08:00
if (!comp) {
comp = this.addComponent<T>(new type());
2020-07-22 20:07:14 +08:00
}
2020-06-08 16:23:48 +08:00
2020-07-22 20:07:14 +08:00
return comp;
}
2020-06-08 23:04:57 +08:00
2020-07-22 20:07:14 +08:00
/**
* typeName类型的所有组件使
* @param typeName
* @param componentList
*/
public getComponents(typeName: any, componentList?) {
2020-07-22 20:07:14 +08:00
return this.components.getComponents(typeName, componentList);
}
2020-06-08 23:04:57 +08:00
2020-07-22 20:07:14 +08:00
/**
*
* @param component
*/
public removeComponent(component: Component) {
this.components.remove(component);
}
2020-06-08 23:04:57 +08:00
2020-07-22 20:07:14 +08:00
/**
* T的第一个组件
* @param type
*/
public removeComponentForType<T extends Component>(type) {
let comp = this.getComponent<T>(type);
if (comp) {
this.removeComponent(comp);
return true;
}
2020-07-09 14:16:10 +08:00
2020-07-22 20:07:14 +08:00
return false;
}
2020-06-08 11:49:45 +08:00
2020-07-22 20:07:14 +08:00
/**
*
*/
public removeAllComponents() {
for (let i = 0; i < this.components.count; i++) {
this.removeComponent(this.components.buffer[i]);
}
}
2020-07-09 14:16:10 +08:00
public compareTo(other: Entity): number {
let compare = this._updateOrder - other._updateOrder;
if (compare == 0)
compare = this.id - other.id;
return compare;
}
2020-11-27 11:07:43 +08:00
public equals(other: Entity): boolean {
return this.compareTo(other) == 0;
}
public getHashCode(): number {
return this.id;
}
2020-07-22 20:07:14 +08:00
public toString(): string {
return `[Entity: name: ${this.name}, tag: ${this.tag}, enabled: ${this.enabled}, depth: ${this.updateOrder}]`;
2020-06-08 11:49:45 +08:00
}
}
2020-07-08 18:12:17 +08:00
}