整理ecs框架
This commit is contained in:
@@ -1,96 +1,137 @@
|
||||
abstract class Component extends egret.DisplayObjectContainer {
|
||||
public entity: Entity;
|
||||
private _enabled: boolean = true;
|
||||
public updateInterval: number = 1;
|
||||
/** 允许用户为实体存入信息 */
|
||||
public userData: any;
|
||||
private _updateOrder = 0;
|
||||
|
||||
public get enabled(){
|
||||
return this.entity ? this.entity.enabled && this._enabled : this._enabled;
|
||||
}
|
||||
|
||||
public set enabled(value: boolean){
|
||||
this.setEnabled(value);
|
||||
}
|
||||
|
||||
public get localPosition(){
|
||||
return new Vector2(this.entity.x + this.x, this.entity.y + this.y);
|
||||
}
|
||||
|
||||
public setEnabled(isEnabled: boolean){
|
||||
if (this._enabled != isEnabled){
|
||||
this._enabled = isEnabled;
|
||||
|
||||
if (this._enabled){
|
||||
this.onEnabled();
|
||||
}else{
|
||||
this.onDisabled();
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/** 更新此实体上组件的顺序 */
|
||||
public get updateOrder(){
|
||||
return this._updateOrder;
|
||||
}
|
||||
/** 更新此实体上组件的顺序 */
|
||||
public set updateOrder(value: number){
|
||||
this.setUpdateOrder(value);
|
||||
}
|
||||
public setUpdateOrder(updateOrder: number){
|
||||
if (this._updateOrder != updateOrder){
|
||||
this._updateOrder = updateOrder;
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public initialize(){
|
||||
}
|
||||
|
||||
public onAddedToEntity(){
|
||||
|
||||
}
|
||||
|
||||
public onRemovedFromEntity(){
|
||||
|
||||
}
|
||||
|
||||
public onEnabled(){
|
||||
|
||||
}
|
||||
|
||||
public onDisabled(){
|
||||
|
||||
}
|
||||
|
||||
public debugRender(){
|
||||
|
||||
}
|
||||
|
||||
public update(){
|
||||
|
||||
}
|
||||
|
||||
module es {
|
||||
/**
|
||||
* 当实体的位置改变时调用。这允许组件知道它们由于父实体的移动而移动了。
|
||||
* @param comp
|
||||
* 执行顺序
|
||||
* - onAddedToEntity
|
||||
* - OnEnabled
|
||||
*
|
||||
* 删除执行顺序
|
||||
* - onRemovedFromEntity
|
||||
*/
|
||||
public onEntityTransformChanged(comp: TransformComponent){
|
||||
export abstract class Component {
|
||||
/**
|
||||
* 此组件附加的实体
|
||||
*/
|
||||
public entity: Entity;
|
||||
|
||||
}
|
||||
/**
|
||||
* 快速访问 this.entity.transform
|
||||
*/
|
||||
public get transform(): Transform {
|
||||
return this.entity.transform;
|
||||
}
|
||||
|
||||
/** 内部使用 运行时不应该调用 */
|
||||
public registerComponent(){
|
||||
this.entity.componentBits.set(ComponentTypeManager.getIndexFor(this), false);
|
||||
this.entity.scene.entityProcessors.onComponentAdded(this.entity);
|
||||
}
|
||||
/**
|
||||
* 如果组件和实体都已启用,则为。当启用该组件时,将调用该组件的生命周期方法。状态的改变会导致调用onEnabled/onDisable。
|
||||
*/
|
||||
public get enabled() {
|
||||
return this.entity ? this.entity.enabled && this._enabled : this._enabled;
|
||||
}
|
||||
|
||||
public deregisterComponent(){
|
||||
this.entity.componentBits.set(ComponentTypeManager.getIndexFor(this));
|
||||
this.entity.scene.entityProcessors.onComponentRemoved(this.entity);
|
||||
/**
|
||||
* 如果组件和实体都已启用,则为。当启用该组件时,将调用该组件的生命周期方法。状态的改变会导致调用onEnabled/onDisable。
|
||||
* @param value
|
||||
*/
|
||||
public set enabled(value: boolean) {
|
||||
this.setEnabled(value);
|
||||
}
|
||||
|
||||
/** 更新此实体上组件的顺序 */
|
||||
public get updateOrder() {
|
||||
return this._updateOrder;
|
||||
}
|
||||
|
||||
/** 更新此实体上组件的顺序 */
|
||||
public set updateOrder(value: number) {
|
||||
this.setUpdateOrder(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新该组件的时间间隔。这与实体的更新间隔无关。
|
||||
*/
|
||||
public updateInterval: number = 1;
|
||||
|
||||
private _enabled: boolean = true;
|
||||
private _updateOrder = 0;
|
||||
|
||||
/**
|
||||
* 当此组件已分配其实体,但尚未添加到实体的活动组件列表时调用。有用的东西,如物理组件,需要访问转换来修改碰撞体的属性。
|
||||
*/
|
||||
public initialize() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 在提交所有挂起的组件更改后,将该组件添加到场景时调用。此时,设置了实体字段和实体。场景也设定好了。
|
||||
*/
|
||||
public onAddedToEntity() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 当此组件从其实体中移除时调用。在这里做所有的清理工作。
|
||||
*/
|
||||
public onRemovedFromEntity() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 当实体的位置改变时调用。这允许组件知道它们由于父实体的移动而移动了。
|
||||
* @param comp
|
||||
*/
|
||||
public onEntityTransformChanged(comp: Transform.Component) {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public debugRender() {
|
||||
}
|
||||
|
||||
/**
|
||||
*当父实体或此组件启用时调用
|
||||
*/
|
||||
public onEnabled() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 禁用父实体或此组件时调用
|
||||
*/
|
||||
public onDisabled() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 当该组件启用时每帧进行调用
|
||||
*/
|
||||
public update() {
|
||||
}
|
||||
|
||||
public setEnabled(isEnabled: boolean) {
|
||||
if (this._enabled != isEnabled) {
|
||||
this._enabled = isEnabled;
|
||||
|
||||
if (this._enabled) {
|
||||
this.onEnabled();
|
||||
} else {
|
||||
this.onDisabled();
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public setUpdateOrder(updateOrder: number) {
|
||||
if (this._updateOrder != updateOrder) {
|
||||
this._updateOrder = updateOrder;
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建此组件的克隆
|
||||
*/
|
||||
public clone(): Component {
|
||||
let component = ObjectUtils.clone<Component>(this);
|
||||
component.entity = null;
|
||||
|
||||
return component;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,234 +1,236 @@
|
||||
class Camera extends Component {
|
||||
private _zoom;
|
||||
private _origin: Vector2 = Vector2.zero;
|
||||
module es {
|
||||
export class Camera extends Component {
|
||||
private _zoom;
|
||||
private _origin: Vector2 = Vector2.zero;
|
||||
|
||||
private _minimumZoom = 0.3;
|
||||
private _maximumZoom = 3;
|
||||
private _minimumZoom = 0.3;
|
||||
private _maximumZoom = 3;
|
||||
|
||||
private _position: Vector2 = Vector2.zero;
|
||||
/**
|
||||
* 如果相机模式为cameraWindow 则会进行缓动移动
|
||||
* 该值为移动速度
|
||||
*/
|
||||
public followLerp = 0.1;
|
||||
public deadzone: Rectangle = new Rectangle();
|
||||
/** 锁定偏移量 默认中心 */
|
||||
public focusOffset: Vector2 = new Vector2();
|
||||
/** 是否地图锁定 如果锁定则需要设置mapSize属性 */
|
||||
public mapLockEnabled: boolean = false;
|
||||
/** 设置地图大小 默认从0 0左上角开始 只需要输入地图宽高 */
|
||||
public mapSize: Vector2 = new Vector2();
|
||||
/** 跟随的实体 设置后镜头将锁定目标为中心 */
|
||||
public targetEntity: Entity;
|
||||
private _worldSpaceDeadZone: Rectangle = new Rectangle();
|
||||
private _desiredPositionDelta: Vector2 = new Vector2();
|
||||
private _targetCollider: Collider;
|
||||
/** 相机模式 */
|
||||
public cameraStyle: CameraStyle = CameraStyle.lockOn;
|
||||
private _position: Vector2 = Vector2.zero;
|
||||
/**
|
||||
* 如果相机模式为cameraWindow 则会进行缓动移动
|
||||
* 该值为移动速度
|
||||
*/
|
||||
public followLerp = 0.1;
|
||||
public deadzone: Rectangle = new Rectangle();
|
||||
/** 锁定偏移量 默认中心 */
|
||||
public focusOffset: Vector2 = new Vector2();
|
||||
/** 是否地图锁定 如果锁定则需要设置mapSize属性 */
|
||||
public mapLockEnabled: boolean = false;
|
||||
/** 设置地图大小 默认从0 0左上角开始 只需要输入地图宽高 */
|
||||
public mapSize: Vector2 = new Vector2();
|
||||
/** 跟随的实体 设置后镜头将锁定目标为中心 */
|
||||
public targetEntity: Entity;
|
||||
private _worldSpaceDeadZone: Rectangle = new Rectangle();
|
||||
private _desiredPositionDelta: Vector2 = new Vector2();
|
||||
private _targetCollider: Collider;
|
||||
/** 相机模式 */
|
||||
public cameraStyle: CameraStyle = CameraStyle.lockOn;
|
||||
|
||||
public get zoom(){
|
||||
if (this._zoom == 0)
|
||||
return 1;
|
||||
public get zoom(){
|
||||
if (this._zoom == 0)
|
||||
return 1;
|
||||
|
||||
if (this._zoom < 1)
|
||||
return MathHelper.map(this._zoom, this._minimumZoom, 1, -1, 0);
|
||||
if (this._zoom < 1)
|
||||
return MathHelper.map(this._zoom, this._minimumZoom, 1, -1, 0);
|
||||
|
||||
return MathHelper.map(this._zoom, 1, this._maximumZoom, 0, 1);
|
||||
}
|
||||
|
||||
public set zoom(value: number){
|
||||
this.setZoom(value);
|
||||
}
|
||||
|
||||
public get minimumZoom(){
|
||||
return this._minimumZoom;
|
||||
}
|
||||
|
||||
public set minimumZoom(value: number){
|
||||
this.setMinimumZoom(value);
|
||||
}
|
||||
|
||||
public get maximumZoom(){
|
||||
return this._maximumZoom;
|
||||
}
|
||||
|
||||
public set maximumZoom(value: number){
|
||||
this.setMaximumZoom(value);
|
||||
}
|
||||
|
||||
public get origin(){
|
||||
return this._origin;
|
||||
}
|
||||
|
||||
public set origin(value: Vector2){
|
||||
if (this._origin != value){
|
||||
this._origin = value;
|
||||
}
|
||||
}
|
||||
|
||||
public get position(){
|
||||
return this._position;
|
||||
}
|
||||
|
||||
public set position(value: Vector2){
|
||||
this._position = value;
|
||||
}
|
||||
|
||||
public get x(){
|
||||
return this._position.x;
|
||||
}
|
||||
public set x(value: number){
|
||||
this._position.x = value;
|
||||
}
|
||||
public get y(){
|
||||
return this._position.y;
|
||||
}
|
||||
public set y(value: number){
|
||||
this._position.y = value;
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.width = SceneManager.stage.stageWidth;
|
||||
this.height = SceneManager.stage.stageHeight;
|
||||
this.setZoom(0);
|
||||
}
|
||||
|
||||
public onSceneSizeChanged(newWidth: number, newHeight: number){
|
||||
let oldOrigin = this._origin;
|
||||
this.origin = new Vector2(newWidth / 2, newHeight / 2);
|
||||
|
||||
this.entity.position = Vector2.add(this.entity.position, Vector2.subtract(this._origin, oldOrigin));
|
||||
}
|
||||
|
||||
public setMinimumZoom(minZoom: number): Camera{
|
||||
if (this._zoom < minZoom)
|
||||
this._zoom = this.minimumZoom;
|
||||
|
||||
this._minimumZoom = minZoom;
|
||||
return this;
|
||||
}
|
||||
|
||||
public setMaximumZoom(maxZoom: number): Camera {
|
||||
if (this._zoom > maxZoom)
|
||||
this._zoom = maxZoom;
|
||||
|
||||
this._maximumZoom = maxZoom;
|
||||
return this;
|
||||
}
|
||||
|
||||
public setZoom(zoom: number): Camera{
|
||||
let newZoom = MathHelper.clamp(zoom, -1, 1);
|
||||
if (newZoom == 0){
|
||||
this._zoom = 1;
|
||||
} else if(newZoom < 0){
|
||||
this._zoom = MathHelper.map(newZoom, -1, 0, this._minimumZoom, 1);
|
||||
} else {
|
||||
this._zoom = MathHelper.map(newZoom, 0, 1, 1, this._maximumZoom);
|
||||
return MathHelper.map(this._zoom, 1, this._maximumZoom, 0, 1);
|
||||
}
|
||||
|
||||
SceneManager.scene.scaleX = this._zoom;
|
||||
SceneManager.scene.scaleY = this._zoom;
|
||||
return this;
|
||||
}
|
||||
|
||||
public setRotation(rotation: number): Camera {
|
||||
SceneManager.scene.rotation = rotation;
|
||||
return this;
|
||||
}
|
||||
|
||||
public setPosition(position: Vector2){
|
||||
this.entity.position = position;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public follow(targetEntity: Entity, cameraStyle: CameraStyle = CameraStyle.cameraWindow){
|
||||
this.targetEntity = targetEntity;
|
||||
this.cameraStyle = cameraStyle;
|
||||
let cameraBounds = new Rectangle(0, 0, SceneManager.stage.stageWidth, SceneManager.stage.stageHeight);
|
||||
|
||||
switch (this.cameraStyle){
|
||||
case CameraStyle.cameraWindow:
|
||||
let w = cameraBounds.width / 6;
|
||||
let h = cameraBounds.height / 3;
|
||||
this.deadzone = new Rectangle((cameraBounds.width - w) / 2, (cameraBounds.height - h) / 2, w, h);
|
||||
break;
|
||||
case CameraStyle.lockOn:
|
||||
this.deadzone = new Rectangle(cameraBounds.width / 2, cameraBounds.height / 2, 10, 10);
|
||||
break;
|
||||
public set zoom(value: number){
|
||||
this.setZoom(value);
|
||||
}
|
||||
}
|
||||
|
||||
public update(){
|
||||
let cameraBounds = new Rectangle(0, 0, SceneManager.stage.stageWidth, SceneManager.stage.stageHeight);
|
||||
let halfScreen = Vector2.multiply(new Vector2(cameraBounds.width, cameraBounds.height), new Vector2(0.5));
|
||||
this._worldSpaceDeadZone.x = this.position.x - halfScreen.x * SceneManager.scene.scaleX + this.deadzone.x + this.focusOffset.x;
|
||||
this._worldSpaceDeadZone.y = this.position.y - halfScreen.y * SceneManager.scene.scaleY + this.deadzone.y + this.focusOffset.y;
|
||||
this._worldSpaceDeadZone.width = this.deadzone.width;
|
||||
this._worldSpaceDeadZone.height = this.deadzone.height;
|
||||
public get minimumZoom(){
|
||||
return this._minimumZoom;
|
||||
}
|
||||
|
||||
if (this.targetEntity)
|
||||
this.updateFollow();
|
||||
public set minimumZoom(value: number){
|
||||
this.setMinimumZoom(value);
|
||||
}
|
||||
|
||||
this.position = Vector2.lerp(this.position, Vector2.add(this.position, this._desiredPositionDelta), this.followLerp);
|
||||
this.entity.roundPosition();
|
||||
public get maximumZoom(){
|
||||
return this._maximumZoom;
|
||||
}
|
||||
|
||||
if (this.mapLockEnabled){
|
||||
this.position = this.clampToMapSize(this.position);
|
||||
public set maximumZoom(value: number){
|
||||
this.setMaximumZoom(value);
|
||||
}
|
||||
|
||||
public get origin(){
|
||||
return this._origin;
|
||||
}
|
||||
|
||||
public set origin(value: Vector2){
|
||||
if (this._origin != value){
|
||||
this._origin = value;
|
||||
}
|
||||
}
|
||||
|
||||
public get position(){
|
||||
return this._position;
|
||||
}
|
||||
|
||||
public set position(value: Vector2){
|
||||
this._position = value;
|
||||
}
|
||||
|
||||
public get x(){
|
||||
return this._position.x;
|
||||
}
|
||||
public set x(value: number){
|
||||
this._position.x = value;
|
||||
}
|
||||
public get y(){
|
||||
return this._position.y;
|
||||
}
|
||||
public set y(value: number){
|
||||
this._position.y = value;
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.width = SceneManager.stage.stageWidth;
|
||||
this.height = SceneManager.stage.stageHeight;
|
||||
this.setZoom(0);
|
||||
}
|
||||
|
||||
public onSceneSizeChanged(newWidth: number, newHeight: number){
|
||||
let oldOrigin = this._origin;
|
||||
this.origin = new Vector2(newWidth / 2, newHeight / 2);
|
||||
|
||||
this.entity.position = Vector2.add(this.entity.position, Vector2.subtract(this._origin, oldOrigin));
|
||||
}
|
||||
|
||||
public setMinimumZoom(minZoom: number): Camera{
|
||||
if (this._zoom < minZoom)
|
||||
this._zoom = this.minimumZoom;
|
||||
|
||||
this._minimumZoom = minZoom;
|
||||
return this;
|
||||
}
|
||||
|
||||
public setMaximumZoom(maxZoom: number): Camera {
|
||||
if (this._zoom > maxZoom)
|
||||
this._zoom = maxZoom;
|
||||
|
||||
this._maximumZoom = maxZoom;
|
||||
return this;
|
||||
}
|
||||
|
||||
public setZoom(zoom: number): Camera{
|
||||
let newZoom = MathHelper.clamp(zoom, -1, 1);
|
||||
if (newZoom == 0){
|
||||
this._zoom = 1;
|
||||
} else if(newZoom < 0){
|
||||
this._zoom = MathHelper.map(newZoom, -1, 0, this._minimumZoom, 1);
|
||||
} else {
|
||||
this._zoom = MathHelper.map(newZoom, 0, 1, 1, this._maximumZoom);
|
||||
}
|
||||
|
||||
SceneManager.scene.scaleX = this._zoom;
|
||||
SceneManager.scene.scaleY = this._zoom;
|
||||
return this;
|
||||
}
|
||||
|
||||
public setRotation(rotation: number): Camera {
|
||||
SceneManager.scene.rotation = rotation;
|
||||
return this;
|
||||
}
|
||||
|
||||
public setPosition(position: Vector2){
|
||||
this.entity.position = position;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public follow(targetEntity: Entity, cameraStyle: CameraStyle = CameraStyle.cameraWindow){
|
||||
this.targetEntity = targetEntity;
|
||||
this.cameraStyle = cameraStyle;
|
||||
let cameraBounds = new Rectangle(0, 0, SceneManager.stage.stageWidth, SceneManager.stage.stageHeight);
|
||||
|
||||
switch (this.cameraStyle){
|
||||
case CameraStyle.cameraWindow:
|
||||
let w = cameraBounds.width / 6;
|
||||
let h = cameraBounds.height / 3;
|
||||
this.deadzone = new Rectangle((cameraBounds.width - w) / 2, (cameraBounds.height - h) / 2, w, h);
|
||||
break;
|
||||
case CameraStyle.lockOn:
|
||||
this.deadzone = new Rectangle(cameraBounds.width / 2, cameraBounds.height / 2, 10, 10);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public update(){
|
||||
let cameraBounds = new Rectangle(0, 0, SceneManager.stage.stageWidth, SceneManager.stage.stageHeight);
|
||||
let halfScreen = Vector2.multiply(new Vector2(cameraBounds.width, cameraBounds.height), new Vector2(0.5));
|
||||
this._worldSpaceDeadZone.x = this.position.x - halfScreen.x * SceneManager.scene.scaleX + this.deadzone.x + this.focusOffset.x;
|
||||
this._worldSpaceDeadZone.y = this.position.y - halfScreen.y * SceneManager.scene.scaleY + this.deadzone.y + this.focusOffset.y;
|
||||
this._worldSpaceDeadZone.width = this.deadzone.width;
|
||||
this._worldSpaceDeadZone.height = this.deadzone.height;
|
||||
|
||||
if (this.targetEntity)
|
||||
this.updateFollow();
|
||||
|
||||
this.position = Vector2.lerp(this.position, Vector2.add(this.position, this._desiredPositionDelta), this.followLerp);
|
||||
this.entity.roundPosition();
|
||||
|
||||
if (this.mapLockEnabled){
|
||||
this.position = this.clampToMapSize(this.position);
|
||||
this.entity.roundPosition();
|
||||
}
|
||||
}
|
||||
|
||||
private clampToMapSize(position: Vector2){
|
||||
let cameraBounds = new Rectangle(0, 0, SceneManager.stage.stageWidth, SceneManager.stage.stageHeight);
|
||||
let halfScreen = Vector2.multiply(new Vector2(cameraBounds.width, cameraBounds.height), new Vector2(0.5));
|
||||
let cameraMax = new Vector2(this.mapSize.x - halfScreen.x, this.mapSize.y - halfScreen.y);
|
||||
|
||||
return Vector2.clamp(position, halfScreen, cameraMax);
|
||||
}
|
||||
|
||||
private updateFollow(){
|
||||
this._desiredPositionDelta.x = this._desiredPositionDelta.y = 0;
|
||||
|
||||
if (this.cameraStyle == CameraStyle.lockOn){
|
||||
let targetX = this.targetEntity.position.x;
|
||||
let targetY = this.targetEntity.position.y;
|
||||
|
||||
if (this._worldSpaceDeadZone.x > targetX)
|
||||
this._desiredPositionDelta.x = targetX - this._worldSpaceDeadZone.x;
|
||||
else if(this._worldSpaceDeadZone.x < targetX)
|
||||
this._desiredPositionDelta.x = targetX - this._worldSpaceDeadZone.x;
|
||||
|
||||
if (this._worldSpaceDeadZone.y < targetY)
|
||||
this._desiredPositionDelta.y = targetY - this._worldSpaceDeadZone.y;
|
||||
else if(this._worldSpaceDeadZone.y > targetY)
|
||||
this._desiredPositionDelta.y = targetY - this._worldSpaceDeadZone.y;
|
||||
} else {
|
||||
if (!this._targetCollider){
|
||||
this._targetCollider = this.targetEntity.getComponent<Collider>(Collider);
|
||||
if (!this._targetCollider)
|
||||
return;
|
||||
}
|
||||
|
||||
let targetBounds = this.targetEntity.getComponent<Collider>(Collider).bounds;
|
||||
if (!this._worldSpaceDeadZone.containsRect(targetBounds)){
|
||||
if (this._worldSpaceDeadZone.left > targetBounds.left)
|
||||
this._desiredPositionDelta.x = targetBounds.left - this._worldSpaceDeadZone.left;
|
||||
else if(this._worldSpaceDeadZone.right < targetBounds.right)
|
||||
this._desiredPositionDelta.x = targetBounds.right - this._worldSpaceDeadZone.right;
|
||||
|
||||
if (this._worldSpaceDeadZone.bottom < targetBounds.bottom)
|
||||
this._desiredPositionDelta.y = targetBounds.bottom - this._worldSpaceDeadZone.bottom;
|
||||
else if(this._worldSpaceDeadZone.top > targetBounds.top)
|
||||
this._desiredPositionDelta.y = targetBounds.top - this._worldSpaceDeadZone.top;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private clampToMapSize(position: Vector2){
|
||||
let cameraBounds = new Rectangle(0, 0, SceneManager.stage.stageWidth, SceneManager.stage.stageHeight);
|
||||
let halfScreen = Vector2.multiply(new Vector2(cameraBounds.width, cameraBounds.height), new Vector2(0.5));
|
||||
let cameraMax = new Vector2(this.mapSize.x - halfScreen.x, this.mapSize.y - halfScreen.y);
|
||||
|
||||
return Vector2.clamp(position, halfScreen, cameraMax);
|
||||
}
|
||||
|
||||
private updateFollow(){
|
||||
this._desiredPositionDelta.x = this._desiredPositionDelta.y = 0;
|
||||
|
||||
if (this.cameraStyle == CameraStyle.lockOn){
|
||||
let targetX = this.targetEntity.position.x;
|
||||
let targetY = this.targetEntity.position.y;
|
||||
|
||||
if (this._worldSpaceDeadZone.x > targetX)
|
||||
this._desiredPositionDelta.x = targetX - this._worldSpaceDeadZone.x;
|
||||
else if(this._worldSpaceDeadZone.x < targetX)
|
||||
this._desiredPositionDelta.x = targetX - this._worldSpaceDeadZone.x;
|
||||
|
||||
if (this._worldSpaceDeadZone.y < targetY)
|
||||
this._desiredPositionDelta.y = targetY - this._worldSpaceDeadZone.y;
|
||||
else if(this._worldSpaceDeadZone.y > targetY)
|
||||
this._desiredPositionDelta.y = targetY - this._worldSpaceDeadZone.y;
|
||||
} else {
|
||||
if (!this._targetCollider){
|
||||
this._targetCollider = this.targetEntity.getComponent<Collider>(Collider);
|
||||
if (!this._targetCollider)
|
||||
return;
|
||||
}
|
||||
|
||||
let targetBounds = this.targetEntity.getComponent<Collider>(Collider).bounds;
|
||||
if (!this._worldSpaceDeadZone.containsRect(targetBounds)){
|
||||
if (this._worldSpaceDeadZone.left > targetBounds.left)
|
||||
this._desiredPositionDelta.x = targetBounds.left - this._worldSpaceDeadZone.left;
|
||||
else if(this._worldSpaceDeadZone.right < targetBounds.right)
|
||||
this._desiredPositionDelta.x = targetBounds.right - this._worldSpaceDeadZone.right;
|
||||
|
||||
if (this._worldSpaceDeadZone.bottom < targetBounds.bottom)
|
||||
this._desiredPositionDelta.y = targetBounds.bottom - this._worldSpaceDeadZone.bottom;
|
||||
else if(this._worldSpaceDeadZone.top > targetBounds.top)
|
||||
this._desiredPositionDelta.y = targetBounds.top - this._worldSpaceDeadZone.top;
|
||||
}
|
||||
}
|
||||
export enum CameraStyle {
|
||||
lockOn,
|
||||
cameraWindow,
|
||||
}
|
||||
}
|
||||
|
||||
enum CameraStyle {
|
||||
lockOn,
|
||||
cameraWindow,
|
||||
}
|
||||
@@ -1,6 +1,14 @@
|
||||
abstract class Collider extends Component {
|
||||
/** 对撞机的基本形状 */
|
||||
public shape: Shape;
|
||||
protected _localOffset: Vector2 = Vector2.zero;
|
||||
public get localOffset(){
|
||||
return this._localOffset;
|
||||
}
|
||||
public set localOffset(){
|
||||
|
||||
}
|
||||
public _localOffsetLength: number;
|
||||
/** 在处理冲突时,physicsLayer可以用作过滤器。Flags类有帮助位掩码的方法。 */
|
||||
public physicsLayer = 1 << 0;
|
||||
/** 如果这个碰撞器是一个触发器,它将不会引起碰撞,但它仍然会触发事件 */
|
||||
@@ -15,38 +23,32 @@ abstract class Collider extends Component {
|
||||
/** 默认为所有层。 */
|
||||
public collidesWithLayers = Physics.allLayers;
|
||||
|
||||
public _localOffsetLength: number;
|
||||
/** 标记来跟踪我们的实体是否被添加到场景中 */
|
||||
protected _isParentEntityAddedToScene;
|
||||
protected _colliderRequiresAutoSizing;
|
||||
protected _localOffset: Vector2 = new Vector2(0, 0);
|
||||
/** 标记来记录我们是否注册了物理系统 */
|
||||
protected _isColliderRegistered;
|
||||
|
||||
public get bounds(): Rectangle {
|
||||
let shapeBounds = this.shape.bounds;
|
||||
let colliderBuonds = new Rectangle(this.x + this.localOffset.x, this.y + this.localOffset.y, shapeBounds.width, shapeBounds.height);
|
||||
let colliderBuonds = new Rectangle(this.entity.x, this.entity.y, shapeBounds.width, shapeBounds.height);
|
||||
return colliderBuonds;
|
||||
}
|
||||
|
||||
public get localOffset() {
|
||||
return this._localOffset;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将localOffset添加到实体。获取碰撞器的最终位置。这允许您向一个实体添加多个碰撞器并分别定位它们。
|
||||
* 将localOffset添加到实体。获取碰撞器的最终位置。
|
||||
* 这允许您向一个实体添加多个碰撞器并分别定位它们。
|
||||
* @param offset
|
||||
*/
|
||||
public set localOffset(value: Vector2) {
|
||||
this.setLocalOffset(value);
|
||||
}
|
||||
|
||||
public setLocalOffset(offset: Vector2) {
|
||||
if (this._localOffset != offset) {
|
||||
public setLocalOffset(offset: Vector2): Collider{
|
||||
if (this._localOffset != offset){
|
||||
this.unregisterColliderWithPhysicsSystem();
|
||||
this._localOffset = offset;
|
||||
this._localOffsetLength = this._localOffset.length();
|
||||
this.registerColliderWithPhysicsSystem();
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -85,15 +87,15 @@ abstract class Collider extends Component {
|
||||
*/
|
||||
public collidesWith(collider: Collider, motion: Vector2) {
|
||||
// 改变形状的位置,使它在移动后的位置,这样我们可以检查重叠
|
||||
let oldPosition = this.shape.position;
|
||||
this.shape.position = Vector2.add(this.shape.position, motion);
|
||||
let oldPosition = this.entity.position;
|
||||
this.entity.position = Vector2.add(this.entity.position, motion);
|
||||
|
||||
let result = this.shape.collidesWithShape(collider.shape);
|
||||
if (result)
|
||||
result.collider = collider;
|
||||
|
||||
// 将图形位置返回到检查前的位置
|
||||
this.shape.position = oldPosition;
|
||||
this.entity.position = oldPosition;
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -111,19 +113,17 @@ abstract class Collider extends Component {
|
||||
// 这里我们需要大小*反尺度,因为当我们自动调整碰撞器的大小时,它需要没有缩放的渲染
|
||||
let width = bounds.width / this.entity.scale.x;
|
||||
let height = bounds.height / this.entity.scale.y;
|
||||
|
||||
// 圆碰撞器需要特别注意原点
|
||||
if (this instanceof CircleCollider){
|
||||
let circleCollider = this as CircleCollider;
|
||||
circleCollider.radius = Math.max(width, height) * 0.5;
|
||||
|
||||
this.localOffset = bounds.location;
|
||||
} else {
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
|
||||
this.localOffset = bounds.location;
|
||||
}
|
||||
|
||||
// 获取渲染的中心,将其转移到本地坐标,并使用它作为碰撞器的localOffset
|
||||
this.localOffset = Vector2.subtract(bounds.center, this.entity.position);
|
||||
} else {
|
||||
console.warn("Collider has no shape and no RenderableComponent. Can't figure out how to size it.");
|
||||
}
|
||||
@@ -154,8 +154,8 @@ abstract class Collider extends Component {
|
||||
public update(){
|
||||
let renderable = this.entity.getComponent<RenderableComponent>(RenderableComponent);
|
||||
if (renderable){
|
||||
this.$setX(renderable.x + this.localOffset.x);
|
||||
this.$setY(renderable.y + this.localOffset.y);
|
||||
this.$setX(renderable.x);
|
||||
this.$setY(renderable.y);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -16,8 +16,6 @@ class PolygonCollider extends Collider {
|
||||
if (isPolygonClosed)
|
||||
points.splice(points.length - 1, 1);
|
||||
|
||||
let center = Polygon.findPolygonCenter(points);
|
||||
this.setLocalOffset(center);
|
||||
Polygon.recenterPolygonVerts(points);
|
||||
this.shape = new Polygon(points);
|
||||
}
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
class SpriteRenderer extends RenderableComponent{
|
||||
class SpriteRenderer extends RenderableComponent {
|
||||
private _sprite: Sprite;
|
||||
protected bitmap: egret.Bitmap;
|
||||
|
||||
/** 应该由这个精灵显示的精灵 */
|
||||
public get sprite(): Sprite{
|
||||
public get sprite(): Sprite {
|
||||
return this._sprite;
|
||||
}
|
||||
/** 应该由这个精灵显示的精灵 */
|
||||
public set sprite(value: Sprite){
|
||||
public set sprite(value: Sprite) {
|
||||
this.setSprite(value);
|
||||
}
|
||||
|
||||
public setSprite(sprite: Sprite): SpriteRenderer{
|
||||
public setSprite(sprite: Sprite): SpriteRenderer {
|
||||
this.removeChildren();
|
||||
this._sprite = sprite;
|
||||
if (this._sprite) {
|
||||
@@ -24,7 +24,7 @@ class SpriteRenderer extends RenderableComponent{
|
||||
return this;
|
||||
}
|
||||
|
||||
public setColor(color: number): SpriteRenderer{
|
||||
public setColor(color: number): SpriteRenderer {
|
||||
let colorMatrix = [
|
||||
1, 0, 0, 0, 0,
|
||||
0, 1, 0, 0, 0,
|
||||
@@ -40,23 +40,27 @@ class SpriteRenderer extends RenderableComponent{
|
||||
return this;
|
||||
}
|
||||
|
||||
public isVisibleFromCamera(camera: Camera): boolean{
|
||||
public isVisibleFromCamera(camera: Camera): boolean {
|
||||
this.isVisible = new Rectangle(0, 0, this.stage.stageWidth, this.stage.stageHeight).intersects(this.bounds);
|
||||
this.visible = this.isVisible;
|
||||
return this.isVisible;
|
||||
}
|
||||
|
||||
/** 渲染处理 在每个模块中处理各自的渲染逻辑 */
|
||||
public render(camera: Camera){
|
||||
this.x = -camera.position.x + camera.origin.x;
|
||||
this.y = -camera.position.y + camera.origin.y;
|
||||
public render(camera: Camera) {
|
||||
if (this.x != -camera.position.x + camera.origin.x ||
|
||||
this.y != -camera.position.y + camera.origin.y) {
|
||||
this.x = -camera.position.x + camera.origin.x;
|
||||
this.y = -camera.position.y + camera.origin.y;
|
||||
this.entity.onEntityTransformChanged(TransformComponent.position);
|
||||
}
|
||||
}
|
||||
|
||||
public onRemovedFromEntity(){
|
||||
public onRemovedFromEntity() {
|
||||
if (this.parent)
|
||||
this.parent.removeChild(this);
|
||||
}
|
||||
|
||||
public reset(){
|
||||
public reset() {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,237 +1,377 @@
|
||||
class Entity extends egret.DisplayObjectContainer {
|
||||
private static _idGenerator: number;
|
||||
module es {
|
||||
export class Entity {
|
||||
public static _idGenerator: number;
|
||||
|
||||
public name: string;
|
||||
public readonly id: number;
|
||||
/** 当前实体所属的场景 */
|
||||
public scene: Scene;
|
||||
/** 当前附加到此实体的所有组件的列表 */
|
||||
public readonly components: ComponentList;
|
||||
private _updateOrder: number = 0;
|
||||
private _enabled: boolean = true;
|
||||
public _isDestoryed: boolean;
|
||||
private _tag: number = 0;
|
||||
/**
|
||||
* 当前实体所属的场景
|
||||
*/
|
||||
public scene: Scene;
|
||||
/**
|
||||
* 实体名称。用于在场景范围内搜索实体
|
||||
*/
|
||||
public name: string;
|
||||
/**
|
||||
* 此实体的唯一标识
|
||||
*/
|
||||
public readonly id: number;
|
||||
/**
|
||||
* 封装实体的位置/旋转/缩放,并允许设置一个高层结构
|
||||
*/
|
||||
public readonly transform: Transform;
|
||||
/**
|
||||
* 当前附加到此实体的所有组件的列表
|
||||
*/
|
||||
public readonly components: ComponentList;
|
||||
|
||||
public componentBits: BitSet;
|
||||
|
||||
public get isDestoryed(){
|
||||
return this._isDestoryed;
|
||||
}
|
||||
|
||||
public get position(){
|
||||
return new Vector2(this.x, this.y);
|
||||
}
|
||||
|
||||
public set position(value: Vector2){
|
||||
this.$setX(value.x);
|
||||
this.$setY(value.y);
|
||||
this.onEntityTransformChanged(TransformComponent.position);
|
||||
}
|
||||
|
||||
public get scale(){
|
||||
return new Vector2(this.scaleX, this.scaleY);
|
||||
}
|
||||
|
||||
public set scale(value: Vector2){
|
||||
this.$setScaleX(value.x);
|
||||
this.$setScaleY(value.y);
|
||||
this.onEntityTransformChanged(TransformComponent.scale);
|
||||
}
|
||||
|
||||
public set rotation(value: number){
|
||||
this.$setRotation(value);
|
||||
this.onEntityTransformChanged(TransformComponent.rotation);
|
||||
}
|
||||
|
||||
public get rotation(){
|
||||
return this.$getRotation();
|
||||
}
|
||||
|
||||
public get enabled(){
|
||||
return this._enabled;
|
||||
}
|
||||
|
||||
public set enabled(value: boolean){
|
||||
this.setEnabled(value);
|
||||
}
|
||||
|
||||
public setEnabled(isEnabled: boolean){
|
||||
if (this._enabled != isEnabled){
|
||||
this._enabled = isEnabled;
|
||||
/**
|
||||
* 你可以随意使用。稍后可以使用它来查询场景中具有特定标记的所有实体
|
||||
*/
|
||||
public get tag(): number {
|
||||
return this._tag;
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* 你可以随意使用。稍后可以使用它来查询场景中具有特定标记的所有实体
|
||||
* @param value
|
||||
*/
|
||||
public set tag(value: number) {
|
||||
this.setTag(value);
|
||||
}
|
||||
|
||||
public get tag(){
|
||||
return this._tag;
|
||||
}
|
||||
/**
|
||||
* 指定应该调用这个entity update方法的频率。1表示每一帧,2表示每一帧,以此类推
|
||||
*/
|
||||
public updateInterval: number = 1;
|
||||
|
||||
public set tag(value: number){
|
||||
this.setTag(value);
|
||||
}
|
||||
/**
|
||||
* 启用/禁用实体。当禁用碰撞器从物理系统和组件中移除时,方法将不会被调用
|
||||
*/
|
||||
public get enabled() {
|
||||
return this._enabled;
|
||||
}
|
||||
|
||||
public get stage(){
|
||||
if (!this.scene)
|
||||
return null;
|
||||
|
||||
return this.scene.stage;
|
||||
}
|
||||
/**
|
||||
* 启用/禁用实体。当禁用碰撞器从物理系统和组件中移除时,方法将不会被调用
|
||||
* @param value
|
||||
*/
|
||||
public set enabled(value: boolean) {
|
||||
this.setEnabled(value);
|
||||
}
|
||||
|
||||
constructor(name: string){
|
||||
super();
|
||||
this.name = name;
|
||||
this.components = new ComponentList(this);
|
||||
this.id = Entity._idGenerator ++;
|
||||
/**
|
||||
* 更新此实体的顺序。updateOrder还用于对scene.entities上的标签列表进行排序
|
||||
*/
|
||||
public get updateOrder() {
|
||||
return this._updateOrder;
|
||||
}
|
||||
|
||||
this.componentBits = new BitSet();
|
||||
this.addEventListener(egret.Event.ADDED_TO_STAGE, this.onAddToStage, this);
|
||||
}
|
||||
/**
|
||||
* 更新此实体的顺序。updateOrder还用于对scene.entities上的标签列表进行排序
|
||||
* @param value
|
||||
*/
|
||||
public set updateOrder(value: number) {
|
||||
this.setUpdateOrder(value);
|
||||
}
|
||||
|
||||
private onAddToStage(){
|
||||
this.onEntityTransformChanged(TransformComponent.position);
|
||||
}
|
||||
public _isDestroyed: boolean;
|
||||
/**
|
||||
* 如果调用了destroy,那么在下一次处理实体之前这将一直为true
|
||||
*/
|
||||
public get isDestroyed() {
|
||||
return this._isDestroyed;
|
||||
}
|
||||
|
||||
public get updateOrder(){
|
||||
return this._updateOrder;
|
||||
}
|
||||
public componentBits: BitSet;
|
||||
|
||||
public set updateOrder(value: number){
|
||||
this.setUpdateOrder(value);
|
||||
}
|
||||
private _tag: number = 0;
|
||||
private _enabled: boolean = true;
|
||||
private _updateOrder: number = 0;
|
||||
|
||||
public roundPosition(){
|
||||
this.position = Vector2Ext.round(this.position);
|
||||
}
|
||||
public get parent(): Transform {
|
||||
return this.transform.parent;
|
||||
}
|
||||
|
||||
public setUpdateOrder(updateOrder: number){
|
||||
if (this._updateOrder != updateOrder){
|
||||
this._updateOrder = updateOrder;
|
||||
if (this.scene){
|
||||
|
||||
public set parent(value: Transform) {
|
||||
this.transform.setParent(value);
|
||||
}
|
||||
|
||||
public get childCount() {
|
||||
return this.transform.childCount;
|
||||
}
|
||||
|
||||
public get position(): Vector2 {
|
||||
return this.transform.position;
|
||||
}
|
||||
|
||||
public set position(value: Vector2) {
|
||||
this.transform.setPosition(value.x, value.y);
|
||||
}
|
||||
|
||||
public get rotation(): number {
|
||||
return this.transform.rotation;
|
||||
}
|
||||
|
||||
public set rotation(value: number) {
|
||||
this.transform.setRotation(value);
|
||||
}
|
||||
|
||||
|
||||
public get scale(): Vector2 {
|
||||
return this.transform.scale;
|
||||
}
|
||||
|
||||
public set scale(value: Vector2) {
|
||||
this.transform.setScale(value);
|
||||
}
|
||||
|
||||
constructor(name: string) {
|
||||
this.components = new ComponentList(this);
|
||||
this.transform = new Transform(this);
|
||||
this.name = name;
|
||||
this.id = Entity._idGenerator++;
|
||||
|
||||
this.componentBits = new BitSet();
|
||||
}
|
||||
|
||||
public onTransformChanged(comp: Transform.Component) {
|
||||
// 通知我们的子项改变了位置
|
||||
this.components.onEntityTransformChanged(comp);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置实体的标记
|
||||
* @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);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
public setTag(tag: number): Entity{
|
||||
if (this._tag != tag){
|
||||
if (this.scene){
|
||||
this.scene.entities.removeFromTagList(this);
|
||||
/**
|
||||
* 设置实体的启用状态。当禁用碰撞器从物理系统和组件中移除时,方法将不会被调用
|
||||
* @param isEnabled
|
||||
*/
|
||||
public setEnabled(isEnabled: boolean) {
|
||||
if (this._enabled != isEnabled) {
|
||||
this._enabled = isEnabled;
|
||||
|
||||
if (this._enabled)
|
||||
this.components.onEntityEnabled();
|
||||
else
|
||||
this.components.onEntityDisabled();
|
||||
}
|
||||
this._tag = tag;
|
||||
if (this.scene){
|
||||
this.scene.entities.addToTagList(this);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置此实体的更新顺序。updateOrder还用于对scene.entities上的标签列表进行排序
|
||||
* @param updateOrder
|
||||
*/
|
||||
public setUpdateOrder(updateOrder: number) {
|
||||
if (this._updateOrder != updateOrder) {
|
||||
this._updateOrder = updateOrder;
|
||||
if (this.scene) {
|
||||
// TODO: markEntityListSorted
|
||||
// markTagUnsorted
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* 从场景中删除实体并销毁所有子元素
|
||||
*/
|
||||
public destroy() {
|
||||
this._isDestroyed = true;
|
||||
this.scene.entities.remove(this);
|
||||
this.transform.parent = null;
|
||||
|
||||
public attachToScene(newScene: Scene){
|
||||
this.scene = newScene;
|
||||
newScene.entities.add(this);
|
||||
this.components.registerAllComponents();
|
||||
|
||||
for (let i = 0; i < this.numChildren; i ++){
|
||||
(this.getChildAt(i) as Component).entity.attachToScene(newScene);
|
||||
}
|
||||
}
|
||||
|
||||
public detachFromScene(){
|
||||
this.scene.entities.remove(this);
|
||||
this.components.deregisterAllComponents();
|
||||
|
||||
for (let i = 0; i < this.numChildren; i ++)
|
||||
(this.getChildAt(i) as Component).entity.detachFromScene();
|
||||
}
|
||||
|
||||
public addComponent<T extends Component>(component: T): T{
|
||||
component.entity = this;
|
||||
this.components.add(component);
|
||||
this.addChild(component);
|
||||
component.initialize();
|
||||
return component;
|
||||
}
|
||||
|
||||
public hasComponent<T extends Component>(type){
|
||||
return this.components.getComponent<T>(type, false) != null;
|
||||
}
|
||||
|
||||
public getOrCreateComponent<T extends Component>(type: T){
|
||||
let comp = this.components.getComponent<T>(type, true);
|
||||
if (!comp){
|
||||
comp = this.addComponent<T>(type);
|
||||
// 销毁所有子项
|
||||
for (let i = this.transform.childCount - 1; i >= 0; i--) {
|
||||
let child = this.transform.getChild(i);
|
||||
child.entity.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
return comp;
|
||||
}
|
||||
/**
|
||||
* 将实体从场景中分离。下面的生命周期方法将被调用在组件上:OnRemovedFromEntity
|
||||
*/
|
||||
public detachFromScene() {
|
||||
this.scene.entities.remove(this);
|
||||
this.components.deregisterAllComponents();
|
||||
|
||||
public getComponent<T extends Component>(type): T{
|
||||
return this.components.getComponent(type, false) as T;
|
||||
}
|
||||
|
||||
public getComponents(typeName: string | any, componentList?){
|
||||
return this.components.getComponents(typeName, componentList);
|
||||
}
|
||||
|
||||
private onEntityTransformChanged(comp: TransformComponent){
|
||||
this.components.onEntityTransformChanged(comp);
|
||||
}
|
||||
|
||||
public removeComponentForType<T extends Component>(type){
|
||||
let comp = this.getComponent<T>(type);
|
||||
if (comp){
|
||||
this.removeComponent(comp);
|
||||
return true;
|
||||
for (let i = 0; i < this.transform.childCount; i++)
|
||||
this.transform.getChild(i).entity.detachFromScene();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* 将一个先前分离的实体附加到一个新的场景
|
||||
* @param newScene
|
||||
*/
|
||||
public attachToScene(newScene: Scene) {
|
||||
this.scene = newScene;
|
||||
newScene.entities.add(this);
|
||||
this.components.registerAllComponents();
|
||||
|
||||
public removeComponent(component: Component){
|
||||
this.components.remove(component);
|
||||
}
|
||||
|
||||
public removeAllComponents(){
|
||||
for (let i = 0; i < this.components.count; i ++){
|
||||
this.removeComponent(this.components.buffer[i]);
|
||||
for (let i = 0; i < this.transform.childCount; i++) {
|
||||
this.transform.getChild(i).entity.attachToScene(newScene);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public update(){
|
||||
this.components.update();
|
||||
}
|
||||
/**
|
||||
* 创建此实体的深层克隆。子类可以重写此方法来复制任何自定义字段。
|
||||
* 当重写时,应该调用CopyFrom方法,它将为您克隆所有组件、碰撞器和转换子组件。
|
||||
* 注意克隆的实体不会被添加到任何场景中!你必须自己添加它们!
|
||||
* @param position
|
||||
*/
|
||||
public clone(position: Vector2 = new Vector2()): Entity {
|
||||
let entity = new Entity(this.name + "(clone)");
|
||||
entity.copyFrom(this);
|
||||
entity.transform.position = position;
|
||||
|
||||
public onAddedToScene(){
|
||||
return entity;
|
||||
}
|
||||
|
||||
}
|
||||
/**
|
||||
* 将实体的属性、组件和碰撞器复制到此实例
|
||||
* @param entity
|
||||
*/
|
||||
protected copyFrom(entity: Entity) {
|
||||
this.tag = entity.tag;
|
||||
this.updateInterval = entity.updateInterval;
|
||||
this.updateOrder = entity.updateOrder;
|
||||
this.enabled = entity.enabled;
|
||||
|
||||
public onRemovedFromScene(){
|
||||
if (this._isDestoryed)
|
||||
this.components.removeAllComponents();
|
||||
}
|
||||
this.transform.scale = entity.transform.scale;
|
||||
this.transform.rotation = entity.transform.rotation;
|
||||
|
||||
public destroy(){
|
||||
this._isDestoryed = true;
|
||||
this.removeEventListener(egret.Event.ADDED_TO_STAGE, this.onAddToStage, this);
|
||||
for (let i = 0; i < entity.components.count; i++)
|
||||
this.addComponent(entity.components.buffer[i].clone());
|
||||
for (let i = 0; i < entity.components._componentsToAdd.length; i++)
|
||||
this.addComponent(entity.components._componentsToAdd[i].clone());
|
||||
|
||||
this.scene.entities.remove(this);
|
||||
this.removeChildren();
|
||||
for (let i = 0; i < entity.transform.childCount; i++) {
|
||||
let child = entity.transform.getChild(i).entity;
|
||||
let childClone = child.clone();
|
||||
childClone.transform.copyFrom(child.transform);
|
||||
childClone.transform.parent = this.transform;
|
||||
}
|
||||
}
|
||||
|
||||
if (this.parent)
|
||||
this.parent.removeChild(this);
|
||||
/**
|
||||
* 在提交了所有挂起的实体更改后,将此实体添加到场景时调用
|
||||
*/
|
||||
public onAddedToScene() {
|
||||
}
|
||||
|
||||
for (let i = this.numChildren - 1; i >= 0; i --){
|
||||
let child = this.getChildAt(i);
|
||||
(child as Component).entity.destroy();
|
||||
/**
|
||||
* 当此实体从场景中删除时调用
|
||||
*/
|
||||
public onRemovedFromScene() {
|
||||
// 如果已经被销毁了,移走我们的组件。如果我们只是分离,我们需要保持我们的组件在实体上。
|
||||
if (this._isDestroyed)
|
||||
this.components.removeAllComponents();
|
||||
}
|
||||
|
||||
/**
|
||||
* 每帧进行调用进行更新组件
|
||||
*/
|
||||
public update() {
|
||||
this.components.update();
|
||||
}
|
||||
|
||||
/**
|
||||
* 将组件添加到组件列表中。返回组件。
|
||||
* @param component
|
||||
*/
|
||||
public addComponent<T extends Component>(component: T): T {
|
||||
component.entity = this;
|
||||
this.components.add(component);
|
||||
component.initialize();
|
||||
return component;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取类型T的第一个组件并返回它。如果没有找到组件,则返回null。
|
||||
* @param type
|
||||
*/
|
||||
public getComponent<T extends Component>(type): T {
|
||||
return this.components.getComponent(type, false) as T;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查实体是否具有该组件
|
||||
* @param type
|
||||
*/
|
||||
public hasComponent<T extends Component>(type) {
|
||||
return this.components.getComponent<T>(type, false) != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取类型T的第一个组件并返回它。如果没有找到组件,将创建组件。
|
||||
* @param type
|
||||
*/
|
||||
public getOrCreateComponent<T extends Component>(type: T) {
|
||||
let comp = this.components.getComponent<T>(type, true);
|
||||
if (!comp) {
|
||||
comp = this.addComponent<T>(type);
|
||||
}
|
||||
|
||||
return comp;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取typeName类型的所有组件,但不使用列表分配
|
||||
* @param typeName
|
||||
* @param componentList
|
||||
*/
|
||||
public getComponents(typeName: string | any, componentList?) {
|
||||
return this.components.getComponents(typeName, componentList);
|
||||
}
|
||||
|
||||
/**
|
||||
* 从组件列表中删除组件
|
||||
* @param component
|
||||
*/
|
||||
public removeComponent(component: Component) {
|
||||
this.components.remove(component);
|
||||
}
|
||||
|
||||
/**
|
||||
* 从组件列表中删除类型为T的第一个组件
|
||||
* @param type
|
||||
*/
|
||||
public removeComponentForType<T extends Component>(type) {
|
||||
let comp = this.getComponent<T>(type);
|
||||
if (comp) {
|
||||
this.removeComponent(comp);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从实体中删除所有组件
|
||||
*/
|
||||
public removeAllComponents() {
|
||||
for (let i = 0; i < this.components.count; i++) {
|
||||
this.removeComponent(this.components.buffer[i]);
|
||||
}
|
||||
}
|
||||
|
||||
public toString(): string {
|
||||
return `[Entity: name: ${this.name}, tag: ${this.tag}, enabled: ${this.enabled}, depth: ${this.updateOrder}]`;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum TransformComponent {
|
||||
rotation,
|
||||
scale,
|
||||
position
|
||||
}
|
||||
@@ -1,213 +1,360 @@
|
||||
/** 场景 */
|
||||
class Scene extends egret.DisplayObjectContainer {
|
||||
public camera: Camera;
|
||||
public readonly entities: EntityList;
|
||||
public readonly renderableComponents: RenderableComponentList;
|
||||
public readonly content: ContentManager;
|
||||
public enablePostProcessing = true;
|
||||
module es {
|
||||
/** 场景 */
|
||||
export class Scene extends egret.DisplayObjectContainer {
|
||||
/**
|
||||
* 默认场景摄像机
|
||||
*/
|
||||
public camera: Camera;
|
||||
/**
|
||||
* 场景特定内容管理器。使用它来加载仅由这个场景需要的任何资源。如果你有全局/多场景资源,你可以使用SceneManager.content。
|
||||
* contentManager来加载它们,因为Nez不会卸载它们。
|
||||
*/
|
||||
public readonly content: ContentManager;
|
||||
/**
|
||||
* 全局切换后处理器
|
||||
*/
|
||||
public enablePostProcessing = true;
|
||||
/**
|
||||
* 这个场景中的实体列表
|
||||
*/
|
||||
public readonly entities: EntityList;
|
||||
/**
|
||||
* 管理当前在场景实体上的所有可呈现组件的列表
|
||||
*/
|
||||
public readonly renderableComponents: RenderableComponentList;
|
||||
/**
|
||||
* 管理所有实体处理器
|
||||
*/
|
||||
public readonly entityProcessors: EntityProcessorList;
|
||||
|
||||
private _renderers: Renderer[] = [];
|
||||
private _postProcessors: PostProcessor[] = [];
|
||||
private _didSceneBegin;
|
||||
public _renderers: Renderer[] = [];
|
||||
public readonly _postProcessors: PostProcessor[] = [];
|
||||
public _didSceneBegin;
|
||||
|
||||
public readonly entityProcessors: EntityProcessorList;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.entityProcessors = new EntityProcessorList();
|
||||
this.renderableComponents = new RenderableComponentList();
|
||||
this.entities = new EntityList(this);
|
||||
this.content = new ContentManager();
|
||||
this.width = SceneManager.stage.stageWidth;
|
||||
this.height = SceneManager.stage.stageHeight;
|
||||
|
||||
this.addEventListener(egret.Event.ACTIVATE, this.onActive, this);
|
||||
this.addEventListener(egret.Event.DEACTIVATE, this.onDeactive, this);
|
||||
}
|
||||
|
||||
public createEntity(name: string) {
|
||||
let entity = new Entity(name);
|
||||
entity.position = new Vector2(0, 0);
|
||||
return this.addEntity(entity);
|
||||
}
|
||||
|
||||
public addEntity(entity: Entity) {
|
||||
this.entities.add(entity);
|
||||
entity.scene = this;
|
||||
this.addChild(entity);
|
||||
|
||||
for (let i = 0; i < entity.numChildren; i++)
|
||||
this.addEntity((entity.getChildAt(i) as Component).entity);
|
||||
|
||||
return entity;
|
||||
}
|
||||
|
||||
public destroyAllEntities() {
|
||||
for (let i = 0; i < this.entities.count; i++) {
|
||||
this.entities.buffer[i].destroy();
|
||||
}
|
||||
}
|
||||
|
||||
public findEntity(name: string): Entity {
|
||||
return this.entities.findEntity(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* 在场景中添加一个EntitySystem处理器
|
||||
* @param processor 处理器
|
||||
*/
|
||||
public addEntityProcessor(processor: EntitySystem) {
|
||||
processor.scene = this;
|
||||
this.entityProcessors.add(processor);
|
||||
return processor;
|
||||
}
|
||||
|
||||
public removeEntityProcessor(processor: EntitySystem) {
|
||||
this.entityProcessors.remove(processor);
|
||||
}
|
||||
|
||||
public getEntityProcessor<T extends EntitySystem>(): T {
|
||||
return this.entityProcessors.getProcessor<T>();
|
||||
}
|
||||
|
||||
public addRenderer<T extends Renderer>(renderer: T) {
|
||||
this._renderers.push(renderer);
|
||||
this._renderers.sort();
|
||||
|
||||
renderer.onAddedToScene(this);
|
||||
|
||||
return renderer;
|
||||
}
|
||||
|
||||
public getRenderer<T extends Renderer>(type): T {
|
||||
for (let i = 0; i < this._renderers.length; i++) {
|
||||
if (this._renderers[i] instanceof type)
|
||||
return this._renderers[i] as T;
|
||||
/**
|
||||
* 辅助器,创建一个场景与DefaultRenderer附加并准备使用
|
||||
*/
|
||||
public static createWithDefaultRenderer(){
|
||||
let scene = new Scene();
|
||||
scene.addRenderer(new DefaultRenderer());
|
||||
return scene;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
constructor() {
|
||||
super();
|
||||
this.entities = new EntityList(this);
|
||||
this.renderableComponents = new RenderableComponentList();
|
||||
this.content = new ContentManager();
|
||||
|
||||
public removeRenderer(renderer: Renderer) {
|
||||
this._renderers.remove(renderer);
|
||||
renderer.unload();
|
||||
}
|
||||
this.entityProcessors = new EntityProcessorList();
|
||||
|
||||
public begin() {
|
||||
if (SceneManager.sceneTransition){
|
||||
SceneManager.stage.addChildAt(this, SceneManager.stage.numChildren - 1);
|
||||
}else{
|
||||
SceneManager.stage.addChild(this);
|
||||
}
|
||||
|
||||
if (this._renderers.length == 0) {
|
||||
this.addRenderer(new DefaultRenderer());
|
||||
console.warn("场景开始时没有渲染器 自动添加DefaultRenderer以保证能够正常渲染");
|
||||
}
|
||||
/** 初始化默认相机 */
|
||||
this.camera = this.createEntity("camera").getOrCreateComponent(new Camera());
|
||||
this.width = SceneManager.stage.stageWidth;
|
||||
this.height = SceneManager.stage.stageHeight;
|
||||
|
||||
Physics.reset();
|
||||
|
||||
if (this.entityProcessors)
|
||||
this.entityProcessors.begin();
|
||||
|
||||
this.camera.onSceneSizeChanged(this.stage.stageWidth, this.stage.stageHeight);
|
||||
|
||||
this._didSceneBegin = true;
|
||||
this.onStart();
|
||||
}
|
||||
|
||||
public end() {
|
||||
this._didSceneBegin = false;
|
||||
|
||||
this.removeEventListener(egret.Event.DEACTIVATE, this.onDeactive, this);
|
||||
this.removeEventListener(egret.Event.ACTIVATE, this.onActive, this);
|
||||
|
||||
for (let i = 0; i < this._renderers.length; i++) {
|
||||
this._renderers[i].unload();
|
||||
this.initialize();
|
||||
}
|
||||
|
||||
for (let i = 0; i < this._postProcessors.length; i++) {
|
||||
this._postProcessors[i].unload();
|
||||
/**
|
||||
* 在场景子类中重写这个并在这里进行加载。在场景设置好之后,在调用begin之前,从构造器中调用。
|
||||
*/
|
||||
public initialize(){}
|
||||
|
||||
/**
|
||||
* 在场景子类中重写这个。当SceneManager将此场景设置为活动场景时,将调用此操作。
|
||||
*/
|
||||
public async onStart() {}
|
||||
|
||||
/**
|
||||
* 在场景子类中重写这个,并在这里做任何必要的卸载。当SceneManager从活动槽中删除此场景时调用。
|
||||
*/
|
||||
public unload() { }
|
||||
|
||||
|
||||
/**
|
||||
* 在场景子类中重写这个,当该场景当获得焦点时调用
|
||||
*/
|
||||
public onActive() {}
|
||||
|
||||
/**
|
||||
* 在场景子类中重写这个,当该场景当失去焦点时调用
|
||||
*/
|
||||
public onDeactive() {}
|
||||
|
||||
public async begin() {
|
||||
// 如果是场景转换需要在最顶层
|
||||
if (SceneManager.sceneTransition){
|
||||
SceneManager.stage.addChildAt(this, SceneManager.stage.numChildren - 1);
|
||||
}else{
|
||||
SceneManager.stage.addChild(this);
|
||||
}
|
||||
|
||||
if (this._renderers.length == 0) {
|
||||
this.addRenderer(new DefaultRenderer());
|
||||
console.warn("场景开始时没有渲染器 自动添加DefaultRenderer以保证能够正常渲染");
|
||||
}
|
||||
|
||||
this.camera = this.createEntity("camera").getOrCreateComponent(new Camera());
|
||||
|
||||
Physics.reset();
|
||||
|
||||
if (this.entityProcessors)
|
||||
this.entityProcessors.begin();
|
||||
|
||||
this.addEventListener(egret.Event.ACTIVATE, this.onActive, this);
|
||||
this.addEventListener(egret.Event.DEACTIVATE, this.onDeactive, this);
|
||||
this.camera.onSceneSizeChanged(this.stage.stageWidth, this.stage.stageHeight);
|
||||
|
||||
this._didSceneBegin = true;
|
||||
this.onStart();
|
||||
}
|
||||
|
||||
this.entities.removeAllEntities();
|
||||
this.removeChildren();
|
||||
public end() {
|
||||
this._didSceneBegin = false;
|
||||
|
||||
Physics.clear();
|
||||
this.removeEventListener(egret.Event.DEACTIVATE, this.onDeactive, this);
|
||||
this.removeEventListener(egret.Event.ACTIVATE, this.onActive, this);
|
||||
|
||||
this.camera = null;
|
||||
this.content.dispose();
|
||||
for (let i = 0; i < this._renderers.length; i++) {
|
||||
this._renderers[i].unload();
|
||||
}
|
||||
|
||||
if (this.entityProcessors)
|
||||
this.entityProcessors.end();
|
||||
|
||||
this.unload();
|
||||
|
||||
if (this.parent)
|
||||
this.parent.removeChild(this);
|
||||
}
|
||||
|
||||
protected async onStart() {
|
||||
|
||||
}
|
||||
|
||||
/** 场景激活 */
|
||||
protected onActive() {
|
||||
|
||||
}
|
||||
|
||||
/** 场景失去焦点 */
|
||||
protected onDeactive() {
|
||||
|
||||
}
|
||||
|
||||
protected unload() { }
|
||||
|
||||
public update() {
|
||||
this.entities.updateLists();
|
||||
|
||||
if (this.entityProcessors)
|
||||
this.entityProcessors.update()
|
||||
|
||||
this.entities.update();
|
||||
|
||||
if (this.entityProcessors)
|
||||
this.entityProcessors.lateUpdate();
|
||||
|
||||
this.renderableComponents.updateList();
|
||||
}
|
||||
|
||||
public postRender() {
|
||||
let enabledCounter = 0;
|
||||
if (this.enablePostProcessing) {
|
||||
for (let i = 0; i < this._postProcessors.length; i++) {
|
||||
if (this._postProcessors[i].enable) {
|
||||
let isEven = MathHelper.isEven(enabledCounter);
|
||||
enabledCounter ++;
|
||||
this._postProcessors[i].unload();
|
||||
}
|
||||
|
||||
this._postProcessors[i].process();
|
||||
this.entities.removeAllEntities();
|
||||
this.removeChildren();
|
||||
|
||||
this.camera = null;
|
||||
this.content.dispose();
|
||||
|
||||
if (this.entityProcessors)
|
||||
this.entityProcessors.end();
|
||||
|
||||
if (this.parent)
|
||||
this.parent.removeChild(this);
|
||||
|
||||
this.unload();
|
||||
}
|
||||
|
||||
public update() {
|
||||
// 更新我们的列表,以防它们有任何变化
|
||||
this.entities.updateLists();
|
||||
|
||||
// 更新我们的实体解析器
|
||||
if (this.entityProcessors)
|
||||
this.entityProcessors.update();
|
||||
|
||||
// 更新我们的实体组
|
||||
this.entities.update();
|
||||
|
||||
if (this.entityProcessors)
|
||||
this.entityProcessors.lateUpdate();
|
||||
|
||||
// 我们在实体之后更新我们的呈现。如果添加了任何新的渲染,请进行更新
|
||||
this.renderableComponents.updateList();
|
||||
}
|
||||
|
||||
public render() {
|
||||
if (this._renderers.length == 0){
|
||||
console.error("there are no renderers in the scene!");
|
||||
return;
|
||||
}
|
||||
|
||||
for (let i = 0; i < this._renderers.length; i++) {
|
||||
this._renderers[i].render(this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 现在的任何后处理器都要完成它的处理
|
||||
* 只有在SceneTransition请求渲染时,它才会有一个值。
|
||||
*/
|
||||
public postRender() {
|
||||
if (this.enablePostProcessing) {
|
||||
for (let i = 0; i < this._postProcessors.length; i++) {
|
||||
if (this._postProcessors[i].enabled) {
|
||||
this._postProcessors[i].process();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public render() {
|
||||
for (let i = 0; i < this._renderers.length; i++) {
|
||||
this._renderers[i].render(this);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 为场景添加一个渲染器
|
||||
* @param renderer
|
||||
*/
|
||||
public addRenderer<T extends Renderer>(renderer: T) {
|
||||
this._renderers.push(renderer);
|
||||
this._renderers.sort();
|
||||
|
||||
public addPostProcessor<T extends PostProcessor>(postProcessor: T): T{
|
||||
this._postProcessors.push(postProcessor);
|
||||
this._postProcessors.sort();
|
||||
postProcessor.onAddedToScene(this);
|
||||
renderer.onAddedToScene(this);
|
||||
|
||||
if (this._didSceneBegin){
|
||||
postProcessor.onSceneBackBufferSizeChanged(this.stage.stageWidth, this.stage.stageHeight);
|
||||
return renderer;
|
||||
}
|
||||
|
||||
return postProcessor;
|
||||
/**
|
||||
* 获取类型为T的第一个渲染器
|
||||
* @param type
|
||||
*/
|
||||
public getRenderer<T extends Renderer>(type): T {
|
||||
for (let i = 0; i < this._renderers.length; i++) {
|
||||
if (this._renderers[i] instanceof type)
|
||||
return this._renderers[i] as T;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从场景中移除渲染器
|
||||
* @param renderer
|
||||
*/
|
||||
public removeRenderer(renderer: Renderer) {
|
||||
if (!this._renderers.contains(renderer))
|
||||
return;
|
||||
this._renderers.remove(renderer);
|
||||
renderer.unload();
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加一个后处理器到场景。设置场景字段并调用后处理器。onAddedToScene使后处理器可以使用场景ContentManager加载资源。
|
||||
* @param postProcessor
|
||||
*/
|
||||
public addPostProcessor<T extends PostProcessor>(postProcessor: T): T{
|
||||
this._postProcessors.push(postProcessor);
|
||||
this._postProcessors.sort();
|
||||
postProcessor.onAddedToScene(this);
|
||||
|
||||
if (this._didSceneBegin){
|
||||
postProcessor.onSceneBackBufferSizeChanged(this.stage.stageWidth, this.stage.stageHeight);
|
||||
}
|
||||
|
||||
return postProcessor;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取类型为T的第一个后处理器
|
||||
* @param type
|
||||
*/
|
||||
public getPostProcessor<T extends PostProcessor>(type): T{
|
||||
for (let i = 0; i < this._postProcessors.length; i ++){
|
||||
if (this._postProcessors[i] instanceof type)
|
||||
return this._postProcessors[i] as T;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除一个后处理程序。注意,在删除时不会调用unload,因此如果不再需要PostProcessor,请确保调用unload来释放资源。
|
||||
* @param postProcessor
|
||||
*/
|
||||
public removePostProcessor(postProcessor: PostProcessor){
|
||||
if (!this._postProcessors.contains(postProcessor))
|
||||
return;
|
||||
|
||||
this._postProcessors.remove(postProcessor);
|
||||
postProcessor.unload();
|
||||
}
|
||||
|
||||
/**
|
||||
* 将实体添加到此场景,并返回它
|
||||
* @param name
|
||||
*/
|
||||
public createEntity(name: string) {
|
||||
let entity = new Entity(name);
|
||||
return this.addEntity(entity);
|
||||
}
|
||||
|
||||
/**
|
||||
* 在场景的实体列表中添加一个实体
|
||||
* @param entity
|
||||
*/
|
||||
public addEntity(entity: Entity) {
|
||||
if (this.entities.buffer.contains(entity))
|
||||
console.warn(`You are attempting to add the same entity to a scene twice: ${entity}`);
|
||||
this.entities.add(entity);
|
||||
entity.scene = this;
|
||||
|
||||
for (let i = 0; i < entity.transform.childCount; i++)
|
||||
this.addEntity(entity.transform.getChild(i).entity);
|
||||
|
||||
return entity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从场景中删除所有实体
|
||||
*/
|
||||
public destroyAllEntities() {
|
||||
for (let i = 0; i < this.entities.count; i++) {
|
||||
this.entities.buffer[i].destroy();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 搜索并返回第一个具有名称的实体
|
||||
* @param name
|
||||
*/
|
||||
public findEntity(name: string): Entity {
|
||||
return this.entities.findEntity(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回具有给定标记的所有实体
|
||||
* @param tag
|
||||
*/
|
||||
public findEntitiesWithTag(tag: number): Entity[]{
|
||||
return this.entities.entitiesWithTag(tag);
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回类型为T的所有实体
|
||||
* @param type
|
||||
*/
|
||||
public entitiesOfType<T extends Entity>(type): T[]{
|
||||
return this.entities.entitiesOfType<T>(type);
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回第一个启用加载的类型为T的组件
|
||||
* @param type
|
||||
*/
|
||||
public findComponentOfType<T extends Component>(type): T {
|
||||
return this.entities.findComponentOfType<T>(type);
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回类型为T的所有已启用已加载组件的列表
|
||||
* @param type
|
||||
*/
|
||||
public findComponentsOfType<T extends Component>(type): T[] {
|
||||
return this.entities.findComponentsOfType<T>(type);
|
||||
}
|
||||
|
||||
/**
|
||||
* 在场景中添加一个EntitySystem处理器
|
||||
* @param processor 处理器
|
||||
*/
|
||||
public addEntityProcessor(processor: EntitySystem) {
|
||||
processor.scene = this;
|
||||
this.entityProcessors.add(processor);
|
||||
return processor;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从场景中删除EntitySystem处理器
|
||||
* @param processor
|
||||
*/
|
||||
public removeEntityProcessor(processor: EntitySystem) {
|
||||
this.entityProcessors.remove(processor);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取EntitySystem处理器
|
||||
*/
|
||||
public getEntityProcessor<T extends EntitySystem>(): T {
|
||||
return this.entityProcessors.getProcessor<T>();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,6 +12,7 @@ class SceneManager {
|
||||
public static content: ContentManager;
|
||||
/** 简化对内部类的全局内容实例的访问 */
|
||||
private static _instnace: SceneManager;
|
||||
private static timerRuler: TimeRuler;
|
||||
public static get Instance(){
|
||||
return this._instnace;
|
||||
}
|
||||
@@ -25,6 +26,7 @@ class SceneManager {
|
||||
|
||||
SceneManager.stage = stage;
|
||||
SceneManager.initialize(stage);
|
||||
SceneManager.timerRuler = new TimeRuler();
|
||||
}
|
||||
|
||||
public static get scene() {
|
||||
@@ -50,6 +52,7 @@ class SceneManager {
|
||||
}
|
||||
|
||||
public static update() {
|
||||
SceneManager.startDebugUpdate();
|
||||
Time.update(egret.getTimer());
|
||||
|
||||
if (SceneManager._scene) {
|
||||
@@ -74,6 +77,7 @@ class SceneManager {
|
||||
}
|
||||
}
|
||||
|
||||
SceneManager.endDebugUpdate();
|
||||
SceneManager.render();
|
||||
}
|
||||
|
||||
@@ -128,4 +132,13 @@ class SceneManager {
|
||||
SceneManager.emitter.emit(CoreEvents.SceneChanged);
|
||||
Time.sceneChanged();
|
||||
}
|
||||
|
||||
private static startDebugUpdate(){
|
||||
TimeRuler.Instance.startFrame();
|
||||
TimeRuler.Instance.beginMark("update", 0x00FF00);
|
||||
}
|
||||
|
||||
private static endDebugUpdate(){
|
||||
TimeRuler.Instance.endMark("update");
|
||||
}
|
||||
}
|
||||
138
source/src/ECS/Transform.ts
Normal file
138
source/src/ECS/Transform.ts
Normal file
@@ -0,0 +1,138 @@
|
||||
module es {
|
||||
export class Transform {
|
||||
/** 与此转换关联的实体 */
|
||||
public readonly entity: Entity;
|
||||
|
||||
private _parent: Transform;
|
||||
/**
|
||||
* 获取此转换的父转换
|
||||
*/
|
||||
public get parent() {
|
||||
return this._parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置此转换的父转换
|
||||
* @param value
|
||||
*/
|
||||
public set parent(value: Transform) {
|
||||
this.setParent(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 这个转换的所有子元素
|
||||
*/
|
||||
public get childCount() {
|
||||
return this._children.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* 变换在世界空间中的位置
|
||||
*/
|
||||
public position: Vector2;
|
||||
/**
|
||||
* 变换在世界空间的旋转度
|
||||
*/
|
||||
public rotation: number;
|
||||
/**
|
||||
* 变换在世界空间的缩放
|
||||
*/
|
||||
public scale: Vector2;
|
||||
public _children: Transform[];
|
||||
|
||||
constructor(entity: Entity) {
|
||||
this.entity = entity;
|
||||
this.scale = Vector2.one;
|
||||
this._children = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回在索引处的转换子元素
|
||||
* @param index
|
||||
*/
|
||||
public getChild(index: number): Transform {
|
||||
return this._children[index];
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置此转换的父转换
|
||||
* @param parent
|
||||
*/
|
||||
public setParent(parent: Transform): Transform {
|
||||
if (this._parent == parent)
|
||||
return this;
|
||||
|
||||
if (!this._parent) {
|
||||
this._parent._children.remove(this);
|
||||
this._parent._children.push(this);
|
||||
}
|
||||
|
||||
this._parent = parent;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置转换在世界空间中的位置
|
||||
* @param x
|
||||
* @param y
|
||||
*/
|
||||
public setPosition(x: number, y: number): Transform {
|
||||
this.position = new Vector2(x, y);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置变换在世界空间的旋转度
|
||||
* @param degrees
|
||||
*/
|
||||
public setRotation(degrees: number): Transform {
|
||||
this.rotation = degrees;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置变换在世界空间中的缩放
|
||||
* @param scale
|
||||
*/
|
||||
public setScale(scale: Vector2): Transform {
|
||||
this.scale = scale;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 旋转精灵的顶部,使其朝向位置
|
||||
* @param pos
|
||||
*/
|
||||
public lookAt(pos: Vector2) {
|
||||
let sign = this.position.x > pos.x ? -1 : 1;
|
||||
let vectorToAlignTo = Vector2.normalize(Vector2.subtract(this.position, pos));
|
||||
this.rotation = sign * Math.acos(Vector2.dot(vectorToAlignTo, Vector2.unitY));
|
||||
}
|
||||
|
||||
/**
|
||||
* 对精灵坐标进行四舍五入
|
||||
*/
|
||||
public roundPosition() {
|
||||
this.position = this.position.round();
|
||||
}
|
||||
|
||||
/**
|
||||
* 从另一个transform属性进行拷贝
|
||||
* @param transform
|
||||
*/
|
||||
public copyFrom(transform: Transform) {
|
||||
this.position = transform.position;
|
||||
this.rotation = transform.rotation;
|
||||
this.scale = transform.scale;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module Transform {
|
||||
export enum Component {
|
||||
position,
|
||||
scale,
|
||||
rotation,
|
||||
}
|
||||
}
|
||||
@@ -1,224 +1,241 @@
|
||||
class ComponentList {
|
||||
private _entity: Entity;
|
||||
/** 添加到实体的组件列表 */
|
||||
private _components: Component[] = [];
|
||||
/** 添加到此框架的组件列表。用来对组件进行分组,这样我们就可以同时进行加工 */
|
||||
private _componentsToAdd: Component[] = [];
|
||||
/** 标记要删除此框架的组件列表。用来对组件进行分组,这样我们就可以同时进行加工 */
|
||||
private _componentsToRemove: Component[] = [];
|
||||
private _tempBufferList: Component[] = [];
|
||||
module es {
|
||||
export class ComponentList {
|
||||
public _entity: Entity;
|
||||
|
||||
constructor(entity: Entity) {
|
||||
this._entity = entity;
|
||||
}
|
||||
/**
|
||||
* 添加到实体的组件列表
|
||||
*/
|
||||
public _components: Component[] = [];
|
||||
/**
|
||||
* 添加到此框架的组件列表。用来对组件进行分组,这样我们就可以同时进行加工
|
||||
*/
|
||||
public _componentsToAdd: Component[] = [];
|
||||
/**
|
||||
* 标记要删除此框架的组件列表。用来对组件进行分组,这样我们就可以同时进行加工
|
||||
*/
|
||||
public _componentsToRemove: Component[] = [];
|
||||
public _tempBufferList: Component[] = [];
|
||||
|
||||
public get count() {
|
||||
return this._components.length;
|
||||
}
|
||||
|
||||
public get buffer() {
|
||||
return this._components;
|
||||
}
|
||||
|
||||
public add(component: Component) {
|
||||
this._componentsToAdd.push(component);
|
||||
}
|
||||
|
||||
public remove(component: Component) {
|
||||
if (this._componentsToRemove.contains(component))
|
||||
console.warn(`You are trying to remove a Component (${component}) that you already removed`)
|
||||
|
||||
// 这可能不是一个活动的组件,所以我们必须注意它是否还没有被处理,它可能正在同一帧中被删除
|
||||
if (this._componentsToAdd.contains(component)) {
|
||||
this._componentsToAdd.remove(component);
|
||||
return;
|
||||
constructor(entity: Entity) {
|
||||
this._entity = entity;
|
||||
}
|
||||
|
||||
this._componentsToRemove.push(component);
|
||||
}
|
||||
|
||||
/**
|
||||
* 立即从组件列表中删除所有组件
|
||||
*/
|
||||
public removeAllComponents() {
|
||||
for (let i = 0; i < this._components.length; i++) {
|
||||
this.handleRemove(this._components[i]);
|
||||
public get count() {
|
||||
return this._components.length;
|
||||
}
|
||||
|
||||
this._components.length = 0;
|
||||
this._componentsToAdd.length = 0;
|
||||
this._componentsToRemove.length = 0;
|
||||
}
|
||||
public get buffer() {
|
||||
return this._components;
|
||||
}
|
||||
|
||||
public deregisterAllComponents() {
|
||||
for (let i = 0; i < this._components.length; i++) {
|
||||
let component = this._components[i];
|
||||
public add(component: Component) {
|
||||
this._componentsToAdd.push(component);
|
||||
}
|
||||
|
||||
public remove(component: Component) {
|
||||
if (this._componentsToRemove.contains(component))
|
||||
console.warn(`You are trying to remove a Component (${component}) that you already removed`)
|
||||
|
||||
// 这可能不是一个活动的组件,所以我们必须注意它是否还没有被处理,它可能正在同一帧中被删除
|
||||
if (this._componentsToAdd.contains(component)) {
|
||||
this._componentsToAdd.remove(component);
|
||||
return;
|
||||
}
|
||||
|
||||
this._componentsToRemove.push(component);
|
||||
}
|
||||
|
||||
/**
|
||||
* 立即从组件列表中删除所有组件
|
||||
*/
|
||||
public removeAllComponents() {
|
||||
for (let i = 0; i < this._components.length; i++) {
|
||||
this.handleRemove(this._components[i]);
|
||||
}
|
||||
|
||||
this._components.length = 0;
|
||||
this._componentsToAdd.length = 0;
|
||||
this._componentsToRemove.length = 0;
|
||||
}
|
||||
|
||||
public deregisterAllComponents() {
|
||||
for (let i = 0; i < this._components.length; i++) {
|
||||
let component = this._components[i];
|
||||
|
||||
// 处理渲染层列表
|
||||
if (component instanceof RenderableComponent)
|
||||
this._entity.scene.renderableComponents.remove(component);
|
||||
|
||||
this._entity.componentBits.set(ComponentTypeManager.getIndexFor(component), false);
|
||||
this._entity.scene.entityProcessors.onComponentRemoved(this._entity);
|
||||
}
|
||||
}
|
||||
|
||||
public registerAllComponents() {
|
||||
for (let i = 0; i < this._components.length; i++) {
|
||||
let component = this._components[i];
|
||||
|
||||
if (component instanceof RenderableComponent)
|
||||
this._entity.scene.renderableComponents.add(component);
|
||||
|
||||
this._entity.componentBits.set(ComponentTypeManager.getIndexFor(component));
|
||||
this._entity.scene.entityProcessors.onComponentAdded(this._entity);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理任何需要删除或添加的组件
|
||||
*/
|
||||
public updateLists() {
|
||||
if (this._componentsToRemove.length > 0) {
|
||||
for (let i = 0; i < this._componentsToRemove.length; i++) {
|
||||
this.handleRemove(this._componentsToRemove[i]);
|
||||
this._components.remove(this._componentsToRemove[i]);
|
||||
}
|
||||
|
||||
this._componentsToRemove.length = 0;
|
||||
}
|
||||
|
||||
if (this._componentsToAdd.length > 0) {
|
||||
for (let i = 0, count = this._componentsToAdd.length; i < count; i++) {
|
||||
let component = this._componentsToAdd[i];
|
||||
if (component instanceof RenderableComponent)
|
||||
this._entity.scene.renderableComponents.add(component);
|
||||
|
||||
this._entity.componentBits.set(ComponentTypeManager.getIndexFor(component));
|
||||
this._entity.scene.entityProcessors.onComponentAdded(this._entity);
|
||||
|
||||
this._components.push(component);
|
||||
this._tempBufferList.push(component);
|
||||
}
|
||||
|
||||
// 在调用onAddedToEntity之前清除,以防添加更多组件
|
||||
this._componentsToAdd.length = 0;
|
||||
|
||||
// 现在所有的组件都添加到了场景中,我们再次循环并调用onAddedToEntity/onEnabled
|
||||
for (let i = 0; i < this._tempBufferList.length; i++) {
|
||||
let component = this._tempBufferList[i];
|
||||
component.onAddedToEntity();
|
||||
|
||||
// enabled检查实体和组件
|
||||
if (component.enabled) {
|
||||
component.onEnabled();
|
||||
}
|
||||
}
|
||||
|
||||
this._tempBufferList.length = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public handleRemove(component: Component) {
|
||||
// 处理渲染层列表
|
||||
if (component instanceof RenderableComponent)
|
||||
this._entity.scene.renderableComponents.remove(component);
|
||||
|
||||
this._entity.componentBits.set(ComponentTypeManager.getIndexFor(component), false);
|
||||
this._entity.scene.entityProcessors.onComponentRemoved(this._entity);
|
||||
}
|
||||
}
|
||||
|
||||
public registerAllComponents() {
|
||||
for (let i = 0; i < this._components.length; i++) {
|
||||
let component = this._components[i];
|
||||
|
||||
if (component instanceof RenderableComponent)
|
||||
this._entity.scene.renderableComponents.add(component);
|
||||
|
||||
this._entity.componentBits.set(ComponentTypeManager.getIndexFor(component));
|
||||
this._entity.scene.entityProcessors.onComponentAdded(this._entity);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理任何需要删除或添加的组件
|
||||
*/
|
||||
public updateLists() {
|
||||
if (this._componentsToRemove.length > 0) {
|
||||
for (let i = 0; i < this._componentsToRemove.length; i++) {
|
||||
this.handleRemove(this._componentsToRemove[i]);
|
||||
this._components.remove(this._componentsToRemove[i]);
|
||||
}
|
||||
|
||||
this._componentsToRemove.length = 0;
|
||||
component.onRemovedFromEntity();
|
||||
component.entity = null;
|
||||
}
|
||||
|
||||
if (this._componentsToAdd.length > 0) {
|
||||
for (let i = 0, count = this._componentsToAdd.length; i < count; i++) {
|
||||
let component = this._componentsToAdd[i];
|
||||
if (component instanceof RenderableComponent)
|
||||
this._entity.scene.renderableComponents.add(component);
|
||||
|
||||
this._entity.componentBits.set(ComponentTypeManager.getIndexFor(component));
|
||||
this._entity.scene.entityProcessors.onComponentAdded(this._entity);
|
||||
|
||||
this._components.push(component);
|
||||
this._tempBufferList.push(component);
|
||||
}
|
||||
|
||||
// 在调用onAddedToEntity之前清除,以防添加更多组件
|
||||
this._componentsToAdd.length = 0;
|
||||
|
||||
// 现在所有的组件都添加到了场景中,我们再次循环并调用onAddedToEntity/onEnabled
|
||||
for (let i = 0; i < this._tempBufferList.length; i++) {
|
||||
let component = this._tempBufferList[i];
|
||||
component.onAddedToEntity();
|
||||
|
||||
// enabled检查实体和组件
|
||||
if (component.enabled) {
|
||||
component.onEnabled();
|
||||
}
|
||||
}
|
||||
|
||||
this._tempBufferList.length = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public onEntityTransformChanged(comp: TransformComponent) {
|
||||
for (let i = 0; i < this._components.length; i++) {
|
||||
if (this._components[i].enabled)
|
||||
this._components[i].onEntityTransformChanged(comp);
|
||||
}
|
||||
|
||||
for (let i = 0; i < this._componentsToAdd.length; i++) {
|
||||
if (this._componentsToAdd[i].enabled)
|
||||
this._componentsToAdd[i].onEntityTransformChanged(comp);
|
||||
}
|
||||
}
|
||||
|
||||
private handleRemove(component: Component) {
|
||||
if (component instanceof RenderableComponent)
|
||||
this._entity.scene.renderableComponents.remove(component);
|
||||
|
||||
this._entity.componentBits.set(ComponentTypeManager.getIndexFor(component), false);
|
||||
this._entity.scene.entityProcessors.onComponentRemoved(this._entity);
|
||||
|
||||
component.onRemovedFromEntity();
|
||||
component.entity = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取类型T的第一个组件并返回它
|
||||
* 可以选择跳过检查未初始化的组件(尚未调用onAddedToEntity方法的组件)
|
||||
* 如果没有找到组件,则返回null。
|
||||
* @param type
|
||||
* @param onlyReturnInitializedComponents
|
||||
*/
|
||||
public getComponent<T extends Component>(type, onlyReturnInitializedComponents: boolean): T {
|
||||
for (let i = 0; i < this._components.length; i++) {
|
||||
let component = this._components[i];
|
||||
if (component instanceof type)
|
||||
return component as T;
|
||||
}
|
||||
|
||||
// 我们可以选择检查挂起的组件,以防addComponent和getComponent在同一个框架中被调用
|
||||
if (!onlyReturnInitializedComponents) {
|
||||
for (let i = 0; i < this._componentsToAdd.length; i++) {
|
||||
let component = this._componentsToAdd[i];
|
||||
/**
|
||||
* 获取类型T的第一个组件并返回它
|
||||
* 可以选择跳过检查未初始化的组件(尚未调用onAddedToEntity方法的组件)
|
||||
* 如果没有找到组件,则返回null。
|
||||
* @param type
|
||||
* @param onlyReturnInitializedComponents
|
||||
*/
|
||||
public getComponent<T extends Component>(type, onlyReturnInitializedComponents: boolean): T {
|
||||
for (let i = 0; i < this._components.length; i++) {
|
||||
let component = this._components[i];
|
||||
if (component instanceof type)
|
||||
return component as T;
|
||||
}
|
||||
|
||||
// 我们可以选择检查挂起的组件,以防addComponent和getComponent在同一个框架中被调用
|
||||
if (!onlyReturnInitializedComponents) {
|
||||
for (let i = 0; i < this._componentsToAdd.length; i++) {
|
||||
let component = this._componentsToAdd[i];
|
||||
if (component instanceof type)
|
||||
return component as T;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
/**
|
||||
* 获取T类型的所有组件,但不使用列表分配
|
||||
* @param typeName
|
||||
* @param components
|
||||
*/
|
||||
public getComponents(typeName: string | any, components?) {
|
||||
if (!components)
|
||||
components = [];
|
||||
|
||||
/**
|
||||
* 获取T类型的所有组件,但不使用列表分配
|
||||
* @param typeName
|
||||
* @param components
|
||||
*/
|
||||
public getComponents(typeName: string | any, components?) {
|
||||
if (!components)
|
||||
components = [];
|
||||
for (let i = 0; i < this._components.length; i++) {
|
||||
let component = this._components[i];
|
||||
if (typeof (typeName) == "string") {
|
||||
if (egret.is(component, typeName)) {
|
||||
components.push(component);
|
||||
}
|
||||
} else {
|
||||
if (component instanceof typeName) {
|
||||
components.push(component);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (let i = 0; i < this._components.length; i++) {
|
||||
let component = this._components[i];
|
||||
if (typeof (typeName) == "string") {
|
||||
if (egret.is(component, typeName)) {
|
||||
components.push(component);
|
||||
}
|
||||
} else {
|
||||
if (component instanceof typeName) {
|
||||
components.push(component);
|
||||
for (let i = 0; i < this._componentsToAdd.length; i++) {
|
||||
let component = this._componentsToAdd[i];
|
||||
if (typeof (typeName) == "string") {
|
||||
if (egret.is(component, typeName)) {
|
||||
components.push(component);
|
||||
}
|
||||
} else {
|
||||
if (component instanceof typeName) {
|
||||
components.push(component);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return components;
|
||||
}
|
||||
|
||||
public update() {
|
||||
this.updateLists();
|
||||
for (let i = 0; i < this._components.length; i++) {
|
||||
let updatableComponent = this._components[i];
|
||||
|
||||
if (updatableComponent.enabled &&
|
||||
(updatableComponent.updateInterval == 1 ||
|
||||
Time.frameCount % updatableComponent.updateInterval == 0))
|
||||
updatableComponent.update();
|
||||
}
|
||||
}
|
||||
|
||||
for (let i = 0; i < this._componentsToAdd.length; i++) {
|
||||
let component = this._componentsToAdd[i];
|
||||
if (typeof (typeName) == "string") {
|
||||
if (egret.is(component, typeName)) {
|
||||
components.push(component);
|
||||
}
|
||||
} else {
|
||||
if (component instanceof typeName) {
|
||||
components.push(component);
|
||||
}
|
||||
public onEntityTransformChanged(comp: Transform.Component) {
|
||||
for (let i = 0; i < this._components.length; i++) {
|
||||
if (this._components[i].enabled)
|
||||
this._components[i].onEntityTransformChanged(comp);
|
||||
}
|
||||
|
||||
for (let i = 0; i < this._componentsToAdd.length; i++) {
|
||||
if (this._componentsToAdd[i].enabled)
|
||||
this._componentsToAdd[i].onEntityTransformChanged(comp);
|
||||
}
|
||||
}
|
||||
|
||||
return components;
|
||||
}
|
||||
public onEntityEnabled() {
|
||||
for (let i = 0; i < this._components.length; i++)
|
||||
this._components[i].onEnabled();
|
||||
}
|
||||
|
||||
public update() {
|
||||
this.updateLists();
|
||||
for (let i = 0; i < this._components.length; i++) {
|
||||
let updatable = this._components[i];
|
||||
let updateableComponent;
|
||||
if (updatable instanceof Component)
|
||||
updateableComponent = updatable as Component;
|
||||
|
||||
if (updatable.enabled &&
|
||||
updateableComponent.enabled &&
|
||||
(updateableComponent.updateInterval == 1 ||
|
||||
Time.frameCount % updateableComponent.updateInterval == 0))
|
||||
updatable.update();
|
||||
public onEntityDisabled() {
|
||||
for (let i = 0; i < this._components.length; i++)
|
||||
this._components[i].onDisabled();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,134 +1,213 @@
|
||||
class EntityList{
|
||||
public scene: Scene;
|
||||
private _entitiesToRemove: Entity[] = [];
|
||||
private _entitiesToAdded: Entity[] = [];
|
||||
private _tempEntityList: Entity[] = [];
|
||||
private _entities: Entity[] = [];
|
||||
private _entityDict: Map<number, Entity[]> = new Map<number, Entity[]>();
|
||||
private _unsortedTags: number[] = [];
|
||||
module es {
|
||||
export class EntityList{
|
||||
public scene: Scene;
|
||||
private _entitiesToRemove: Entity[] = [];
|
||||
private _entitiesToAdded: Entity[] = [];
|
||||
private _tempEntityList: Entity[] = [];
|
||||
private _entities: Entity[] = [];
|
||||
private _entityDict: Map<number, Entity[]> = new Map<number, Entity[]>();
|
||||
private _unsortedTags: number[] = [];
|
||||
|
||||
constructor(scene: Scene){
|
||||
this.scene = scene;
|
||||
}
|
||||
|
||||
public get count(){
|
||||
return this._entities.length;
|
||||
}
|
||||
|
||||
public get buffer(){
|
||||
return this._entities;
|
||||
}
|
||||
|
||||
public add(entity: Entity){
|
||||
if (this._entitiesToAdded.indexOf(entity) == -1)
|
||||
this._entitiesToAdded.push(entity);
|
||||
}
|
||||
|
||||
public remove(entity: Entity){
|
||||
if (this._entitiesToAdded.contains(entity)){
|
||||
this._entitiesToAdded.remove(entity);
|
||||
return;
|
||||
constructor(scene: Scene){
|
||||
this.scene = scene;
|
||||
}
|
||||
|
||||
if (!this._entitiesToRemove.contains(entity))
|
||||
this._entitiesToRemove.push(entity);
|
||||
}
|
||||
|
||||
public findEntity(name: string){
|
||||
for (let i = 0; i < this._entities.length; i ++){
|
||||
if (this._entities[i].name == name)
|
||||
return this._entities[i];
|
||||
public get count(){
|
||||
return this._entities.length;
|
||||
}
|
||||
|
||||
return this._entitiesToAdded.firstOrDefault(entity => entity.name == name);
|
||||
}
|
||||
|
||||
public getTagList(tag: number){
|
||||
let list = this._entityDict.get(tag);
|
||||
if (!list){
|
||||
list = [];
|
||||
this._entityDict.set(tag, list);
|
||||
public get buffer(){
|
||||
return this._entities;
|
||||
}
|
||||
|
||||
return this._entityDict.get(tag);
|
||||
}
|
||||
|
||||
public addToTagList(entity: Entity){
|
||||
let list = this.getTagList(entity.tag);
|
||||
if (!list.contains(entity)){
|
||||
list.push(entity);
|
||||
this._unsortedTags.push(entity.tag);
|
||||
}
|
||||
}
|
||||
|
||||
public removeFromTagList(entity: Entity){
|
||||
let list = this._entityDict.get(entity.tag);
|
||||
if (list){
|
||||
list.remove(entity);
|
||||
}
|
||||
}
|
||||
|
||||
public update(){
|
||||
for (let i = 0; i < this._entities.length; i++){
|
||||
let entity = this._entities[i];
|
||||
if (entity.enabled)
|
||||
entity.update();
|
||||
}
|
||||
}
|
||||
|
||||
public removeAllEntities(){
|
||||
this._entitiesToAdded.length = 0;
|
||||
|
||||
this.updateLists();
|
||||
|
||||
for (let i = 0; i < this._entities.length; i ++){
|
||||
this._entities[i]._isDestoryed = true;
|
||||
this._entities[i].onRemovedFromScene();
|
||||
this._entities[i].scene = null;
|
||||
public add(entity: Entity){
|
||||
if (this._entitiesToAdded.indexOf(entity) == -1)
|
||||
this._entitiesToAdded.push(entity);
|
||||
}
|
||||
|
||||
this._entities.length = 0;
|
||||
this._entityDict.clear();
|
||||
}
|
||||
public remove(entity: Entity){
|
||||
if (this._entitiesToAdded.contains(entity)){
|
||||
this._entitiesToAdded.remove(entity);
|
||||
return;
|
||||
}
|
||||
|
||||
public updateLists(){
|
||||
if (this._entitiesToRemove.length > 0){
|
||||
let temp = this._entitiesToRemove;
|
||||
this._entitiesToRemove = this._tempEntityList;
|
||||
this._tempEntityList = temp;
|
||||
this._tempEntityList.forEach(entity => {
|
||||
this._entities.remove(entity);
|
||||
entity.scene = null;
|
||||
if (!this._entitiesToRemove.contains(entity))
|
||||
this._entitiesToRemove.push(entity);
|
||||
}
|
||||
|
||||
this.scene.entityProcessors.onEntityRemoved(entity);
|
||||
public findEntity(name: string){
|
||||
for (let i = 0; i < this._entities.length; i ++){
|
||||
if (this._entities[i].name == name)
|
||||
return this._entities[i];
|
||||
}
|
||||
|
||||
return this._entitiesToAdded.firstOrDefault(entity => entity.name == name);
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回带有标记的所有实体的列表。如果没有实体具有标记,则返回一个空列表。可以通过ListPool.free将返回的列表放回池中。
|
||||
* @param tag
|
||||
*/
|
||||
public entitiesWithTag(tag: number){
|
||||
let list = this.getTagList(tag);
|
||||
|
||||
let returnList = ListPool.obtain<Entity>();
|
||||
for (let i = 0; i < list.length; i ++)
|
||||
returnList.push(list[i]);
|
||||
|
||||
return returnList;
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回t类型的所有实体的列表。返回的列表可以通过ListPool.free放回池中。
|
||||
* @param type
|
||||
*/
|
||||
public entitiesOfType<T extends Entity>(type): T[]{
|
||||
let list = ListPool.obtain<T>();
|
||||
for (let i = 0; i < this._entities.length; i ++){
|
||||
if (this._entities[i] instanceof type)
|
||||
list.push(this._entities[i] as T);
|
||||
}
|
||||
this._entitiesToAdded.forEach(entity => {
|
||||
if (entity instanceof type)
|
||||
list.push(entity as T);
|
||||
});
|
||||
|
||||
this._tempEntityList.length = 0;
|
||||
return list;
|
||||
}
|
||||
|
||||
if (this._entitiesToAdded.length > 0){
|
||||
let temp = this._entitiesToAdded;
|
||||
this._entitiesToAdded = this._tempEntityList;
|
||||
this._tempEntityList = temp;
|
||||
this._tempEntityList.forEach(entity => {
|
||||
if (!this._entities.contains(entity)){
|
||||
this._entities.push(entity);
|
||||
entity.scene = this.scene;
|
||||
|
||||
this.scene.entityProcessors.onEntityAdded(entity)
|
||||
/**
|
||||
* 返回在类型为T的场景中找到的第一个组件
|
||||
* @param type
|
||||
*/
|
||||
public findComponentOfType<T extends Component>(type): T {
|
||||
for (let i = 0; i < this._entities.length; i ++){
|
||||
if (this._entities[i].enabled){
|
||||
let comp = this._entities[i].getComponent<T>(type);
|
||||
if (comp)
|
||||
return comp;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
this._tempEntityList.forEach(entity => entity.onAddedToScene());
|
||||
this._tempEntityList.length = 0;
|
||||
for (let i = 0; i < this._entitiesToAdded.length; i ++){
|
||||
let entity = this._entitiesToAdded[i];
|
||||
if (entity.enabled){
|
||||
let comp = entity.getComponent<T>(type);
|
||||
if (comp)
|
||||
return comp;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
if (this._unsortedTags.length > 0){
|
||||
this._unsortedTags.forEach(tag => {
|
||||
this._entityDict.get(tag).sort();
|
||||
});
|
||||
/**
|
||||
* 返回在类型t的场景中找到的所有组件。返回的列表可以通过ListPool.free放回池中。
|
||||
* @param type
|
||||
*/
|
||||
public findComponentsOfType<T extends Component>(type): T[]{
|
||||
let comps = ListPool.obtain<T>();
|
||||
for (let i = 0; i < this._entities.length; i ++){
|
||||
if (this._entities[i].enabled)
|
||||
this._entities[i].getComponents(type, comps);
|
||||
}
|
||||
|
||||
this._unsortedTags.length = 0;
|
||||
for (let i = 0; i < this._entitiesToAdded.length; i ++){
|
||||
let entity = this._entitiesToAdded[i];
|
||||
if (entity.enabled)
|
||||
entity.getComponents(type,comps);
|
||||
}
|
||||
|
||||
return comps;
|
||||
}
|
||||
|
||||
public getTagList(tag: number){
|
||||
let list = this._entityDict.get(tag);
|
||||
if (!list){
|
||||
list = [];
|
||||
this._entityDict.set(tag, list);
|
||||
}
|
||||
|
||||
return this._entityDict.get(tag);
|
||||
}
|
||||
|
||||
public addToTagList(entity: Entity){
|
||||
let list = this.getTagList(entity.tag);
|
||||
if (!list.contains(entity)){
|
||||
list.push(entity);
|
||||
this._unsortedTags.push(entity.tag);
|
||||
}
|
||||
}
|
||||
|
||||
public removeFromTagList(entity: Entity){
|
||||
let list = this._entityDict.get(entity.tag);
|
||||
if (list){
|
||||
list.remove(entity);
|
||||
}
|
||||
}
|
||||
|
||||
public update(){
|
||||
for (let i = 0; i < this._entities.length; i++){
|
||||
let entity = this._entities[i];
|
||||
if (entity.enabled)
|
||||
entity.update();
|
||||
}
|
||||
}
|
||||
|
||||
public removeAllEntities(){
|
||||
this._entitiesToAdded.length = 0;
|
||||
|
||||
this.updateLists();
|
||||
|
||||
for (let i = 0; i < this._entities.length; i ++){
|
||||
this._entities[i]._isDestoryed = true;
|
||||
this._entities[i].onRemovedFromScene();
|
||||
this._entities[i].scene = null;
|
||||
}
|
||||
|
||||
this._entities.length = 0;
|
||||
this._entityDict.clear();
|
||||
}
|
||||
|
||||
public updateLists(){
|
||||
if (this._entitiesToRemove.length > 0){
|
||||
let temp = this._entitiesToRemove;
|
||||
this._entitiesToRemove = this._tempEntityList;
|
||||
this._tempEntityList = temp;
|
||||
this._tempEntityList.forEach(entity => {
|
||||
this._entities.remove(entity);
|
||||
entity.scene = null;
|
||||
|
||||
this.scene.entityProcessors.onEntityRemoved(entity);
|
||||
});
|
||||
|
||||
this._tempEntityList.length = 0;
|
||||
}
|
||||
|
||||
if (this._entitiesToAdded.length > 0){
|
||||
let temp = this._entitiesToAdded;
|
||||
this._entitiesToAdded = this._tempEntityList;
|
||||
this._tempEntityList = temp;
|
||||
this._tempEntityList.forEach(entity => {
|
||||
if (!this._entities.contains(entity)){
|
||||
this._entities.push(entity);
|
||||
entity.scene = this.scene;
|
||||
|
||||
this.scene.entityProcessors.onEntityAdded(entity)
|
||||
}
|
||||
});
|
||||
|
||||
this._tempEntityList.forEach(entity => entity.onAddedToScene());
|
||||
this._tempEntityList.length = 0;
|
||||
}
|
||||
|
||||
if (this._unsortedTags.length > 0){
|
||||
this._unsortedTags.forEach(tag => {
|
||||
this._entityDict.get(tag).sort();
|
||||
});
|
||||
|
||||
this._unsortedTags.length = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user