Files
esengine/source/src/ECS/Components/RenderableComponent.ts

229 lines
8.1 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
///<reference path="./PooledComponent.ts" />
module es {
/**
* 所有可渲染组件的基类
*/
export abstract class RenderableComponent extends Component implements IRenderable {
/**
* 用于装载egret显示对象
*/
public displayObject: egret.DisplayObject = new egret.DisplayObject();
public hollowShape: egret.Shape = new egret.Shape();
public pixelShape: egret.Shape = new egret.Shape();
/**
* 用于着色器处理精灵
*/
public color: number = 0x000000;
protected _areBoundsDirty = true;
/**
* renderableComponent的宽度
* 如果你不重写bounds属性则需要实现这个
*/
public get width() {
return this.bounds.width;
}
/**
* renderableComponent的高度
* 如果你不重写bounds属性则需要实现这个
*/
public get height() {
return this.bounds.height;
}
public debugRenderEnabled: boolean = true;
protected _localOffset: Vector2 = Vector2.zero;
/**
* 从父实体的偏移量。用于向需要特定定位的实体
*/
public get localOffset(): Vector2 {
return this._localOffset;
}
/**
* 从父实体的偏移量。用于向需要特定定位的实体
* @param value
*/
public set localOffset(value: Vector2) {
this.setLocalOffset(value);
}
protected _renderLayer: number = 0;
/**
* 较低的渲染层在前面,较高的在后面
*/
public get renderLayer(): number {
return this._renderLayer;
}
public set renderLayer(value: number) {
this.setRenderLayer(value);
}
protected _bounds: Rectangle = new Rectangle();
/**
* 这个物体的AABB, 用于相机剔除
*/
public get bounds(): Rectangle {
if (this._areBoundsDirty) {
this._bounds.calculateBounds(this.entity.transform.position, this._localOffset, Vector2.zero,
this.entity.transform.scale, this.entity.transform.rotation, this.width, this.height);
this._areBoundsDirty = false;
}
return this._bounds;
}
private _isVisible: boolean;
/**
* 可渲染的可见性。状态的改变会调用onBecameVisible/onBecameInvisible方法
*/
public get isVisible() {
return this._isVisible;
}
/**
* 可渲染的可见性。状态的改变会调用onBecameVisible/onBecameInvisible方法
* @param value
*/
public set isVisible(value: boolean) {
if (this._isVisible != value) {
this._isVisible = value;
if (this._isVisible)
this.onBecameVisible();
else
this.onBecameInvisible();
}
}
public onEntityTransformChanged(comp: transform.Component) {
this._areBoundsDirty = true;
}
/**
* 由渲染器调用。可以使用摄像机进行剔除
* @param camera
*/
public abstract render(camera: Camera);
public debugRender() {
if (!this.debugRenderEnabled)
return;
if (!this.hollowShape.parent)
this.debugDisplayObject.addChild(this.hollowShape);
if (!this.pixelShape.parent)
this.debugDisplayObject.addChild(this.pixelShape);
// if (!this.entity.getComponent(Collider)){
// this.hollowShape.graphics.clear();
// this.hollowShape.graphics.beginFill(Colors.renderableBounds, 0);
// this.hollowShape.graphics.lineStyle(1, Colors.renderableBounds);
// this.hollowShape.graphics.drawRect(this.bounds.x, this.bounds.y, this.bounds.width, this.bounds.height);
// this.hollowShape.graphics.endFill();
// }
let pixelPos = Vector2.add(this.entity.transform.position, this._localOffset);
this.pixelShape.graphics.clear();
this.pixelShape.graphics.beginFill(Colors.renderableCenter, 0);
this.pixelShape.graphics.lineStyle(4, Colors.renderableCenter);
this.pixelShape.graphics.lineTo(pixelPos.x, pixelPos.y);
this.pixelShape.graphics.moveTo(pixelPos.x, pixelPos.y);
this.pixelShape.graphics.endFill();
}
/**
* 如果renderableComponent的边界与camera.bounds相交 返回true
* 用于处理isVisible标志的状态开关
* 在渲染方法中使用这个方法来决定是否渲染
* @param camera
*/
public isVisibleFromCamera(camera: Camera): boolean {
if (!camera)
return false;
this.isVisible = camera.bounds.intersects(this.bounds);
return this.isVisible;
}
/**
* 较低的渲染层在前面,较高的在后面
* @param renderLayer
*/
public setRenderLayer(renderLayer: number): RenderableComponent {
if (renderLayer != this._renderLayer) {
let oldRenderLayer = this._renderLayer;
this._renderLayer = renderLayer;
// 如果该组件拥有一个实体那么是由ComponentList管理需要通知它改变了渲染层
if (this.entity && this.entity.scene)
this.entity.scene.renderableComponents.updateRenderableRenderLayer(this, oldRenderLayer, this._renderLayer);
}
return this;
}
/**
* 用于着色器处理精灵
* @param color
*/
public setColor(color: number): RenderableComponent {
this.color = color;
return this;
}
/**
* 从父实体的偏移量。用于向需要特定定位的实体
* @param offset
*/
public setLocalOffset(offset: Vector2): RenderableComponent {
if (this._localOffset != offset) {
this._localOffset = offset;
}
return this;
}
/**
* 进行状态同步
*/
public sync(camera: Camera) {
let afterPos = new Vector2(this.entity.position.x + this.localOffset.x - camera.position.x + camera.origin.x,
this.entity.position.y + this.localOffset.y - camera.position.y + camera.origin.y);
if (this.displayObject.x != afterPos.x) this.displayObject.x = afterPos.x;
if (this.displayObject.y != afterPos.y) this.displayObject.y = afterPos.y;
if (this.displayObject.scaleX != this.entity.scale.x) this.displayObject.scaleX = this.entity.scale.x;
if (this.displayObject.scaleY != this.entity.scale.y) this.displayObject.scaleY = this.entity.scale.y;
if (this.displayObject.rotation != this.entity.rotation) this.displayObject.rotation = this.entity.rotation;
}
public toString() {
return `[RenderableComponent] renderLayer: ${this.renderLayer}`;
}
/**
* 当renderableComponent进入相机框架时调用
* 如果渲染器不适用isVisibleFromCamera进行剔除检查 这些方法不会被调用
*/
protected onBecameVisible() {
this.displayObject.visible = this.isVisible;
this.debugDisplayObject.visible = this.isVisible;
}
/**
* 当renderableComponent离开相机框架时调用
* 如果渲染器不适用isVisibleFromCamera进行剔除检查 这些方法不会被调用
*/
protected onBecameInvisible() {
this.displayObject.visible = this.isVisible;
this.debugDisplayObject.visible = this.isVisible;
}
}
}