Something went wrong. Try again.
[READ-ONLY] Mirror of https://github.com/excaliburjs/Excalibur. 🎮 Your friendly TypeScript 2D game engine for the web 🗡️ excaliburjs.com
excalibur excaliburjs game-development game-engine game-framework gamedev games html5-canvas typescript
Something went wrong. Try again.
5.3 kB · 200 lines
TypeScript
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201import type { Vector } from '../../math/vector';import { CoordPlane } from '../../math/coord-plane';import { Transform } from '../../math/transform';import { Component } from '../component';import type { Entity } from '../entity';import { Observable } from '../../util/observable';import { Logger } from '../../util/log';
// =============================================================// Transform Component Serialization Data// ============================================================
export interface TransformComponentData { type: string; pos: { x: number; y: number }; rotation: number; scale: { x: number; y: number }; z: number; coordPlane?: CoordPlane;}
export class TransformComponent extends Component { // @ts-ignore private static _NAME = 'TransformComponent'; private _logger = Logger.getInstance(); private _parentComponent: TransformComponent | null = null; private _transform = new Transform(); public get() { return this._transform; }
private _addChildTransform = (child: Entity) => { const childTxComponent = child.get(TransformComponent); if (childTxComponent) { childTxComponent._transform.parent = this._transform; childTxComponent._parentComponent = this; } }; override onAdd(owner: Entity): void { for (const child of owner.children) { this._addChildTransform(child); } owner.childrenAdded$.subscribe((child) => this._addChildTransform(child)); owner.childrenRemoved$.subscribe((child) => { const childTxComponent = child.get(TransformComponent); if (childTxComponent) { childTxComponent._transform.parent = null; childTxComponent._parentComponent = null; } }); } override onRemove(_previousOwner: Entity): void { this._transform.parent = null; this._parentComponent = null; }
/** * Observable that emits when the z index changes on this component */ public zIndexChanged$ = new Observable<number>();
/** * The z-index ordering of the entity, a higher values are drawn on top of lower values. * For example z=99 would be drawn on top of z=0. */ public get z(): number { return this._transform.z; }
public set z(val: number) { const oldz = this._transform.z; this._transform.z = val; if (oldz !== val) { this.zIndexChanged$.notifyAll(val); } }
public get globalZ() { return this._transform.globalZ; }
public set globalZ(z: number) { this._transform.globalZ = z; }
private _coordPlane = CoordPlane.World; /** * The {@apilink CoordPlane | `coordinate plane`} for this transform for the entity. */ public get coordPlane() { if (this._parentComponent) { return this._parentComponent.coordPlane; } return this._coordPlane; }
public set coordPlane(value: CoordPlane) { if (!this._parentComponent) { this._coordPlane = value; } else { this._logger.warn( `Cannot set coordinate plane on child entity ${this.owner?.name}, children inherit their coordinate plane from their parents.` ); } }
get pos() { return this._transform.pos; } set pos(v: Vector) { this._transform.pos = v; }
get globalPos() { return this._transform.globalPos; } set globalPos(v: Vector) { this._transform.globalPos = v; }
get rotation() { return this._transform.rotation; } set rotation(rotation) { this._transform.rotation = rotation; }
get globalRotation() { return this._transform.globalRotation; } set globalRotation(rotation) { this._transform.globalRotation = rotation; }
get scale() { return this._transform.scale; } set scale(v: Vector) { this._transform.scale = v; }
get globalScale() { return this._transform.globalScale; } set globalScale(v: Vector) { this._transform.globalScale = v; }
applyInverse(v: Vector) { return this._transform.applyInverse(v); }
apply(v: Vector) { return this._transform.apply(v); }
override clone(): TransformComponent { const component = new TransformComponent(); component._transform = this._transform.clone(); return component; }
/** * Custom serialization - only store local transform values * Private fields (_transform, _parentComponent) are automatically excluded */ public override serialize(): TransformComponentData { const type = this.constructor.name; const data: TransformComponentData = { type, pos: { x: this.pos.x, y: this.pos.y }, rotation: this.rotation, scale: { x: this.scale.x, y: this.scale.y }, z: this.z };
// Only serialize coordPlane if not inherited from parent if (!this._parentComponent) { data.coordPlane = this._coordPlane; }
return data; }
/** * Restore state from serialized data */ public override deserialize(data: TransformComponentData): void { // Set local transform values this.pos = { x: data.pos.x, y: data.pos.y } as Vector; this.rotation = data.rotation; this.scale = { x: data.scale.x, y: data.scale.y } as Vector; this.z = data.z;
// Only set coordPlane if provided (root entities only) if (data.coordPlane !== undefined && !this._parentComponent) { this._coordPlane = data.coordPlane; } }}