实体跟随相机
This commit is contained in:
17
source/src/ECS/Component.ts
Normal file
17
source/src/ECS/Component.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
abstract class Component {
|
||||
public entity: Entity;
|
||||
public displayRender: egret.DisplayObject;
|
||||
|
||||
public abstract initialize();
|
||||
|
||||
public update(){
|
||||
|
||||
}
|
||||
|
||||
/** 绑定显示对象 */
|
||||
public bind(displayRender: egret.DisplayObject){
|
||||
this.displayRender = displayRender;
|
||||
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,46 @@
|
||||
class Camera {
|
||||
private _displayContent: egret.DisplayObject;
|
||||
///<reference path="../Component.ts"/>
|
||||
class Camera extends Component {
|
||||
private _zoom;
|
||||
private _origin: Vector2;
|
||||
private _transformMatrix: Matrix2D = Matrix2D.identity;
|
||||
private _inverseTransformMatrix = Matrix2D.identity;
|
||||
|
||||
constructor(displayObject: egret.DisplayObject){
|
||||
this._displayContent = displayObject;
|
||||
public get transformMatrix(){
|
||||
this.updateMatrixes();
|
||||
|
||||
return this._transformMatrix;
|
||||
}
|
||||
|
||||
public destory(){
|
||||
this._displayContent = null;
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
|
||||
public initialize() {
|
||||
|
||||
}
|
||||
|
||||
public update(){
|
||||
SceneManager.getActiveScene().entities.forEach(entity => entity.components.forEach(component => {
|
||||
if (component.displayRender){
|
||||
let has = this.entity.scene.$children.indexOf(component.displayRender)
|
||||
if (has == -1){
|
||||
this.entity.scene.stage.addChild(component.displayRender);
|
||||
}
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
public setPosition(position: Vector2){
|
||||
this.entity.transform.setPosition(position);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public updateMatrixes(){
|
||||
this._transformMatrix = Matrix2D.createTranslation(-this.entity.transform.position.x, -this.entity.transform.position.y);
|
||||
}
|
||||
|
||||
public destory() {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -4,10 +4,33 @@ class Entity {
|
||||
public scene: Scene;
|
||||
/** 封装实体的位置/旋转/缩放,并允许设置一个高层结构 */
|
||||
public readonly transform: Transform;
|
||||
/** 当前附加到此实体的所有组件的列表 */
|
||||
public readonly components: Component[];
|
||||
private _updateOrder: number = 0;
|
||||
|
||||
constructor(name: string){
|
||||
this.name = name;
|
||||
this.transform = new Transform(this);
|
||||
this.components = [];
|
||||
}
|
||||
|
||||
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;
|
||||
if (this.scene){
|
||||
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
public attachToScene(newScene: Scene){
|
||||
@@ -19,6 +42,17 @@ class Entity {
|
||||
}
|
||||
}
|
||||
|
||||
public addComponent<T extends Component>(component: T): T{
|
||||
component.entity = this;
|
||||
this.components.push(component);
|
||||
component.initialize();
|
||||
return component;
|
||||
}
|
||||
|
||||
public update(){
|
||||
this.components.forEach(component => component.update());
|
||||
}
|
||||
|
||||
public destory(){
|
||||
this.scene.entities.remove(this);
|
||||
this.transform.parent = null;
|
||||
|
||||
@@ -3,17 +3,24 @@ class Scene extends egret.DisplayObjectContainer {
|
||||
public camera: Camera;
|
||||
public entities: Entity[] = [];
|
||||
|
||||
private _projectionMatrix: Matrix2D;
|
||||
private _transformMatrix: Matrix2D;
|
||||
private _matrixTransformMatrix: Matrix2D;
|
||||
|
||||
constructor(displayObject: egret.DisplayObject){
|
||||
super();
|
||||
displayObject.stage.addChild(this);
|
||||
/** 初始化默认相机 */
|
||||
this.camera = new Camera(displayObject);
|
||||
this.camera = this.createEntity("camera").addComponent(new Camera());
|
||||
this._projectionMatrix = new Matrix2D(0, 0, 0, 0, 0, 0);
|
||||
this.addEventListener(egret.Event.ACTIVATE, this.onActive, this);
|
||||
this.addEventListener(egret.Event.DEACTIVATE, this.onDeactive, this);
|
||||
this.addEventListener(egret.Event.ENTER_FRAME, this.update, this);
|
||||
}
|
||||
|
||||
public createEntity(name: string){
|
||||
let entity = new Entity(name);
|
||||
|
||||
entity.transform.position = new Vector2(0, 0);
|
||||
return this.addEntity(entity);
|
||||
}
|
||||
|
||||
@@ -45,6 +52,18 @@ class Scene extends egret.DisplayObjectContainer {
|
||||
|
||||
}
|
||||
|
||||
public update(){
|
||||
this.entities.forEach(entity => entity.update());
|
||||
}
|
||||
|
||||
public prepRenderState(){
|
||||
this._projectionMatrix.m11 = 2 / this.stage.width;
|
||||
this._projectionMatrix.m22 = -2 / this.stage.height;
|
||||
|
||||
this._transformMatrix = this.camera.transformMatrix;
|
||||
this._matrixTransformMatrix = Matrix2D.multiply(this._transformMatrix, this._projectionMatrix);
|
||||
}
|
||||
|
||||
public destory(){
|
||||
this.removeEventListener(egret.Event.DEACTIVATE, this.onDeactive, this);
|
||||
this.removeEventListener(egret.Event.ACTIVATE, this.onActive, this);
|
||||
|
||||
@@ -33,4 +33,8 @@ class SceneManager {
|
||||
this._activeScene.initialize();
|
||||
return scene;
|
||||
}
|
||||
|
||||
public static getActiveScene(){
|
||||
return this._activeScene;
|
||||
}
|
||||
}
|
||||
@@ -4,12 +4,31 @@ class Transform {
|
||||
private _children: Transform[];
|
||||
private _parent: Transform;
|
||||
|
||||
private _localPosition: Vector2;
|
||||
private _localRotation: number = 0;
|
||||
private _localScale: Vector2;
|
||||
|
||||
private _translationMatrix: Matrix2D;
|
||||
private _rotationMatrix: Matrix2D;
|
||||
private _scaleMatrix: Matrix2D;
|
||||
|
||||
private _worldTransform = Matrix2D.identity;
|
||||
private _worldToLocalTransform = Matrix2D.identity;
|
||||
private _worldInverseTransform = Matrix2D.identity;
|
||||
|
||||
private _rotation: number = 0;
|
||||
private _position: Vector2;
|
||||
private _scale: Vector2;
|
||||
|
||||
private _localTransform;
|
||||
|
||||
public get childCount(){
|
||||
return this._children.length;
|
||||
}
|
||||
|
||||
constructor(entity: Entity){
|
||||
this.entity = entity;
|
||||
this._scale = this._localScale = Vector2.One;
|
||||
this._children = [];
|
||||
}
|
||||
|
||||
@@ -39,4 +58,83 @@ class Transform {
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public get position(){
|
||||
this.updateTransform();
|
||||
if (!this.parent){
|
||||
this._position = this._localPosition;
|
||||
}else{
|
||||
this.parent.updateTransform();
|
||||
this._position = Vector2.transform(this._localPosition, this.parent._worldTransform);
|
||||
}
|
||||
|
||||
return this._position;
|
||||
}
|
||||
|
||||
public set position(value: Vector2){
|
||||
this.setPosition(value);
|
||||
}
|
||||
|
||||
public get localPosition(){
|
||||
this.updateTransform();
|
||||
return this._localPosition;
|
||||
}
|
||||
|
||||
public set localPosition(value: Vector2){
|
||||
this.setLocalPosition(value);
|
||||
}
|
||||
|
||||
public setLocalPosition(localPosition: Vector2){
|
||||
if (localPosition == this._localPosition)
|
||||
return this;
|
||||
|
||||
this._localPosition = localPosition;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public setPosition(position: Vector2){
|
||||
if (position == this._position)
|
||||
return this;
|
||||
|
||||
this._position = position;
|
||||
if (this.parent){
|
||||
this.localPosition = Vector2.transform(this._position, this._worldToLocalTransform);
|
||||
}else{
|
||||
this.localPosition = position;
|
||||
}
|
||||
|
||||
for (let i = 0; i < this.entity.components.length; i ++){
|
||||
let component = this.entity.components[i];
|
||||
if (component.displayRender){
|
||||
component.displayRender.x = this.entity.scene.camera.transformMatrix.m31 + this.position.x;
|
||||
component.displayRender.y = this.entity.scene.camera.transformMatrix.m32 + this.position.y;
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public updateTransform(){
|
||||
if (this.parent)
|
||||
this.parent.updateTransform();
|
||||
|
||||
this._translationMatrix = Matrix2D.createTranslation(this._localPosition.x, this._localPosition.y);
|
||||
this._rotationMatrix = Matrix2D.createRotation(this._localRotation);
|
||||
this._scaleMatrix = Matrix2D.createScale(this._localScale.x, this._localScale.y);
|
||||
|
||||
this._localTransform = Matrix2D.multiply(this._scaleMatrix, this._rotationMatrix);
|
||||
this._localTransform = Matrix2D.multiply(this._localTransform, this._translationMatrix);
|
||||
|
||||
if (!this.parent){
|
||||
this._worldTransform = this._localTransform;
|
||||
this._rotation = this._localRotation;
|
||||
this._scale = this._localScale;
|
||||
}else{
|
||||
this._worldTransform = Matrix2D.multiply(this._localTransform, this.parent._worldTransform);
|
||||
|
||||
this._rotation = this._localRotation + this.parent._rotation;
|
||||
this._scale = Vector2.multiply( this.parent._scale, this._localScale);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,7 @@ class MathHelper {
|
||||
* 将弧度转换成角度。
|
||||
* @param radians 用弧度表示的角
|
||||
*/
|
||||
public static ToDegrees(radians: number){
|
||||
public static toDegrees(radians: number){
|
||||
return radians * 57.295779513082320876798154814105;
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ class MathHelper {
|
||||
* 将角度转换为弧度
|
||||
* @param degrees
|
||||
*/
|
||||
public static ToRadians(degrees: number){
|
||||
public static toRadians(degrees: number){
|
||||
return degrees * 0.017453292519943295769236907684886;
|
||||
}
|
||||
}
|
||||
@@ -2,14 +2,14 @@
|
||||
* 表示右手3 * 3的浮点矩阵,可以存储平移、缩放和旋转信息。
|
||||
*/
|
||||
class Matrix2D {
|
||||
public m11: number;
|
||||
public m12: number;
|
||||
public m11: number = 0;
|
||||
public m12: number = 0;
|
||||
|
||||
public m21: number;
|
||||
public m22: number;
|
||||
public m21: number = 0;
|
||||
public m22: number = 0;
|
||||
|
||||
public m31: number;
|
||||
public m32: number;
|
||||
public m31: number = 0;
|
||||
public m32: number = 0;
|
||||
|
||||
private static _identity: Matrix2D = new Matrix2D(1, 0, 0, 1, 0, 0);
|
||||
|
||||
@@ -60,11 +60,11 @@ class Matrix2D {
|
||||
* 以度为单位的旋转存储在这个矩阵中
|
||||
*/
|
||||
public get rotationDegrees(){
|
||||
return MathHelper.ToDegrees(this.rotation);
|
||||
return MathHelper.toDegrees(this.rotation);
|
||||
}
|
||||
|
||||
public set rotationDegrees(value: number){
|
||||
this.rotation = MathHelper.ToRadians(value);
|
||||
this.rotation = MathHelper.toRadians(value);
|
||||
}
|
||||
|
||||
public get scale(){
|
||||
@@ -127,4 +127,68 @@ class Matrix2D {
|
||||
matrix1.m32 = m32;
|
||||
return matrix1;
|
||||
}
|
||||
|
||||
public static multiplyTranslation(matrix: Matrix2D, x: number, y: number){
|
||||
let trans = Matrix2D.createTranslation(x, y);
|
||||
return Matrix2D.multiply(matrix, trans);
|
||||
}
|
||||
|
||||
public determinant(){
|
||||
return this.m11 * this.m22 - this.m12 * this.m21;
|
||||
}
|
||||
|
||||
public static invert(matrix: Matrix2D, result: Matrix2D){
|
||||
let det = 1 / matrix.determinant();
|
||||
|
||||
result.m11 = matrix.m22 * det;
|
||||
result.m12 = -matrix.m12 * det;
|
||||
|
||||
result.m21 = -matrix.m21 * det;
|
||||
result.m22 = matrix.m11 * det;
|
||||
|
||||
result.m31 = (matrix.m32 * matrix.m21 - matrix.m31 * matrix.m22) * det;
|
||||
result.m32 = -(matrix.m32 * matrix.m11 - matrix.m31 * matrix.m12) * det;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static createTranslation(xPosition: number, yPosition: number, result: Matrix2D = Matrix2D.identity){
|
||||
result.m11 = 1;
|
||||
result.m12 = 0;
|
||||
|
||||
result.m21 = 0;
|
||||
result.m22 = 1;
|
||||
|
||||
result.m31 = xPosition;
|
||||
result.m32 = yPosition;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static createRotation(radians: number, result?: Matrix2D){
|
||||
result = Matrix2D.identity;
|
||||
|
||||
let val1 = Math.cos(radians);
|
||||
let val2 = Math.sin(radians);
|
||||
|
||||
result.m11 = val1;
|
||||
result.m12 = val2;
|
||||
result.m21 = -val2;
|
||||
result.m22 = val1;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static createScale(xScale: number, yScale: number, result: Matrix2D = Matrix2D.identity){
|
||||
result.m11 = xScale;
|
||||
result.m12 = 0;
|
||||
|
||||
result.m21 = 0;
|
||||
result.m22 = yScale;
|
||||
|
||||
result.m31 = 0;
|
||||
result.m32 = 0;
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,13 @@
|
||||
/** 2d 向量 */
|
||||
class Vector2 {
|
||||
public x: number;
|
||||
public y: number;
|
||||
public x: number = 0;
|
||||
public y: number = 0;
|
||||
|
||||
private static readonly unitVector2 = new Vector2(1, 1);
|
||||
|
||||
public static get One(){
|
||||
return this.unitVector2;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从两个值构造一个带有X和Y的二维向量。
|
||||
@@ -43,4 +49,8 @@ class Vector2 {
|
||||
this.x *= val;
|
||||
this.y *= val;
|
||||
}
|
||||
|
||||
public static transform(position: Vector2, matrix: Matrix2D){
|
||||
return new Vector2((position.x * matrix.m11) + (position.y * matrix.m21), (position.x * matrix.m12) + (position.y * matrix.m22));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user