2020-06-08 16:23:48 +08:00
|
|
|
///<reference path="../Component.ts"/>
|
|
|
|
|
class Camera extends Component {
|
|
|
|
|
private _zoom;
|
|
|
|
|
private _origin: Vector2;
|
|
|
|
|
private _transformMatrix: Matrix2D = Matrix2D.identity;
|
|
|
|
|
private _inverseTransformMatrix = Matrix2D.identity;
|
2020-06-08 11:49:45 +08:00
|
|
|
|
2020-06-09 11:09:26 +08:00
|
|
|
private _minimumZoom = 0.3;
|
|
|
|
|
private _maximumZoom = 3;
|
|
|
|
|
private _areMatrixesDirty = true;
|
2020-06-10 17:41:53 +08:00
|
|
|
private _inset: CameraInset;
|
|
|
|
|
private _bounds: Rectangle;
|
|
|
|
|
private _areBoundsDirty = true;
|
|
|
|
|
|
|
|
|
|
public get bounds(){
|
|
|
|
|
if (this._areMatrixesDirty)
|
|
|
|
|
this.updateMatrixes();
|
|
|
|
|
|
|
|
|
|
if (this._areBoundsDirty){
|
|
|
|
|
let stage = this.entity.scene.stage;
|
|
|
|
|
let topLeft = this.screenToWorldPoint(new Vector2(this._inset.left, this._inset.top));
|
|
|
|
|
let bottomRight = this.screenToWorldPoint(new Vector2(stage.stageWidth - this._inset.right, stage.stageHeight - this._inset.bottom));
|
|
|
|
|
|
|
|
|
|
if (this.entity.transform.rotation != 0){
|
|
|
|
|
let topRight = this.screenToWorldPoint(new Vector2(stage.stageWidth - this._inset.right, this._inset.top));
|
|
|
|
|
let bottomLeft = this.screenToWorldPoint(new Vector2(this._inset.left, stage.stageHeight - this._inset.bottom));
|
|
|
|
|
|
|
|
|
|
let minX = MathHelper.minOf(topLeft.x, bottomRight.x, topRight.x, bottomLeft.x);
|
|
|
|
|
let maxX = MathHelper.maxOf(topLeft.x, bottomRight.x, topRight.x, bottomLeft.x);
|
|
|
|
|
let minY = MathHelper.minOf(topLeft.y, bottomRight.y, topRight.y, bottomLeft.y);
|
|
|
|
|
let maxY = MathHelper.maxOf(topLeft.y, bottomRight.y, topRight.y, bottomLeft.y);
|
|
|
|
|
|
|
|
|
|
this._bounds.location = new Vector2(minX, minY);
|
|
|
|
|
this._bounds.width = maxX - minX;
|
|
|
|
|
this._bounds.height = maxY - minY;
|
|
|
|
|
}else{
|
|
|
|
|
this._bounds.location = topLeft;
|
|
|
|
|
this._bounds.width = bottomRight.x - topLeft.x;
|
|
|
|
|
this._bounds.height = bottomRight.y - topLeft.y;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this._areBoundsDirty = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return this._bounds;
|
|
|
|
|
}
|
2020-06-09 11:09:26 +08:00
|
|
|
|
|
|
|
|
public get zoom(){
|
|
|
|
|
if (this._zoom == 0)
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
this._areMatrixesDirty = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-06-08 16:23:48 +08:00
|
|
|
public get transformMatrix(){
|
2020-06-10 17:41:53 +08:00
|
|
|
if (this._areBoundsDirty)
|
|
|
|
|
this.updateMatrixes();
|
2020-06-08 16:23:48 +08:00
|
|
|
return this._transformMatrix;
|
|
|
|
|
}
|
|
|
|
|
|
2020-06-10 17:41:53 +08:00
|
|
|
public get inverseTransformMatrix(){
|
|
|
|
|
if (this._areBoundsDirty)
|
|
|
|
|
this.updateMatrixes();
|
|
|
|
|
return this._inverseTransformMatrix;
|
|
|
|
|
}
|
|
|
|
|
|
2020-06-08 16:23:48 +08:00
|
|
|
constructor() {
|
|
|
|
|
super();
|
2020-06-09 11:09:26 +08:00
|
|
|
|
|
|
|
|
this.setZoom(0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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){
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this._areMatrixesDirty = true;
|
|
|
|
|
|
|
|
|
|
return this;
|
2020-06-08 16:23:48 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public initialize() {
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public update(){
|
2020-06-10 16:25:39 +08:00
|
|
|
|
2020-06-08 16:23:48 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public setPosition(position: Vector2){
|
|
|
|
|
this.entity.transform.setPosition(position);
|
|
|
|
|
|
|
|
|
|
return this;
|
2020-06-08 11:49:45 +08:00
|
|
|
}
|
|
|
|
|
|
2020-06-08 16:23:48 +08:00
|
|
|
public updateMatrixes(){
|
2020-06-09 11:09:26 +08:00
|
|
|
if (!this._areMatrixesDirty)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
let tempMat: Matrix2D;
|
2020-06-08 16:23:48 +08:00
|
|
|
this._transformMatrix = Matrix2D.createTranslation(-this.entity.transform.position.x, -this.entity.transform.position.y);
|
2020-06-09 11:09:26 +08:00
|
|
|
if (this._zoom != 1){
|
|
|
|
|
tempMat = Matrix2D.createScale(this._zoom, this._zoom);
|
|
|
|
|
this._transformMatrix = Matrix2D.multiply(this._transformMatrix, tempMat);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
tempMat = Matrix2D.createTranslation(this._origin.x, this._origin.y, tempMat);
|
|
|
|
|
this._transformMatrix = Matrix2D.multiply(this._transformMatrix, tempMat);
|
|
|
|
|
|
|
|
|
|
this._inverseTransformMatrix = Matrix2D.invert(this._transformMatrix);
|
|
|
|
|
|
2020-06-10 17:41:53 +08:00
|
|
|
this._areBoundsDirty = true;
|
2020-06-09 11:09:26 +08:00
|
|
|
this._areMatrixesDirty = false;
|
2020-06-08 16:23:48 +08:00
|
|
|
}
|
|
|
|
|
|
2020-06-10 17:41:53 +08:00
|
|
|
public screenToWorldPoint(screenPosition: Vector2){
|
|
|
|
|
this.updateMatrixes();
|
|
|
|
|
return Vector2.transform(screenPosition, this._inverseTransformMatrix);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public worldToScreenPoint(worldPosition: Vector2){
|
|
|
|
|
this.updateMatrixes();
|
|
|
|
|
return Vector2.transform(worldPosition, this._transformMatrix);
|
|
|
|
|
}
|
|
|
|
|
|
2020-06-08 16:23:48 +08:00
|
|
|
public destory() {
|
|
|
|
|
|
2020-06-08 11:49:45 +08:00
|
|
|
}
|
2020-06-10 17:41:53 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class CameraInset {
|
|
|
|
|
public left;
|
|
|
|
|
public right;
|
|
|
|
|
public top;
|
|
|
|
|
public bottom;
|
2020-06-08 11:49:45 +08:00
|
|
|
}
|