实体跟随相机

This commit is contained in:
yhh
2020-06-08 16:23:48 +08:00
parent f20c460fc6
commit cadd9ab0fc
18 changed files with 925 additions and 54 deletions

View 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;
}
}

View File

@@ -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() {
}
}

View File

@@ -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;

View File

@@ -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);

View File

@@ -33,4 +33,8 @@ class SceneManager {
this._activeScene.initialize();
return scene;
}
public static getActiveScene(){
return this._activeScene;
}
}

View File

@@ -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);
}
}
}