toaimin-indie-engine 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +55 -0
- package/cli/bin.cjs +99 -0
- package/dist/audio/AudioBus.d.ts +30 -0
- package/dist/audio/AudioBus.d.ts.map +1 -0
- package/dist/audio/AudioMock.d.ts +112 -0
- package/dist/audio/AudioMock.d.ts.map +1 -0
- package/dist/audio/ProceduralAudio.d.ts +48 -0
- package/dist/audio/ProceduralAudio.d.ts.map +1 -0
- package/dist/audio/SoundManager.d.ts +73 -0
- package/dist/audio/SoundManager.d.ts.map +1 -0
- package/dist/audio/VoicePool.d.ts +26 -0
- package/dist/audio/VoicePool.d.ts.map +1 -0
- package/dist/audio/index.d.ts +7 -0
- package/dist/audio/index.d.ts.map +1 -0
- package/dist/audio/types.d.ts +87 -0
- package/dist/audio/types.d.ts.map +1 -0
- package/dist/core/EventEmitter.d.ts +64 -0
- package/dist/core/EventEmitter.d.ts.map +1 -0
- package/dist/core/Game.d.ts +248 -0
- package/dist/core/Game.d.ts.map +1 -0
- package/dist/core/GameLoop.d.ts +128 -0
- package/dist/core/GameLoop.d.ts.map +1 -0
- package/dist/core/Time.d.ts +73 -0
- package/dist/core/Time.d.ts.map +1 -0
- package/dist/core/index.d.ts +5 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/entity/Component.d.ts +31 -0
- package/dist/entity/Component.d.ts.map +1 -0
- package/dist/entity/Entity.d.ts +61 -0
- package/dist/entity/Entity.d.ts.map +1 -0
- package/dist/entity/EntityManager.d.ts +46 -0
- package/dist/entity/EntityManager.d.ts.map +1 -0
- package/dist/entity/components/ColliderComponent.d.ts +47 -0
- package/dist/entity/components/ColliderComponent.d.ts.map +1 -0
- package/dist/entity/components/RigidBodyComponent.d.ts +38 -0
- package/dist/entity/components/RigidBodyComponent.d.ts.map +1 -0
- package/dist/entity/components/ScriptComponent.d.ts +32 -0
- package/dist/entity/components/ScriptComponent.d.ts.map +1 -0
- package/dist/entity/components/ShapeComponent.d.ts +50 -0
- package/dist/entity/components/ShapeComponent.d.ts.map +1 -0
- package/dist/entity/components/SpriteComponent.d.ts +31 -0
- package/dist/entity/components/SpriteComponent.d.ts.map +1 -0
- package/dist/entity/components/index.d.ts +6 -0
- package/dist/entity/components/index.d.ts.map +1 -0
- package/dist/entity/index.d.ts +5 -0
- package/dist/entity/index.d.ts.map +1 -0
- package/dist/index.cjs +4 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +6326 -0
- package/dist/index.js.map +1 -0
- package/dist/input/ActionMap.d.ts +91 -0
- package/dist/input/ActionMap.d.ts.map +1 -0
- package/dist/input/InputManager.d.ts +102 -0
- package/dist/input/InputManager.d.ts.map +1 -0
- package/dist/input/Pointer.d.ts +115 -0
- package/dist/input/Pointer.d.ts.map +1 -0
- package/dist/input/VirtualJoystick.d.ts +79 -0
- package/dist/input/VirtualJoystick.d.ts.map +1 -0
- package/dist/input/index.d.ts +5 -0
- package/dist/input/index.d.ts.map +1 -0
- package/dist/math/Circle.d.ts +39 -0
- package/dist/math/Circle.d.ts.map +1 -0
- package/dist/math/Color.d.ts +58 -0
- package/dist/math/Color.d.ts.map +1 -0
- package/dist/math/MathUtils.d.ts +82 -0
- package/dist/math/MathUtils.d.ts.map +1 -0
- package/dist/math/Matrix2D.d.ts +97 -0
- package/dist/math/Matrix2D.d.ts.map +1 -0
- package/dist/math/Rect.d.ts +54 -0
- package/dist/math/Rect.d.ts.map +1 -0
- package/dist/math/Transform2D.d.ts +47 -0
- package/dist/math/Transform2D.d.ts.map +1 -0
- package/dist/math/Vector2.d.ts +89 -0
- package/dist/math/Vector2.d.ts.map +1 -0
- package/dist/math/index.d.ts +8 -0
- package/dist/math/index.d.ts.map +1 -0
- package/dist/physics/BoxCollider2D.d.ts +38 -0
- package/dist/physics/BoxCollider2D.d.ts.map +1 -0
- package/dist/physics/CircleCollider2D.d.ts +27 -0
- package/dist/physics/CircleCollider2D.d.ts.map +1 -0
- package/dist/physics/Collider2D.d.ts +79 -0
- package/dist/physics/Collider2D.d.ts.map +1 -0
- package/dist/physics/CollisionFSM.d.ts +84 -0
- package/dist/physics/CollisionFSM.d.ts.map +1 -0
- package/dist/physics/ContactSolver.d.ts +58 -0
- package/dist/physics/ContactSolver.d.ts.map +1 -0
- package/dist/physics/Narrowphase.d.ts +25 -0
- package/dist/physics/Narrowphase.d.ts.map +1 -0
- package/dist/physics/PhysicsWorld2D.d.ts +75 -0
- package/dist/physics/PhysicsWorld2D.d.ts.map +1 -0
- package/dist/physics/Raycast.d.ts +38 -0
- package/dist/physics/Raycast.d.ts.map +1 -0
- package/dist/physics/RigidBody2D.d.ts +118 -0
- package/dist/physics/RigidBody2D.d.ts.map +1 -0
- package/dist/physics/SpatialGrid.d.ts +78 -0
- package/dist/physics/SpatialGrid.d.ts.map +1 -0
- package/dist/physics/index.d.ts +14 -0
- package/dist/physics/index.d.ts.map +1 -0
- package/dist/rendering/Animation.d.ts +62 -0
- package/dist/rendering/Animation.d.ts.map +1 -0
- package/dist/rendering/AssetLoader.d.ts +35 -0
- package/dist/rendering/AssetLoader.d.ts.map +1 -0
- package/dist/rendering/Camera2D.d.ts +109 -0
- package/dist/rendering/Camera2D.d.ts.map +1 -0
- package/dist/rendering/CanvasContext.d.ts +80 -0
- package/dist/rendering/CanvasContext.d.ts.map +1 -0
- package/dist/rendering/CanvasMock.d.ts +163 -0
- package/dist/rendering/CanvasMock.d.ts.map +1 -0
- package/dist/rendering/ParticleSystem.d.ts +103 -0
- package/dist/rendering/ParticleSystem.d.ts.map +1 -0
- package/dist/rendering/Renderer.d.ts +98 -0
- package/dist/rendering/Renderer.d.ts.map +1 -0
- package/dist/rendering/Shapes.d.ts +24 -0
- package/dist/rendering/Shapes.d.ts.map +1 -0
- package/dist/rendering/Sprite.d.ts +74 -0
- package/dist/rendering/Sprite.d.ts.map +1 -0
- package/dist/rendering/SpriteSheet.d.ts +22 -0
- package/dist/rendering/SpriteSheet.d.ts.map +1 -0
- package/dist/rendering/index.d.ts +11 -0
- package/dist/rendering/index.d.ts.map +1 -0
- package/dist/scene/Blackboard.d.ts +81 -0
- package/dist/scene/Blackboard.d.ts.map +1 -0
- package/dist/scene/Scene.d.ts +160 -0
- package/dist/scene/Scene.d.ts.map +1 -0
- package/dist/scene/SceneManager.d.ts +142 -0
- package/dist/scene/SceneManager.d.ts.map +1 -0
- package/dist/scene/SceneTransition.d.ts +118 -0
- package/dist/scene/SceneTransition.d.ts.map +1 -0
- package/dist/scene/index.d.ts +5 -0
- package/dist/scene/index.d.ts.map +1 -0
- package/dist/ui/UIAnchor.d.ts +31 -0
- package/dist/ui/UIAnchor.d.ts.map +1 -0
- package/dist/ui/UIButton.d.ts +48 -0
- package/dist/ui/UIButton.d.ts.map +1 -0
- package/dist/ui/UIElement.d.ts +108 -0
- package/dist/ui/UIElement.d.ts.map +1 -0
- package/dist/ui/UILabel.d.ts +54 -0
- package/dist/ui/UILabel.d.ts.map +1 -0
- package/dist/ui/UIManager.d.ts +41 -0
- package/dist/ui/UIManager.d.ts.map +1 -0
- package/dist/ui/UIPanel.d.ts +36 -0
- package/dist/ui/UIPanel.d.ts.map +1 -0
- package/dist/ui/UIProgressBar.d.ts +47 -0
- package/dist/ui/UIProgressBar.d.ts.map +1 -0
- package/dist/ui/index.d.ts +8 -0
- package/dist/ui/index.d.ts.map +1 -0
- package/package.json +47 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../src/math/Vector2.ts","../src/math/Matrix2D.ts","../src/math/Transform2D.ts","../src/math/Rect.ts","../src/math/Circle.ts","../src/math/MathUtils.ts","../src/math/Color.ts","../src/core/EventEmitter.ts","../src/core/Time.ts","../src/core/GameLoop.ts","../src/rendering/CanvasContext.ts","../src/rendering/CanvasMock.ts","../src/rendering/Renderer.ts","../src/rendering/Camera2D.ts","../src/input/Pointer.ts","../src/input/VirtualJoystick.ts","../src/input/ActionMap.ts","../src/input/InputManager.ts","../src/physics/RigidBody2D.ts","../src/physics/ContactSolver.ts","../src/physics/SpatialGrid.ts","../src/physics/CollisionFSM.ts","../src/physics/Collider2D.ts","../src/physics/Raycast.ts","../src/physics/CircleCollider2D.ts","../src/physics/BoxCollider2D.ts","../src/physics/Narrowphase.ts","../src/physics/PhysicsWorld2D.ts","../src/audio/AudioBus.ts","../src/audio/VoicePool.ts","../src/audio/ProceduralAudio.ts","../src/audio/SoundManager.ts","../src/scene/Blackboard.ts","../src/scene/Scene.ts","../src/scene/SceneManager.ts","../src/ui/UIElement.ts","../src/ui/UILabel.ts","../src/ui/UIPanel.ts","../src/ui/UIAnchor.ts","../src/ui/UIButton.ts","../src/ui/UIManager.ts","../src/entity/Entity.ts","../src/entity/Component.ts","../src/entity/components/ColliderComponent.ts","../src/entity/components/RigidBodyComponent.ts","../src/entity/EntityManager.ts","../src/core/Game.ts","../src/rendering/Sprite.ts","../src/rendering/Animation.ts","../src/rendering/SpriteSheet.ts","../src/rendering/ParticleSystem.ts","../src/rendering/Shapes.ts","../src/rendering/AssetLoader.ts","../src/scene/SceneTransition.ts","../src/ui/UIProgressBar.ts","../src/audio/AudioMock.ts","../src/entity/components/SpriteComponent.ts","../src/entity/components/ShapeComponent.ts","../src/entity/components/ScriptComponent.ts","../src/index.ts"],"sourcesContent":["/**\n * Production-grade 2D Vector with zero-allocation in-place mutation,\n * immutable ergonomics, zero-division guards, and static scratchpads.\n */\nexport class Vector2 {\n public x: number;\n public y: number;\n\n // Static scratchpad instances for zero-allocation intermediate calculations\n public static readonly temp1: Vector2 = new Vector2(0, 0);\n public static readonly temp2: Vector2 = new Vector2(0, 0);\n\n constructor(x: number = 0, y: number = 0) {\n this.x = x;\n this.y = y;\n }\n\n // ==========================================\n // In-Place Mutation Methods (Zero Allocation)\n // ==========================================\n\n public set(x: number, y: number): this {\n this.x = x;\n this.y = y;\n return this;\n }\n\n public setScalar(scalar: number): this {\n this.x = scalar;\n this.y = scalar;\n return this;\n }\n\n public copy(other: Vector2): this {\n this.x = other.x;\n this.y = other.y;\n return this;\n }\n\n public addInPlace(v: Vector2): this {\n this.x += v.x;\n this.y += v.y;\n return this;\n }\n\n public addVectors(a: Vector2, b: Vector2): this {\n this.x = a.x + b.x;\n this.y = a.y + b.y;\n return this;\n }\n\n public subInPlace(v: Vector2): this {\n this.x -= v.x;\n this.y -= v.y;\n return this;\n }\n\n public subVectors(a: Vector2, b: Vector2): this {\n this.x = a.x - b.x;\n this.y = a.y - b.y;\n return this;\n }\n\n public scaleInPlace(scalar: number): this {\n this.x *= scalar;\n this.y *= scalar;\n return this;\n }\n\n public multiplyInPlace(v: Vector2): this {\n this.x *= v.x;\n this.y *= v.y;\n return this;\n }\n\n public divideInPlace(v: Vector2): this {\n this.x = v.x !== 0 ? this.x / v.x : 0;\n this.y = v.y !== 0 ? this.y / v.y : 0;\n return this;\n }\n\n public divideScalarInPlace(scalar: number): this {\n if (scalar !== 0) {\n const inv = 1 / scalar;\n this.x *= inv;\n this.y *= inv;\n } else {\n this.x = 0;\n this.y = 0;\n }\n return this;\n }\n\n public negateInPlace(): this {\n this.x = this.x === 0 ? 0 : -this.x;\n this.y = this.y === 0 ? 0 : -this.y;\n return this;\n }\n\n /**\n * Normalizes vector to unit length in-place.\n * Guarded against zero/near-zero division: sets to (0,0) if length is negligible.\n */\n public normalizeInPlace(): this {\n const lenSq = this.x * this.x + this.y * this.y;\n if (lenSq > 1e-12) {\n const invLen = 1 / Math.sqrt(lenSq);\n this.x *= invLen;\n this.y *= invLen;\n } else {\n this.x = 0;\n this.y = 0;\n }\n return this;\n }\n\n public clampLengthInPlace(min: number, max: number): this {\n const len = this.length();\n if (len === 0) return this;\n const clamped = Math.max(min, Math.min(max, len));\n const factor = clamped / len;\n this.x *= factor;\n this.y *= factor;\n return this;\n }\n\n public rotateInPlace(radians: number): this {\n const cos = Math.cos(radians);\n const sin = Math.sin(radians);\n const rx = this.x * cos - this.y * sin;\n const ry = this.x * sin + this.y * cos;\n this.x = rx === 0 ? 0 : rx;\n this.y = ry === 0 ? 0 : ry;\n return this;\n }\n\n public rotateAroundInPlace(center: Vector2, radians: number): this {\n const cos = Math.cos(radians);\n const sin = Math.sin(radians);\n const dx = this.x - center.x;\n const dy = this.y - center.y;\n this.x = center.x + (dx * cos - dy * sin);\n this.y = center.y + (dx * sin + dy * cos);\n return this;\n }\n\n public lerpInPlace(target: Vector2, t: number): this {\n this.x += (target.x - this.x) * t;\n this.y += (target.y - this.y) * t;\n return this;\n }\n\n /**\n * Reflects this vector across a given normal vector in-place.\n * Formula: v' = v - 2 * (v . n) * n\n * Guarded: safely handles zero-length normal vectors without producing NaN.\n */\n public reflectInPlace(normal: Vector2): this {\n const nLenSq = normal.lengthSq();\n if (nLenSq >= 1e-12) {\n const dot = this.dot(normal);\n const factor = (2 * dot) / nLenSq;\n this.x -= factor * normal.x;\n this.y -= factor * normal.y;\n }\n return this;\n }\n\n public projectInPlace(onto: Vector2): this {\n const ontoLenSq = onto.lengthSq();\n if (ontoLenSq >= 1e-12) {\n const scale = this.dot(onto) / ontoLenSq;\n this.x = onto.x * scale;\n this.y = onto.y * scale;\n } else {\n this.x = 0;\n this.y = 0;\n }\n return this;\n }\n\n public perpendicularInPlace(clockwise: boolean = true): this {\n const temp = this.x;\n if (clockwise) {\n this.x = this.y === 0 ? 0 : -this.y;\n this.y = temp === 0 ? 0 : temp;\n } else {\n this.x = this.y === 0 ? 0 : this.y;\n this.y = temp === 0 ? 0 : -temp;\n }\n return this;\n }\n\n // ==========================================\n // Immutable Ergonomic Operations\n // ==========================================\n\n public clone(): Vector2 {\n return new Vector2(this.x, this.y);\n }\n\n public add(v: Vector2): Vector2 {\n return new Vector2(this.x + v.x, this.y + v.y);\n }\n\n public sub(v: Vector2): Vector2 {\n return new Vector2(this.x - v.x, this.y - v.y);\n }\n\n public scale(s: number): Vector2 {\n return new Vector2(this.x * s, this.y * s);\n }\n\n public multiply(v: Vector2): Vector2 {\n return new Vector2(this.x * v.x, this.y * v.y);\n }\n\n public divide(scalarOrVec: number | Vector2): Vector2 {\n if (typeof scalarOrVec === 'number') {\n return this.clone().divideScalarInPlace(scalarOrVec);\n }\n return this.clone().divideInPlace(scalarOrVec);\n }\n\n public negate(): Vector2 {\n return new Vector2(-this.x, -this.y);\n }\n\n public normalized(): Vector2 {\n return this.clone().normalizeInPlace();\n }\n\n public rotate(radians: number): Vector2 {\n return this.clone().rotateInPlace(radians);\n }\n\n public lerp(target: Vector2, t: number): Vector2 {\n return new Vector2(\n this.x + (target.x - this.x) * t,\n this.y + (target.y - this.y) * t\n );\n }\n\n public reflect(normal: Vector2): Vector2 {\n return this.clone().reflectInPlace(normal);\n }\n\n public project(onto: Vector2): Vector2 {\n return this.clone().projectInPlace(onto);\n }\n\n public perpendicular(clockwise: boolean = true): Vector2 {\n return this.clone().perpendicularInPlace(clockwise);\n }\n\n // ==========================================\n // Scalar Queries & Algebraic Operations\n // ==========================================\n\n public dot(v: Vector2): number {\n return this.x * v.x + this.y * v.y;\n }\n\n /**\n * 2D scalar cross product: a.x * b.y - a.y * b.x\n * Returns signed area of parallelogram; positive if rotation from this to v is counter-clockwise.\n */\n public cross(v: Vector2): number {\n return this.x * v.y - this.y * v.x;\n }\n\n public lengthSq(): number {\n return this.x * this.x + this.y * this.y;\n }\n\n public length(): number {\n return Math.sqrt(this.lengthSq());\n }\n\n public distanceTo(v: Vector2): number {\n const dx = this.x - v.x;\n const dy = this.y - v.y;\n return Math.sqrt(dx * dx + dy * dy);\n }\n\n public distanceToSq(v: Vector2): number {\n const dx = this.x - v.x;\n const dy = this.y - v.y;\n return dx * dx + dy * dy;\n }\n\n /** Angle in radians relative to positive X-axis in [-PI, PI] */\n public angle(): number {\n return Math.atan2(this.y, this.x);\n }\n\n /** Signed angle in radians between this vector and other */\n public angleTo(other: Vector2): number {\n return Math.atan2(this.cross(other), this.dot(other));\n }\n\n public equals(other: Vector2, epsilon: number = 1e-6): boolean {\n return (\n Math.abs(this.x - other.x) <= epsilon &&\n Math.abs(this.y - other.y) <= epsilon\n );\n }\n\n public isZero(epsilon: number = 1e-6): boolean {\n return Math.abs(this.x) <= epsilon && Math.abs(this.y) <= epsilon;\n }\n\n public toString(): string {\n return `Vector2(${this.x.toFixed(3)}, ${this.y.toFixed(3)})`;\n }\n\n public toJSON(): { x: number; y: number } {\n return { x: this.x, y: this.y };\n }\n\n // ==========================================\n // Static Factory Helpers\n // ==========================================\n\n public static zero(): Vector2 {\n return new Vector2(0, 0);\n }\n\n public static one(): Vector2 {\n return new Vector2(1, 1);\n }\n\n /** Up vector in 2D screen coordinates (points up: y = -1) */\n public static up(): Vector2 {\n return new Vector2(0, -1);\n }\n\n /** Down vector in 2D screen coordinates (points down: y = 1) */\n public static down(): Vector2 {\n return new Vector2(0, 1);\n }\n\n public static left(): Vector2 {\n return new Vector2(-1, 0);\n }\n\n public static right(): Vector2 {\n return new Vector2(1, 0);\n }\n\n public static fromAngle(radians: number, length: number = 1): Vector2 {\n return new Vector2(Math.cos(radians) * length, Math.sin(radians) * length);\n }\n\n public static distance(a: Vector2, b: Vector2): number {\n return a.distanceTo(b);\n }\n\n public static distanceSq(a: Vector2, b: Vector2): number {\n return a.distanceToSq(b);\n }\n\n public static dot(a: Vector2, b: Vector2): number {\n return a.dot(b);\n }\n\n public static cross(a: Vector2, b: Vector2): number {\n return a.cross(b);\n }\n\n public static lerp(a: Vector2, b: Vector2, t: number, out?: Vector2): Vector2 {\n const dest = out ?? new Vector2();\n dest.x = a.x + (b.x - a.x) * t;\n dest.y = a.y + (b.y - a.y) * t;\n return dest;\n }\n}\n","import { Vector2 } from './Vector2';\n\n/**\n * 2D 3x3 Affine Transformation Matrix\n * Matches HTML5 Canvas 2D matrix layout:\n * [ a c tx ]\n * [ b d ty ]\n * [ 0 0 1 ]\n *\n * a: scale X / cos\n * b: skew Y / sin\n * c: skew X / -sin\n * d: scale Y / cos\n * tx: translation X\n * ty: translation Y\n */\nexport class Matrix2D {\n public a: number;\n public b: number;\n public c: number;\n public d: number;\n public tx: number;\n public ty: number;\n\n constructor(\n a: number = 1,\n b: number = 0,\n c: number = 0,\n d: number = 1,\n tx: number = 0,\n ty: number = 0\n ) {\n this.a = a;\n this.b = b;\n this.c = c;\n this.d = d;\n this.tx = tx;\n this.ty = ty;\n }\n\n public set(\n a: number,\n b: number,\n c: number,\n d: number,\n tx: number,\n ty: number\n ): this {\n this.a = a;\n this.b = b;\n this.c = c;\n this.d = d;\n this.tx = tx;\n this.ty = ty;\n return this;\n }\n\n public identity(): this {\n return this.set(1, 0, 0, 1, 0, 0);\n }\n\n public copy(other: Matrix2D): this {\n return this.set(other.a, other.b, other.c, other.d, other.tx, other.ty);\n }\n\n public clone(): Matrix2D {\n return new Matrix2D(this.a, this.b, this.c, this.d, this.tx, this.ty);\n }\n\n /**\n * Determinant: a * d - b * c\n */\n public determinant(): number {\n return this.a * this.d - this.b * this.c;\n }\n\n /**\n * Inverts the matrix in-place.\n * Guarded against singular / degenerate matrices (|det| < 1e-10).\n * In degenerate cases, resets to identity safely without NaN.\n */\n public invert(): this {\n const det = this.determinant();\n if (Math.abs(det) < 1e-10) {\n // Degenerate matrix: prevent NaN poisoning\n this.identity();\n return this;\n }\n\n const invDet = 1.0 / det;\n const a = this.a;\n const b = this.b;\n const c = this.c;\n const d = this.d;\n const tx = this.tx;\n const ty = this.ty;\n\n this.a = d * invDet;\n this.b = -b * invDet;\n this.c = -c * invDet;\n this.d = a * invDet;\n this.tx = (c * ty - d * tx) * invDet;\n this.ty = (b * tx - a * ty) * invDet;\n\n return this;\n }\n\n public getInverse(out?: Matrix2D): Matrix2D {\n const dest = out ?? new Matrix2D();\n return dest.copy(this).invert();\n }\n\n /**\n * Multiplies this matrix by another (this * other).\n * Returns a new Matrix2D instance.\n */\n public multiply(other: Matrix2D): Matrix2D {\n return this.clone().multiplyInPlace(other);\n }\n\n /**\n * Multiplies this matrix by other in-place: this = this * other.\n * Alias: append()\n */\n public multiplyInPlace(other: Matrix2D): this {\n const a1 = this.a, b1 = this.b, c1 = this.c, d1 = this.d, tx1 = this.tx, ty1 = this.ty;\n const a2 = other.a, b2 = other.b, c2 = other.c, d2 = other.d, tx2 = other.tx, ty2 = other.ty;\n\n this.a = a1 * a2 + c1 * b2;\n this.b = b1 * a2 + d1 * b2;\n this.c = a1 * c2 + c1 * d2;\n this.d = b1 * c2 + d1 * d2;\n this.tx = a1 * tx2 + c1 * ty2 + tx1;\n this.ty = b1 * tx2 + d1 * ty2 + ty1;\n\n return this;\n }\n\n public append(other: Matrix2D): this {\n return this.multiplyInPlace(other);\n }\n\n /**\n * Pre-multiplies this matrix by other in-place: this = other * this.\n */\n public prepend(other: Matrix2D): this {\n const a1 = other.a, b1 = other.b, c1 = other.c, d1 = other.d, tx1 = other.tx, ty1 = other.ty;\n const a2 = this.a, b2 = this.b, c2 = this.c, d2 = this.d, tx2 = this.tx, ty2 = this.ty;\n\n this.a = a1 * a2 + c1 * b2;\n this.b = b1 * a2 + d1 * b2;\n this.c = a1 * c2 + c1 * d2;\n this.d = b1 * c2 + d1 * d2;\n this.tx = a1 * tx2 + c1 * ty2 + tx1;\n this.ty = b1 * tx2 + d1 * ty2 + ty1;\n\n return this;\n }\n\n public translate(x: number, y: number): this {\n this.tx += this.a * x + this.c * y;\n this.ty += this.b * x + this.d * y;\n return this;\n }\n\n public rotate(radians: number): this {\n const cos = Math.cos(radians);\n const sin = Math.sin(radians);\n const a = this.a;\n const b = this.b;\n const c = this.c;\n const d = this.d;\n\n this.a = a * cos + c * sin;\n this.b = b * cos + d * sin;\n this.c = -a * sin + c * cos;\n this.d = -b * sin + d * cos;\n\n return this;\n }\n\n public scale(sx: number, sy: number = sx): this {\n this.a *= sx;\n this.b *= sx;\n this.c *= sy;\n this.d *= sy;\n return this;\n }\n\n /**\n * Directly sets this matrix from Translation, Rotation, Scale, and Pivot in a single step with zero allocations.\n * Point order: Translate(-pivot) -> Scale -> Rotate -> Translate(position)\n */\n public fromTransform(\n x: number,\n y: number,\n rotation: number,\n scaleX: number,\n scaleY: number,\n pivotX: number = 0,\n pivotY: number = 0\n ): this {\n const cos = Math.cos(rotation);\n const sin = Math.sin(rotation);\n\n const a = cos * scaleX;\n const b = sin * scaleX;\n const c = -sin * scaleY;\n const d = cos * scaleY;\n\n this.a = a;\n this.b = b;\n this.c = c;\n this.d = d;\n this.tx = x - (a * pivotX + c * pivotY);\n this.ty = y - (b * pivotX + d * pivotY);\n\n return this;\n }\n\n /**\n * Transforms a 2D point vector by this affine matrix:\n * x' = a * x + c * y + tx\n * y' = b * x + d * y + ty\n */\n public transformPoint(point: Vector2, out?: Vector2): Vector2 {\n const dest = out ?? new Vector2();\n const x = point.x;\n const y = point.y;\n dest.x = this.a * x + this.c * y + this.tx;\n dest.y = this.b * x + this.d * y + this.ty;\n return dest;\n }\n\n /**\n * Transforms a 2D direction vector (ignores translation components tx, ty):\n * x' = a * x + c * y\n * y' = b * x + d * y\n */\n public transformDirection(direction: Vector2, out?: Vector2): Vector2 {\n const dest = out ?? new Vector2();\n const x = direction.x;\n const y = direction.y;\n dest.x = this.a * x + this.c * y;\n dest.y = this.b * x + this.d * y;\n return dest;\n }\n\n /**\n * Decomposes matrix into position, rotation (radians), and scale.\n */\n public decompose(out?: {\n position: Vector2;\n rotation: number;\n scale: Vector2;\n }): { position: Vector2; rotation: number; scale: Vector2 } {\n const dest = out ?? {\n position: new Vector2(),\n rotation: 0,\n scale: new Vector2()\n };\n dest.position.set(this.tx, this.ty);\n dest.scale.set(\n Math.sqrt(this.a * this.a + this.b * this.b),\n Math.sqrt(this.c * this.c + this.d * this.d)\n );\n dest.rotation = Math.atan2(this.b, this.a);\n return dest;\n }\n\n /**\n * Directly sets this matrix to a 2D Canvas context.\n */\n public applyToContext(ctx: CanvasRenderingContext2D): void {\n ctx.setTransform(this.a, this.b, this.c, this.d, this.tx, this.ty);\n }\n\n /**\n * Multiplies this matrix onto the current Canvas context matrix.\n */\n public transformContext(ctx: CanvasRenderingContext2D): void {\n ctx.transform(this.a, this.b, this.c, this.d, this.tx, this.ty);\n }\n\n public equals(other: Matrix2D, epsilon: number = 1e-6): boolean {\n return (\n Math.abs(this.a - other.a) <= epsilon &&\n Math.abs(this.b - other.b) <= epsilon &&\n Math.abs(this.c - other.c) <= epsilon &&\n Math.abs(this.d - other.d) <= epsilon &&\n Math.abs(this.tx - other.tx) <= epsilon &&\n Math.abs(this.ty - other.ty) <= epsilon\n );\n }\n\n public static identity(): Matrix2D {\n return new Matrix2D(1, 0, 0, 1, 0, 0);\n }\n}\n","import { Vector2 } from './Vector2';\nimport { Matrix2D } from './Matrix2D';\n\n/**\n * Hierarchical 2D Transform component for Scene Graph entities,\n * with local TRS, pivot, lazy matrix caching, and parent-child propagation.\n */\nexport class Transform2D {\n public readonly position: Vector2;\n public rotation: number; // in radians\n public readonly scale: Vector2;\n public readonly pivot: Vector2;\n\n public parent: Transform2D | null = null;\n public readonly children: Transform2D[] = [];\n\n public readonly localMatrix: Matrix2D = new Matrix2D();\n public readonly worldMatrix: Matrix2D = new Matrix2D();\n\n private _isDirty: boolean = true;\n private _isWorldDirty: boolean = true;\n\n constructor(\n x: number = 0,\n y: number = 0,\n rotation: number = 0,\n scaleX: number = 1,\n scaleY: number = 1,\n pivotX: number = 0,\n pivotY: number = 0\n ) {\n this.position = new Vector2(x, y);\n this.rotation = rotation;\n this.scale = new Vector2(scaleX, scaleY);\n this.pivot = new Vector2(pivotX, pivotY);\n }\n\n // ==========================================\n // Dirty Flag & Hierarchy Invalidation\n // ==========================================\n\n /**\n * Marks this transform and all its descendants as needing world matrix recalculation.\n */\n public markDirty(): this {\n this._isDirty = true;\n this.markWorldDirty();\n return this;\n }\n\n public markWorldDirty(): void {\n if (!this._isWorldDirty) {\n this._isWorldDirty = true;\n for (let i = 0; i < this.children.length; i++) {\n this.children[i].markWorldDirty();\n }\n }\n }\n\n public get isDirty(): boolean {\n return this._isDirty || this._isWorldDirty;\n }\n\n // ==========================================\n // Matrix Evaluation\n // ==========================================\n\n /**\n * Updates local transformation matrix if dirty.\n */\n public updateLocalMatrix(): Matrix2D {\n if (this._isDirty) {\n this.localMatrix.fromTransform(\n this.position.x,\n this.position.y,\n this.rotation,\n this.scale.x,\n this.scale.y,\n this.pivot.x,\n this.pivot.y\n );\n this._isDirty = false;\n }\n return this.localMatrix;\n }\n\n /**\n * Updates and returns the world transformation matrix.\n * Lazily computes parent hierarchy when dirty.\n */\n public updateWorldMatrix(force: boolean = false): Matrix2D {\n if (this._isDirty || force) {\n this.updateLocalMatrix();\n }\n\n if (this._isWorldDirty || force) {\n if (this.parent !== null) {\n this.parent.updateWorldMatrix(force);\n this.worldMatrix.copy(this.parent.worldMatrix).multiplyInPlace(this.localMatrix);\n } else {\n this.worldMatrix.copy(this.localMatrix);\n }\n this._isWorldDirty = false;\n }\n\n return this.worldMatrix;\n }\n\n // ==========================================\n // Hierarchy Management\n // ==========================================\n\n public addChild(child: Transform2D): this {\n if (child === this || child.parent === this) return this;\n\n // Prevent circular hierarchy by checking if child is an ancestor of this\n let ancestor: Transform2D | null = this.parent;\n while (ancestor !== null) {\n if (ancestor === child) return this;\n ancestor = ancestor.parent;\n }\n\n if (child.parent !== null) {\n child.parent.removeChild(child);\n }\n\n child.parent = this;\n this.children.push(child);\n child.markWorldDirty();\n return this;\n }\n\n public removeChild(child: Transform2D): this {\n const index = this.children.indexOf(child);\n if (index !== -1) {\n this.children.splice(index, 1);\n child.parent = null;\n child.markWorldDirty();\n }\n return this;\n }\n\n public setParent(parent: Transform2D | null): this {\n if (parent === this || this.parent === parent) return this;\n\n if (parent === null) {\n if (this.parent !== null) {\n this.parent.removeChild(this);\n }\n return this;\n }\n\n parent.addChild(this);\n return this;\n }\n\n // ==========================================\n // Coordinate Space Transformations\n // ==========================================\n\n public localToWorld(localPoint: Vector2, out?: Vector2): Vector2 {\n this.updateWorldMatrix();\n return this.worldMatrix.transformPoint(localPoint, out);\n }\n\n public worldToLocal(worldPoint: Vector2, out?: Vector2): Vector2 {\n this.updateWorldMatrix();\n const inv = this.worldMatrix.clone().invert();\n return inv.transformPoint(worldPoint, out);\n }\n\n public getWorldPosition(out?: Vector2): Vector2 {\n this.updateWorldMatrix();\n const dest = out ?? new Vector2();\n dest.x = this.worldMatrix.tx;\n dest.y = this.worldMatrix.ty;\n return dest;\n }\n\n public getWorldRotation(): number {\n this.updateWorldMatrix();\n return Math.atan2(this.worldMatrix.b, this.worldMatrix.a);\n }\n\n public getWorldScale(out?: Vector2): Vector2 {\n this.updateWorldMatrix();\n const dest = out ?? new Vector2();\n dest.x = Math.sqrt(this.worldMatrix.a * this.worldMatrix.a + this.worldMatrix.b * this.worldMatrix.b);\n dest.y = Math.sqrt(this.worldMatrix.c * this.worldMatrix.c + this.worldMatrix.d * this.worldMatrix.d);\n return dest;\n }\n\n // ==========================================\n // Fluent Setters (Auto-marking Dirty)\n // ==========================================\n\n public setPosition(x: number, y: number): this {\n this.position.set(x, y);\n return this.markDirty();\n }\n\n public setRotation(radians: number): this {\n this.rotation = radians;\n return this.markDirty();\n }\n\n public setScale(x: number, y: number = x): this {\n this.scale.set(x, y);\n return this.markDirty();\n }\n\n public setPivot(x: number, y: number): this {\n this.pivot.set(x, y);\n return this.markDirty();\n }\n}\n","import { Vector2 } from './Vector2';\n\n/**\n * Axis-Aligned Bounding Box (AABB) 2D Rectangle.\n * Coordinates follow 2D screen convention (x, y at top-left).\n */\nexport class Rect {\n public x: number;\n public y: number;\n public width: number;\n public height: number;\n\n constructor(x: number = 0, y: number = 0, width: number = 0, height: number = 0) {\n this.x = x;\n this.y = y;\n this.width = width;\n this.height = height;\n }\n\n public set(x: number, y: number, width: number, height: number): this {\n this.x = x;\n this.y = y;\n this.width = width;\n this.height = height;\n return this;\n }\n\n public copy(other: Rect): this {\n return this.set(other.x, other.y, other.width, other.height);\n }\n\n public clone(): Rect {\n return new Rect(this.x, this.y, this.width, this.height);\n }\n\n // ==========================================\n // Boundary Getters & Setters\n // ==========================================\n\n public get left(): number {\n return this.x;\n }\n\n public set left(val: number) {\n this.width += this.x - val;\n this.x = val;\n }\n\n public get right(): number {\n return this.x + this.width;\n }\n\n public set right(val: number) {\n this.width = val - this.x;\n }\n\n public get top(): number {\n return this.y;\n }\n\n public set top(val: number) {\n this.height += this.y - val;\n this.y = val;\n }\n\n public get bottom(): number {\n return this.y + this.height;\n }\n\n public set bottom(val: number) {\n this.height = val - this.y;\n }\n\n public get centerX(): number {\n return this.x + this.width * 0.5;\n }\n\n public get centerY(): number {\n return this.y + this.height * 0.5;\n }\n\n public get center(): Vector2 {\n return new Vector2(this.centerX, this.centerY);\n }\n\n public get size(): Vector2 {\n return new Vector2(this.width, this.height);\n }\n\n // ==========================================\n // Intersection & Containment Tests\n // ==========================================\n\n /**\n * Tests whether point (x, y) lies inside this rectangle.\n */\n public contains(x: number, y: number): boolean {\n return (\n x >= this.x &&\n x <= this.x + this.width &&\n y >= this.y &&\n y <= this.y + this.height\n );\n }\n\n public containsPoint(point: Vector2): boolean {\n return this.contains(point.x, point.y);\n }\n\n /**\n * Tests whether another rectangle is entirely enclosed within this rectangle.\n */\n public containsRect(other: Rect): boolean {\n return (\n other.x >= this.x &&\n other.right <= this.right &&\n other.y >= this.y &&\n other.bottom <= this.bottom\n );\n }\n\n /**\n * Tests whether this rectangle intersects with another rectangle (AABB overlap).\n */\n public intersects(other: Rect): boolean {\n return (\n this.x <= other.right &&\n this.right >= other.x &&\n this.y <= other.bottom &&\n this.bottom >= other.y\n );\n }\n\n /**\n * Computes the overlapping intersection rectangle. Returns null if no intersection.\n */\n public intersection(other: Rect, out?: Rect): Rect | null {\n if (!this.intersects(other)) return null;\n\n const x1 = Math.max(this.x, other.x);\n const y1 = Math.max(this.y, other.y);\n const x2 = Math.min(this.right, other.right);\n const y2 = Math.min(this.bottom, other.bottom);\n\n const dest = out ?? new Rect();\n return dest.set(x1, y1, x2 - x1, y2 - y1);\n }\n\n /**\n * Computes bounding rectangle enclosing both this and other.\n */\n public union(other: Rect, out?: Rect): Rect {\n const x1 = Math.min(this.x, other.x);\n const y1 = Math.min(this.y, other.y);\n const x2 = Math.max(this.right, other.right);\n const y2 = Math.max(this.bottom, other.bottom);\n\n const dest = out ?? new Rect();\n return dest.set(x1, y1, x2 - x1, y2 - y1);\n }\n\n public inflate(dx: number, dy: number = dx): this {\n this.x -= dx;\n this.y -= dy;\n this.width += dx * 2;\n this.height += dy * 2;\n return this;\n }\n\n public offset(dx: number, dy: number): this {\n this.x += dx;\n this.y += dy;\n return this;\n }\n\n // ==========================================\n // Static Factory Helpers\n // ==========================================\n\n public static fromPoints(p1: Vector2, p2: Vector2): Rect {\n const minX = Math.min(p1.x, p2.x);\n const minY = Math.min(p1.y, p2.y);\n const maxX = Math.max(p1.x, p2.x);\n const maxY = Math.max(p1.y, p2.y);\n return new Rect(minX, minY, maxX - minX, maxY - minY);\n }\n\n public static fromCenter(\n centerX: number,\n centerY: number,\n width: number,\n height: number\n ): Rect {\n return new Rect(centerX - width * 0.5, centerY - height * 0.5, width, height);\n }\n\n public static fromMinMax(\n minX: number,\n minY: number,\n maxX: number,\n maxY: number\n ): Rect {\n return new Rect(minX, minY, maxX - minX, maxY - minY);\n }\n}\n","import { Vector2 } from './Vector2';\nimport { Rect } from './Rect';\n\n/**\n * 2D Circle Primitive for collision testing and spatial queries.\n */\nexport class Circle {\n public x: number;\n public y: number;\n public radius: number;\n\n constructor(x: number = 0, y: number = 0, radius: number = 0) {\n this.x = x;\n this.y = y;\n this.radius = radius;\n }\n\n public set(x: number, y: number, radius: number): this {\n this.x = x;\n this.y = y;\n this.radius = radius;\n return this;\n }\n\n public copy(other: Circle): this {\n return this.set(other.x, other.y, other.radius);\n }\n\n public clone(): Circle {\n return new Circle(this.x, this.y, this.radius);\n }\n\n public get center(): Vector2 {\n return new Vector2(this.x, this.y);\n }\n\n public set center(v: Vector2) {\n this.x = v.x;\n this.y = v.y;\n }\n\n public get diameter(): number {\n return this.radius * 2;\n }\n\n public get area(): number {\n return Math.PI * this.radius * this.radius;\n }\n\n public get circumference(): number {\n return 2 * Math.PI * this.radius;\n }\n\n /**\n * Tests whether point (x, y) is inside the circle.\n */\n public contains(x: number, y: number): boolean {\n const dx = x - this.x;\n const dy = y - this.y;\n return dx * dx + dy * dy <= this.radius * this.radius;\n }\n\n public containsPoint(point: Vector2): boolean {\n return this.contains(point.x, point.y);\n }\n\n /**\n * Tests whether this circle intersects with another circle.\n */\n public intersects(other: Circle): boolean {\n const dx = other.x - this.x;\n const dy = other.y - this.y;\n const distSq = dx * dx + dy * dy;\n const rSum = this.radius + other.radius;\n return distSq <= rSum * rSum;\n }\n\n /**\n * Tests whether this circle intersects with an AABB Rect.\n * Clamps circle center to rect boundary to find closest point.\n */\n public intersectsRect(rect: Rect): boolean {\n const cx = Math.max(rect.left, Math.min(this.x, rect.right));\n const cy = Math.max(rect.top, Math.min(this.y, rect.bottom));\n const dx = this.x - cx;\n const dy = this.y - cy;\n return dx * dx + dy * dy <= this.radius * this.radius;\n }\n\n /**\n * Returns tight AABB bounding box enclosing this circle.\n */\n public getBoundingBox(out?: Rect): Rect {\n const dest = out ?? new Rect();\n return dest.set(\n this.x - this.radius,\n this.y - this.radius,\n this.radius * 2,\n this.radius * 2\n );\n }\n\n public offset(dx: number, dy: number): this {\n this.x += dx;\n this.y += dy;\n return this;\n }\n}\n","/**\n * Collection of performance-optimized mathematical helper functions,\n * frame-rate independent dampening, angle wrapping, and interpolation.\n */\nexport class MathUtils {\n public static readonly EPSILON: number = 1e-6;\n public static readonly DEG_TO_RAD: number = Math.PI / 180;\n public static readonly RAD_TO_DEG: number = 180 / Math.PI;\n public static readonly TWO_PI: number = Math.PI * 2;\n public static readonly HALF_PI: number = Math.PI / 2;\n\n /**\n * Clamps a value between a minimum and maximum threshold.\n */\n public static clamp(value: number, min: number, max: number): number {\n return Math.max(min, Math.min(max, value));\n }\n\n /**\n * Clamps a value between 0.0 and 1.0.\n */\n public static clamp01(value: number): number {\n return Math.max(0, Math.min(1, value));\n }\n\n /**\n * Standard linear interpolation between a and b by factor t.\n */\n public static lerp(a: number, b: number, t: number): number {\n return a + (b - a) * t;\n }\n\n /**\n * Inverse linear interpolation: computes t for value in [a, b].\n */\n public static inverseLerp(a: number, b: number, value: number): number {\n if (Math.abs(b - a) < MathUtils.EPSILON) return 0;\n return MathUtils.clamp01((value - a) / (b - a));\n }\n\n /**\n * Analytic frame-rate independent smoothing (exponential decay).\n * Guarantees identical smoothing speed regardless of whether game runs at 60 FPS or 144 FPS.\n *\n * @param a Current value\n * @param b Target value\n * @param lambda Smoothing speed (higher = faster, typically 5 to 25)\n * @param dt Delta time in seconds\n */\n public static damp(a: number, b: number, lambda: number, dt: number): number {\n return MathUtils.lerp(a, b, 1 - Math.exp(-lambda * dt));\n }\n\n /**\n * Converts degrees to radians.\n */\n public static degToRad(deg: number): number {\n return deg * MathUtils.DEG_TO_RAD;\n }\n\n /**\n * Converts radians to degrees.\n */\n public static radToDeg(rad: number): number {\n return rad * MathUtils.RAD_TO_DEG;\n }\n\n /**\n * Generates a random float in [min, max).\n */\n public static randomRange(min: number, max: number): number {\n return min + Math.random() * (max - min);\n }\n\n /**\n * Generates a random integer in [min, max] (inclusive).\n */\n public static randomInt(min: number, max: number): number {\n const lo = Math.ceil(min);\n const hi = Math.floor(max);\n return Math.floor(lo + Math.random() * (hi - lo + 1));\n }\n\n /**\n * Picks a random element from an array.\n */\n public static randomChoice<T>(items: readonly T[]): T {\n return items[Math.floor(Math.random() * items.length)];\n }\n\n /**\n * Tests whether two floating-point numbers are approximately equal within epsilon.\n */\n public static approximately(\n a: number,\n b: number,\n epsilon: number = MathUtils.EPSILON\n ): boolean {\n return Math.abs(a - b) <= epsilon;\n }\n\n /**\n * Wraps value into the half-open interval [min, max).\n * Useful for screen wrapping coordinates in toroidal 2D worlds (e.g. Asteroids).\n */\n public static wrap(value: number, min: number, max: number): number {\n const range = max - min;\n if (range === 0) return min;\n return min + ((((value - min) % range) + range) % range);\n }\n\n /**\n * Normalizes an angle in radians into [-PI, PI).\n */\n public static normalizeAngle(radians: number): number {\n return MathUtils.wrap(radians, -Math.PI, Math.PI);\n }\n\n /**\n * Computes the shortest signed angular difference from angle 'from' to angle 'to' in radians.\n * Useful for smooth turret or camera rotation towards a target.\n */\n public static angleDifference(from: number, to: number): number {\n const diff = (to - from) % MathUtils.TWO_PI;\n return ((diff + Math.PI * 3) % MathUtils.TWO_PI) - Math.PI;\n }\n\n /**\n * Smooth Hermite interpolation between edges.\n * Guards against degenerate intervals (|max - min| < EPSILON) returning 1 or 0 instead of NaN.\n */\n public static smoothstep(min: number, max: number, value: number): number {\n if (Math.abs(max - min) < MathUtils.EPSILON) {\n return value >= max ? 1 : 0;\n }\n const x = MathUtils.clamp01((value - min) / (max - min));\n return x * x * (3 - 2 * x);\n }\n\n public static sign(value: number): number {\n return value > 0 ? 1 : value < 0 ? -1 : 0;\n }\n}\n","import { MathUtils } from './MathUtils';\n\n/**\n * Production-ready RGBA Color class with parsing for Hex, RGB, RGBA, and HSL,\n * Canvas2D string generation, and color interpolation.\n */\nexport class Color {\n public r: number; // 0 to 255\n public g: number; // 0 to 255\n public b: number; // 0 to 255\n public a: number; // 0.0 to 1.0\n\n constructor(\n r: number = 255,\n g: number = 255,\n b: number = 255,\n a: number = 1.0\n ) {\n this.r = Math.round(MathUtils.clamp(r, 0, 255));\n this.g = Math.round(MathUtils.clamp(g, 0, 255));\n this.b = Math.round(MathUtils.clamp(b, 0, 255));\n this.a = MathUtils.clamp01(a);\n }\n\n public set(r: number, g: number, b: number, a: number = 1.0): this {\n this.r = Math.round(MathUtils.clamp(r, 0, 255));\n this.g = Math.round(MathUtils.clamp(g, 0, 255));\n this.b = Math.round(MathUtils.clamp(b, 0, 255));\n this.a = MathUtils.clamp01(a);\n return this;\n }\n\n public copy(other: Color): this {\n return this.set(other.r, other.g, other.b, other.a);\n }\n\n public clone(): Color {\n return new Color(this.r, this.g, this.b, this.a);\n }\n\n // ==========================================\n // Normalized Component Getters [0.0, 1.0]\n // ==========================================\n\n public get rNorm(): number {\n return this.r / 255;\n }\n\n public get gNorm(): number {\n return this.g / 255;\n }\n\n public get bNorm(): number {\n return this.b / 255;\n }\n\n public setAlpha(a: number): this {\n this.a = MathUtils.clamp01(a);\n return this;\n }\n\n // ==========================================\n // Parsing Methods\n // ==========================================\n\n /**\n * Parses hex string in formats:\n * #RGB, #RGBA, #RRGGBB, #RRGGBBAA, 0xRGB, 0xRRGGBB, etc.\n */\n public static fromHex(hex: string): Color {\n let clean = hex.trim().replace(/^(#|0x)/i, '');\n\n if (clean.length === 3) {\n // RGB -> RRGGBB\n clean = clean[0] + clean[0] + clean[1] + clean[1] + clean[2] + clean[2];\n } else if (clean.length === 4) {\n // RGBA -> RRGGBBAA\n clean = clean[0] + clean[0] + clean[1] + clean[1] + clean[2] + clean[2] + clean[3] + clean[3];\n }\n\n if (clean.length === 6) {\n const num = parseInt(clean, 16);\n return new Color((num >> 16) & 255, (num >> 8) & 255, num & 255, 1.0);\n } else if (clean.length === 8) {\n const num = parseInt(clean, 16);\n const r = (num >> 24) & 255;\n const g = (num >> 16) & 255;\n const b = (num >> 8) & 255;\n const a = (num & 255) / 255;\n return new Color(r, g, b, a);\n }\n\n return new Color(255, 255, 255, 1.0);\n }\n\n public static fromRGB(r: number, g: number, b: number, a: number = 1.0): Color {\n return new Color(r, g, b, a);\n }\n\n /**\n * Converts HSL (h in [0, 360], s in [0, 1] or [0, 100], l in [0, 1] or [0, 100]) to Color.\n */\n public static fromHSL(\n h: number,\n s: number,\n l: number,\n a: number = 1.0\n ): Color {\n const hue = MathUtils.wrap(h, 0, 360);\n const sat = s > 1 ? s / 100 : s;\n const light = l > 1 ? l / 100 : l;\n\n const c = (1 - Math.abs(2 * light - 1)) * sat;\n const x = c * (1 - Math.abs(((hue / 60) % 2) - 1));\n const m = light - c / 2;\n\n let rPrime = 0, gPrime = 0, bPrime = 0;\n\n if (hue < 60) {\n rPrime = c; gPrime = x; bPrime = 0;\n } else if (hue < 120) {\n rPrime = x; gPrime = c; bPrime = 0;\n } else if (hue < 180) {\n rPrime = 0; gPrime = c; bPrime = x;\n } else if (hue < 240) {\n rPrime = 0; gPrime = x; bPrime = c;\n } else if (hue < 300) {\n rPrime = x; gPrime = 0; bPrime = c;\n } else {\n rPrime = c; gPrime = 0; bPrime = x;\n }\n\n return new Color(\n (rPrime + m) * 255,\n (gPrime + m) * 255,\n (bPrime + m) * 255,\n a\n );\n }\n\n /**\n * Universal parser for CSS strings: #hex, rgb(...), rgba(...), hsl(...), hsla(...), or named colors.\n */\n public static parse(colorStr: string): Color {\n const str = colorStr.trim().toLowerCase();\n\n if (str.startsWith('#') || str.startsWith('0x')) {\n return Color.fromHex(str);\n }\n\n if (str.startsWith('rgb')) {\n const match = str.match(/rgba?\\s*\\(\\s*([\\d.]+)\\s*,\\s*([\\d.]+)\\s*,\\s*([\\d.]+)(?:\\s*,\\s*([\\d.]+))?\\s*\\)/);\n if (match) {\n return new Color(\n parseFloat(match[1]),\n parseFloat(match[2]),\n parseFloat(match[3]),\n match[4] !== undefined ? parseFloat(match[4]) : 1.0\n );\n }\n }\n\n if (str.startsWith('hsl')) {\n const match = str.match(/hsla?\\s*\\(\\s*([\\d.]+)\\s*,\\s*([\\d.]+)%?\\s*,\\s*([\\d.]+)%?(?:\\s*,\\s*([\\d.]+))?\\s*\\)/);\n if (match) {\n return Color.fromHSL(\n parseFloat(match[1]),\n parseFloat(match[2]),\n parseFloat(match[3]),\n match[4] !== undefined ? parseFloat(match[4]) : 1.0\n );\n }\n }\n\n // Named colors fallback\n const namedColors: Record<string, Color> = {\n white: Color.WHITE,\n black: Color.BLACK,\n red: Color.RED,\n green: Color.GREEN,\n blue: Color.BLUE,\n yellow: Color.YELLOW,\n cyan: Color.CYAN,\n magenta: Color.MAGENTA,\n gray: Color.GRAY,\n orange: Color.ORANGE,\n purple: Color.PURPLE,\n transparent: Color.TRANSPARENT\n };\n\n if (namedColors[str]) {\n return namedColors[str].clone();\n }\n\n return Color.WHITE.clone();\n }\n\n // ==========================================\n // Formatting Outputs\n // ==========================================\n\n public toRgbaString(): string {\n return `rgba(${this.r}, ${this.g}, ${this.b}, ${this.a})`;\n }\n\n public toRgbString(): string {\n return `rgb(${this.r}, ${this.g}, ${this.b})`;\n }\n\n public toHexString(includeAlpha: boolean = false): string {\n const rHex = this.r.toString(16).padStart(2, '0');\n const gHex = this.g.toString(16).padStart(2, '0');\n const bHex = this.b.toString(16).padStart(2, '0');\n\n if (includeAlpha) {\n const aHex = Math.round(this.a * 255).toString(16).padStart(2, '0');\n return `#${rHex}${gHex}${bHex}${aHex}`;\n }\n\n return `#${rHex}${gHex}${bHex}`;\n }\n\n public toHsl(): { h: number; s: number; l: number; a: number } {\n const r = this.rNorm;\n const g = this.gNorm;\n const b = this.bNorm;\n\n const max = Math.max(r, g, b);\n const min = Math.min(r, g, b);\n const delta = max - min;\n\n let h = 0;\n const l = (max + min) / 2;\n let s = 0;\n\n if (delta !== 0) {\n s = l > 0.5 ? delta / (2 - max - min) : delta / (max + min);\n if (max === r) {\n h = ((g - b) / delta + (g < b ? 6 : 0)) * 60;\n } else if (max === g) {\n h = ((b - r) / delta + 2) * 60;\n } else {\n h = ((r - g) / delta + 4) * 60;\n }\n }\n\n return { h: Math.round(h), s: Math.round(s * 100), l: Math.round(l * 100), a: this.a };\n }\n\n public toHslString(): string {\n const hsl = this.toHsl();\n return `hsla(${hsl.h}, ${hsl.s}%, ${hsl.l}%, ${hsl.a})`;\n }\n\n // ==========================================\n // Color Operations\n // ==========================================\n\n public lerp(other: Color, t: number): Color {\n return new Color(\n MathUtils.lerp(this.r, other.r, t),\n MathUtils.lerp(this.g, other.g, t),\n MathUtils.lerp(this.b, other.b, t),\n MathUtils.lerp(this.a, other.a, t)\n );\n }\n\n public lerpInPlace(other: Color, t: number): this {\n this.r = Math.round(MathUtils.lerp(this.r, other.r, t));\n this.g = Math.round(MathUtils.lerp(this.g, other.g, t));\n this.b = Math.round(MathUtils.lerp(this.b, other.b, t));\n this.a = MathUtils.lerp(this.a, other.a, t);\n return this;\n }\n\n public equals(other: Color, epsilon: number = 1e-4): boolean {\n return (\n Math.abs(this.r - other.r) <= 1 &&\n Math.abs(this.g - other.g) <= 1 &&\n Math.abs(this.b - other.b) <= 1 &&\n Math.abs(this.a - other.a) <= epsilon\n );\n }\n\n // ==========================================\n // Standard Color Palette Presets\n // ==========================================\n\n public static readonly WHITE = new Color(255, 255, 255, 1.0);\n public static readonly BLACK = new Color(0, 0, 0, 1.0);\n public static readonly TRANSPARENT = new Color(0, 0, 0, 0.0);\n public static readonly RED = new Color(239, 68, 68, 1.0);\n public static readonly GREEN = new Color(34, 197, 94, 1.0);\n public static readonly BLUE = new Color(59, 130, 246, 1.0);\n public static readonly YELLOW = new Color(234, 179, 8, 1.0);\n public static readonly CYAN = new Color(6, 182, 212, 1.0);\n public static readonly MAGENTA = new Color(217, 70, 239, 1.0);\n public static readonly GRAY = new Color(107, 114, 128, 1.0);\n public static readonly ORANGE = new Color(249, 115, 22, 1.0);\n public static readonly PURPLE = new Color(168, 85, 247, 1.0);\n}\n","/**\n * Generic type-safe event map definition.\n */\nexport type EventMap = Record<string | symbol, any>;\n\n/**\n * Event listener callback function.\n */\nexport type EventListener<T = any> = (payload: T) => void;\n\n/**\n * Internal listener entry tracking original function and one-time status.\n */\ninterface ListenerEntry<T = any> {\n fn: EventListener<T>;\n once: boolean;\n}\n\n/**\n * High-performance, type-safe Pub/Sub Event Emitter for game engine and custom game events.\n */\nexport class EventEmitter<TEvents extends EventMap = Record<string, any>> {\n private _events: Map<keyof TEvents, ListenerEntry[]>;\n\n constructor() {\n this._events = new Map();\n }\n\n /**\n * Register a persistent event listener.\n * @param event The event identifier.\n * @param listener Callback function invoked when the event is emitted.\n */\n public on<K extends keyof TEvents>(event: K, listener: EventListener<TEvents[K]>): this {\n if (!listener || typeof listener !== 'function') {\n throw new TypeError(`EventEmitter.on: listener must be a function, received ${typeof listener}`);\n }\n\n let entries = this._events.get(event);\n if (!entries) {\n entries = [];\n this._events.set(event, entries);\n }\n\n entries.push({ fn: listener, once: false });\n return this;\n }\n\n /**\n * Register a one-time event listener that automatically unbinds after first execution.\n * @param event The event identifier.\n * @param listener Callback function invoked once.\n */\n public once<K extends keyof TEvents>(event: K, listener: EventListener<TEvents[K]>): this {\n if (!listener || typeof listener !== 'function') {\n throw new TypeError(`EventEmitter.once: listener must be a function, received ${typeof listener}`);\n }\n\n let entries = this._events.get(event);\n if (!entries) {\n entries = [];\n this._events.set(event, entries);\n }\n\n entries.push({ fn: listener, once: true });\n return this;\n }\n\n /**\n * Unregister an event listener.\n * @param event The event identifier.\n * @param listener The original callback function to remove.\n */\n public off<K extends keyof TEvents>(event: K, listener: EventListener<TEvents[K]>): this {\n const entries = this._events.get(event);\n if (!entries) return this;\n\n for (let i = entries.length - 1; i >= 0; i--) {\n if (entries[i].fn === listener) {\n entries.splice(i, 1);\n break;\n }\n }\n\n if (entries.length === 0) {\n this._events.delete(event);\n }\n\n return this;\n }\n\n /**\n * Register an event listener and return an unsubscribe disposer function.\n * @param event The event identifier.\n * @param listener Callback function.\n * @returns Disposer function that unsubscribes the listener when called.\n */\n public subscribe<K extends keyof TEvents>(\n event: K,\n listener: EventListener<TEvents[K]>\n ): () => void {\n this.on(event, listener);\n let unsubscribed = false;\n return () => {\n if (!unsubscribed) {\n unsubscribed = true;\n this.off(event, listener);\n }\n };\n }\n\n /**\n * Emit an event to all registered listeners.\n * Safe against listener array mutations during execution.\n * @param event The event identifier.\n * @param payload Optional event payload.\n * @returns True if at least one listener was invoked, false otherwise.\n */\n public emit<K extends keyof TEvents>(\n event: K,\n ...args: TEvents[K] extends void ? [] : [TEvents[K]]\n ): boolean {\n const entries = this._events.get(event);\n if (!entries || entries.length === 0) {\n return false;\n }\n\n const payload = args[0] as TEvents[K];\n\n // Snapshot entries to avoid bugs if listeners add/remove listeners during execution\n const snapshot = entries.slice();\n\n for (let i = 0; i < snapshot.length; i++) {\n const entry = snapshot[i];\n\n if (entry.once) {\n this.off(event, entry.fn);\n }\n\n try {\n entry.fn(payload);\n } catch (err) {\n console.error(`EventEmitter error during event \"${String(event)}\":`, err);\n }\n }\n\n return true;\n }\n\n /**\n * Clear listeners for a specific event, or all events if none specified.\n * @param event Optional event identifier.\n */\n public clear<K extends keyof TEvents>(event?: K): this {\n if (event !== undefined) {\n this._events.delete(event);\n } else {\n this._events.clear();\n }\n return this;\n }\n\n /**\n * Return the number of listeners registered for an event.\n * @param event The event identifier.\n */\n public listenerCount<K extends keyof TEvents>(event: K): number {\n const entries = this._events.get(event);\n return entries ? entries.length : 0;\n }\n\n /**\n * Check whether any listeners are registered for an event.\n * @param event The event identifier.\n */\n public hasListeners<K extends keyof TEvents>(event: K): boolean {\n return this.listenerCount(event) > 0;\n }\n}\n","/**\n * Global engine time management and frame rate measurement.\n * Provides scaled, unscaled delta times, game running time, and zero-allocation rolling FPS average.\n */\nexport class Time {\n /**\n * Scaled delta time for the current frame in seconds (rawDeltaTime * timeScale).\n * Use this for game logic, movement, and animations.\n */\n public static deltaTime: number = 0;\n\n /**\n * Real, unscaled delta time for the current frame in seconds.\n * Use this for UI animations, debug metrics, and menus unaffected by slow-motion.\n */\n public static rawDeltaTime: number = 0;\n\n /**\n * Fixed simulation timestep in seconds (default: 1 / 60 = ~0.0166667s).\n * Matches the interval passed to fixedUpdate().\n */\n public static fixedDeltaTime: number = 1 / 60;\n\n /**\n * Total scaled game time elapsed in seconds since engine start.\n */\n public static time: number = 0;\n\n /**\n * Total unscaled real time elapsed in seconds since engine start.\n */\n public static unscaledTime: number = 0;\n\n /**\n * Total number of update frames executed since engine start.\n */\n public static frameCount: number = 0;\n\n /**\n * Global time scale multiplier.\n * 1.0 = normal speed, 0.5 = slow motion, 2.0 = fast forward, 0.0 = pause game logic.\n */\n public static timeScale: number = 1.0;\n\n /**\n * Rolling average Frames Per Second (FPS) rounded to the nearest integer.\n */\n public static fps: number = 60;\n\n /**\n * Precise rolling average Frames Per Second (FPS) as floating point.\n */\n public static exactFps: number = 60.0;\n\n // Zero-allocation circular ring buffer for rolling FPS calculation\n private static readonly SAMPLE_SIZE: number = 30;\n private static readonly _samples: Float64Array = new Float64Array(Time.SAMPLE_SIZE);\n private static _sampleIndex: number = 0;\n private static _sampleCount: number = 0;\n private static _sampleSum: number = 0;\n\n /**\n * Update engine time properties for a new frame.\n * Called automatically by GameLoop at the beginning of each tick.\n * @param rawDelta Elapsed frame time in seconds.\n */\n public static update(rawDelta: number): void {\n const safeRawDelta = rawDelta < 0 ? 0 : rawDelta;\n\n Time.rawDeltaTime = safeRawDelta;\n Time.deltaTime = safeRawDelta * Time.timeScale;\n Time.time += Time.deltaTime;\n Time.unscaledTime += safeRawDelta;\n Time.frameCount++;\n\n // Update rolling FPS average using stable inverse frame-duration\n if (safeRawDelta > 0) {\n if (Time._sampleCount < Time.SAMPLE_SIZE) {\n Time._samples[Time._sampleIndex] = safeRawDelta;\n Time._sampleSum += safeRawDelta;\n Time._sampleCount++;\n } else {\n Time._sampleSum -= Time._samples[Time._sampleIndex];\n Time._samples[Time._sampleIndex] = safeRawDelta;\n Time._sampleSum += safeRawDelta;\n }\n\n Time._sampleIndex = (Time._sampleIndex + 1) % Time.SAMPLE_SIZE;\n\n const avgDelta = Time._sampleSum / Time._sampleCount;\n if (avgDelta > 0) {\n Time.exactFps = 1 / avgDelta;\n Time.fps = Math.round(Time.exactFps);\n }\n }\n }\n\n /**\n * Set the fixed simulation timestep.\n * @param fixedDelta Step duration in seconds (must be > 0).\n */\n public static setFixedDeltaTime(fixedDelta: number): void {\n if (fixedDelta <= 0) {\n throw new RangeError(`Time.setFixedDeltaTime: fixedDelta must be > 0, received ${fixedDelta}`);\n }\n Time.fixedDeltaTime = fixedDelta;\n }\n\n /**\n * Set the global time scale.\n * @param scale Multiplier (clamped to >= 0).\n */\n public static setTimeScale(scale: number): void {\n Time.timeScale = Math.max(0, scale);\n }\n\n /**\n * Reset all time values and rolling FPS buffers to defaults.\n * Useful for unit test isolation and complete game restarts.\n */\n public static reset(): void {\n Time.deltaTime = 0;\n Time.rawDeltaTime = 0;\n Time.fixedDeltaTime = 1 / 60;\n Time.time = 0;\n Time.unscaledTime = 0;\n Time.frameCount = 0;\n Time.timeScale = 1.0;\n Time.fps = 60;\n Time.exactFps = 60.0;\n\n Time._samples.fill(0);\n Time._sampleIndex = 0;\n Time._sampleCount = 0;\n Time._sampleSum = 0;\n }\n}\n","import { Time } from './Time';\n\n/**\n * Callbacks executed by the GameLoop on each frame.\n */\nexport interface GameLoopCallbacks {\n /**\n * Variable logic update called once per render frame.\n * Use for input polling, entity logic, animations, and sound triggers.\n * @param deltaTime Scaled or raw delta time in seconds.\n */\n update: (deltaTime: number) => void;\n\n /**\n * Deterministic fixed timestep update called 0, 1, or multiple times per frame.\n * Use for physics simulation, velocity integration, and collision response.\n * @param fixedDeltaTime Constant timestep in seconds (default: 1/60s).\n */\n fixedUpdate: (fixedDeltaTime: number) => void;\n\n /**\n * Render pass called once per display frame.\n * @param alpha Interpolation factor in [0, 1] representing remaining accumulator fraction.\n */\n render: (alpha: number) => void;\n}\n\n/**\n * Configuration options for the GameLoop.\n */\nexport interface GameLoopConfig {\n /**\n * Fixed physics timestep in seconds (default: 1 / 60 = 0.0166667s).\n */\n fixedDeltaTime?: number;\n\n /**\n * Maximum allowed frame delta in seconds to prevent the Spiral of Death (default: 0.25s).\n */\n maxFrameDelta?: number;\n\n /**\n * Maximum fixed updates permitted in a single frame tick (default: 15).\n */\n maxSubSteps?: number;\n\n /**\n * Automatically pause the game when the browser tab becomes hidden (default: true).\n */\n autoPauseOnHide?: boolean;\n\n /**\n * Whether to invoke the render callback when paused (default: false).\n */\n renderWhenPaused?: boolean;\n}\n\n/**\n * Deterministic fixed-timestep game loop (\"Fix Your Timestep\") with spiral of death protection,\n * variable render interpolation, and automatic browser visibility integration.\n */\nexport class GameLoop {\n public readonly callbacks: GameLoopCallbacks;\n public readonly fixedDeltaTime: number;\n public readonly maxFrameDelta: number;\n public readonly maxSubSteps: number;\n public readonly autoPauseOnHide: boolean;\n public readonly renderWhenPaused: boolean;\n\n private _accumulator: number = 0;\n private _lastTime: number = 0;\n private _rafId: number | null = null;\n private _running: boolean = false;\n private _paused: boolean = false;\n private _pausedByVisibility: boolean = false;\n private _wasManuallyPaused: boolean = false;\n private _boundVisibilityListener: (() => void) | null = null;\n\n constructor(callbacks: GameLoopCallbacks, config: GameLoopConfig = {}) {\n if (!callbacks || typeof callbacks.update !== 'function' || typeof callbacks.fixedUpdate !== 'function' || typeof callbacks.render !== 'function') {\n throw new TypeError('GameLoop requires update, fixedUpdate, and render callbacks.');\n }\n\n this.callbacks = callbacks;\n this.fixedDeltaTime = config.fixedDeltaTime ?? (1 / 60);\n this.maxFrameDelta = config.maxFrameDelta ?? 0.25;\n this.maxSubSteps = config.maxSubSteps ?? Math.max(1, Math.ceil(this.maxFrameDelta / this.fixedDeltaTime));\n this.autoPauseOnHide = config.autoPauseOnHide ?? true;\n this.renderWhenPaused = config.renderWhenPaused ?? false;\n\n Time.fixedDeltaTime = this.fixedDeltaTime;\n\n if (this.autoPauseOnHide) {\n this._initVisibilityListener();\n }\n }\n\n /**\n * Check whether the loop is currently running.\n */\n public isRunning(): boolean {\n return this._running;\n }\n\n /**\n * Check whether the loop is currently paused.\n */\n public isPaused(): boolean {\n return this._paused;\n }\n\n /**\n * Get the current accumulator remainder in seconds.\n */\n public getAccumulator(): number {\n return this._accumulator;\n }\n\n /**\n * Start the game loop.\n */\n public start(): void {\n if (this._running) return;\n\n this._running = true;\n this._paused = false;\n this._pausedByVisibility = false;\n this._wasManuallyPaused = false;\n this._accumulator = 0;\n this._lastTime = this._now();\n\n this._rafId = this._requestFrame(this._tick);\n }\n\n /**\n * Stop and cancel the game loop.\n */\n public stop(): void {\n if (!this._running) return;\n\n this._running = false;\n if (this._rafId !== null) {\n this._cancelFrame(this._rafId);\n this._rafId = null;\n }\n }\n\n /**\n * Pause game updates and physics simulation.\n */\n public pause(): void {\n if (!this._running || this._paused) return;\n this._paused = true;\n }\n\n /**\n * Resume game updates and physics simulation.\n * Resets time reference and accumulator to prevent large delta leaps.\n */\n public resume(): void {\n if (!this._running || !this._paused) return;\n\n this._paused = false;\n this._pausedByVisibility = false;\n this._wasManuallyPaused = false;\n this._lastTime = this._now();\n this._accumulator = 0;\n }\n\n /**\n * Manually execute a single frame tick.\n * Highly useful for deterministic unit testing and frame-by-frame debuggers.\n * @param dt Elapsed frame time in seconds (defaults to fixedDeltaTime).\n */\n public step(dt?: number): void {\n let frameDelta = dt ?? this.fixedDeltaTime;\n\n if (frameDelta < 0) {\n frameDelta = 0;\n } else if (frameDelta > this.maxFrameDelta) {\n frameDelta = this.maxFrameDelta;\n }\n\n Time.update(frameDelta);\n\n // 1. Variable logic update\n this.callbacks.update(Time.deltaTime);\n\n // 2. Fixed physics updates\n this._accumulator += frameDelta;\n let subSteps = 0;\n while (this._accumulator >= this.fixedDeltaTime && subSteps < this.maxSubSteps) {\n this.callbacks.fixedUpdate(this.fixedDeltaTime);\n this._accumulator -= this.fixedDeltaTime;\n subSteps++;\n }\n\n if (subSteps >= this.maxSubSteps) {\n this._accumulator = 0;\n }\n\n // 3. Render pass with interpolation factor alpha in [0, 1]\n const alpha = Math.min(Math.max(this._accumulator / this.fixedDeltaTime, 0), 1);\n this.callbacks.render(alpha);\n }\n\n /**\n * Teardown and clean up all listeners (e.g. document visibilitychange).\n */\n public destroy(): void {\n this.stop();\n if (this._boundVisibilityListener && typeof document !== 'undefined') {\n document.removeEventListener('visibilitychange', this._boundVisibilityListener);\n this._boundVisibilityListener = null;\n }\n }\n\n /**\n * Internal RAF tick execution.\n */\n private _tick = (currentTime: number): void => {\n if (!this._running) return;\n\n const time = currentTime ?? this._now();\n let frameDelta = (time - this._lastTime) / 1000;\n this._lastTime = time;\n\n // Spiral of death prevention (clamp delta during heavy lags or background tabs)\n if (frameDelta < 0) {\n frameDelta = 0;\n } else if (frameDelta > this.maxFrameDelta) {\n frameDelta = this.maxFrameDelta;\n }\n\n if (!this._paused) {\n // 1. Update engine time tracker\n Time.update(frameDelta);\n\n // 2. Variable logic update\n this.callbacks.update(Time.deltaTime);\n\n // 3. Fixed update for deterministic physics simulation\n this._accumulator += frameDelta;\n let subSteps = 0;\n while (this._accumulator >= this.fixedDeltaTime && subSteps < this.maxSubSteps) {\n this.callbacks.fixedUpdate(this.fixedDeltaTime);\n this._accumulator -= this.fixedDeltaTime;\n subSteps++;\n }\n\n // If maximum substeps was reached, discard excess debt to avoid spiral of death\n if (subSteps >= this.maxSubSteps) {\n this._accumulator = 0;\n }\n\n // 4. Render pass with interpolation factor alpha in [0, 1]\n const alpha = Math.min(Math.max(this._accumulator / this.fixedDeltaTime, 0), 1);\n this.callbacks.render(alpha);\n } else if (this.renderWhenPaused) {\n this.callbacks.render(1.0);\n }\n\n if (this._running) {\n this._rafId = this._requestFrame(this._tick);\n }\n };\n\n /**\n * Safe high-resolution timestamp in milliseconds.\n */\n private _now(): number {\n if (typeof performance !== 'undefined' && typeof performance.now === 'function') {\n return performance.now();\n }\n return Date.now();\n }\n\n /**\n * Safe requestAnimationFrame with fallback for headless testing.\n */\n private _requestFrame(callback: (time: number) => void): number {\n if (typeof requestAnimationFrame === 'function') {\n return requestAnimationFrame(callback);\n }\n return setTimeout(() => callback(this._now()), 16) as unknown as number;\n }\n\n /**\n * Safe cancelAnimationFrame with fallback for headless testing.\n */\n private _cancelFrame(id: number): void {\n if (typeof cancelAnimationFrame === 'function') {\n cancelAnimationFrame(id);\n } else {\n clearTimeout(id);\n }\n }\n\n /**\n * Attach visibilitychange listener for browser tab backgrounding.\n */\n private _initVisibilityListener(): void {\n if (typeof document === 'undefined') return;\n\n this._boundVisibilityListener = () => {\n if (document.hidden) {\n if (this._paused) {\n this._wasManuallyPaused = true;\n } else {\n this._wasManuallyPaused = false;\n this._pausedByVisibility = true;\n this.pause();\n }\n } else {\n if (this._pausedByVisibility && !this._wasManuallyPaused) {\n this.resume();\n } else {\n // Even if staying paused, reset timer reference so resuming later doesn't jump\n this._lastTime = this._now();\n this._accumulator = 0;\n }\n }\n };\n\n document.addEventListener('visibilitychange', this._boundVisibilityListener);\n }\n}\n","import { Matrix2D } from '../math/Matrix2D';\nimport { Color } from '../math/Color';\nimport { ICanvasRenderingContext2D } from './CanvasMock';\n\nexport interface CanvasContextOptions {\n pixelArt?: boolean;\n}\n\n/**\n * Ergonomic wrapper around Canvas 2D rendering context.\n * Features:\n * - Direct transformation matrix synchronization with Matrix2D.\n * - Robust save/restore state stack tracking with underflow protection.\n * - Push/pop alpha and composite operations for nested hierarchies.\n * - Pixel-art smoothing controls.\n * - Headless fallback in Node.js runtime.\n */\nexport class CanvasContext {\n public readonly rawContext: ICanvasRenderingContext2D;\n public readonly currentMatrix: Matrix2D = new Matrix2D();\n\n private _saveDepth: number = 0;\n private _matrixStack: Matrix2D[] = [];\n private _alphaStack: number[] = [];\n private _compositeStack: GlobalCompositeOperation[] = [];\n\n constructor(context: ICanvasRenderingContext2D, options?: CanvasContextOptions) {\n this.rawContext = context;\n\n if (options?.pixelArt) {\n this.setImageSmoothing(false);\n }\n }\n\n // ==========================================\n // Save / Restore Stack\n // ==========================================\n\n public get saveDepth(): number {\n return this._saveDepth;\n }\n\n /**\n * Pushes current state (transform, alpha, composite, and context state) to the stack.\n */\n public save(): this {\n this.rawContext.save();\n this._saveDepth++;\n this._matrixStack.push(this.currentMatrix.clone());\n this._alphaStack.push(this.rawContext.globalAlpha);\n this._compositeStack.push(this.rawContext.globalCompositeOperation);\n return this;\n }\n\n /**\n * Restores the most recently saved context state.\n * Guarded against underflow when saveDepth is 0.\n */\n public restore(): this {\n if (this._saveDepth <= 0) {\n return this;\n }\n\n this.rawContext.restore();\n this._saveDepth--;\n\n const savedMatrix = this._matrixStack.pop();\n if (savedMatrix) {\n this.currentMatrix.copy(savedMatrix);\n }\n\n this._alphaStack.pop();\n this._compositeStack.pop();\n\n return this;\n }\n\n /**\n * Restores state until save depth matches targetDepth.\n */\n public restoreTo(targetDepth: number): this {\n while (this._saveDepth > targetDepth && this._saveDepth > 0) {\n this.restore();\n }\n return this;\n }\n\n // ==========================================\n // Matrix Transformations\n // ==========================================\n\n /**\n * Sets transformation matrix directly and synchronizes with Canvas context.\n */\n public setMatrix(matrix: Matrix2D): this {\n this.currentMatrix.copy(matrix);\n matrix.applyToContext(this.rawContext as unknown as CanvasRenderingContext2D);\n return this;\n }\n\n /**\n * Multiplies given matrix onto the current context transformation.\n */\n public transformMatrix(matrix: Matrix2D): this {\n this.currentMatrix.multiplyInPlace(matrix);\n matrix.transformContext(this.rawContext as unknown as CanvasRenderingContext2D);\n return this;\n }\n\n public translate(x: number, y: number): this {\n this.currentMatrix.translate(x, y);\n this.rawContext.translate(x, y);\n return this;\n }\n\n public rotate(radians: number): this {\n this.currentMatrix.rotate(radians);\n this.rawContext.rotate(radians);\n return this;\n }\n\n public scale(sx: number, sy: number = sx): this {\n this.currentMatrix.scale(sx, sy);\n this.rawContext.scale(sx, sy);\n return this;\n }\n\n public resetTransform(): this {\n this.currentMatrix.identity();\n this.rawContext.setTransform(1, 0, 0, 1, 0, 0);\n return this;\n }\n\n public getMatrix(out?: Matrix2D): Matrix2D {\n const dest = out ?? new Matrix2D();\n return dest.copy(this.currentMatrix);\n }\n\n // ==========================================\n // Alpha & Blend Modes\n // ==========================================\n\n public get globalAlpha(): number {\n return this.rawContext.globalAlpha;\n }\n\n public set globalAlpha(value: number) {\n this.rawContext.globalAlpha = Math.max(0, Math.min(1, value));\n }\n\n /**\n * Multiplies current alpha by factor and pushes previous alpha to stack.\n */\n public pushAlpha(factor: number): this {\n this._alphaStack.push(this.rawContext.globalAlpha);\n this.rawContext.globalAlpha = Math.max(0, Math.min(1, this.rawContext.globalAlpha * factor));\n return this;\n }\n\n public popAlpha(): this {\n const prev = this._alphaStack.pop();\n if (prev !== undefined) {\n this.rawContext.globalAlpha = prev;\n }\n return this;\n }\n\n public get blendMode(): GlobalCompositeOperation {\n return this.rawContext.globalCompositeOperation;\n }\n\n public set blendMode(mode: GlobalCompositeOperation) {\n this.rawContext.globalCompositeOperation = mode;\n }\n\n public pushBlendMode(mode: GlobalCompositeOperation): this {\n this._compositeStack.push(this.rawContext.globalCompositeOperation);\n this.rawContext.globalCompositeOperation = mode;\n return this;\n }\n\n public popBlendMode(): this {\n const prev = this._compositeStack.pop();\n if (prev !== undefined) {\n this.rawContext.globalCompositeOperation = prev;\n }\n return this;\n }\n\n // ==========================================\n // Smoothing & Rendering Modes\n // ==========================================\n\n public get imageSmoothingEnabled(): boolean {\n return this.rawContext.imageSmoothingEnabled;\n }\n\n public setImageSmoothing(enabled: boolean): this {\n this.rawContext.imageSmoothingEnabled = enabled;\n return this;\n }\n\n // ==========================================\n // Styling Properties\n // ==========================================\n\n public setFillStyle(style: string | Color | CanvasGradient | CanvasPattern): this {\n if (style instanceof Color) {\n this.rawContext.fillStyle = style.toRgbaString();\n } else {\n this.rawContext.fillStyle = style;\n }\n return this;\n }\n\n public setStrokeStyle(style: string | Color | CanvasGradient | CanvasPattern): this {\n if (style instanceof Color) {\n this.rawContext.strokeStyle = style.toRgbaString();\n } else {\n this.rawContext.strokeStyle = style;\n }\n return this;\n }\n\n public setLineWidth(width: number): this {\n this.rawContext.lineWidth = width;\n return this;\n }\n\n // ==========================================\n // Drawing Primitives\n // ==========================================\n\n public clearRect(x: number, y: number, width: number, height: number): this {\n this.rawContext.clearRect(x, y, width, height);\n return this;\n }\n\n public fillRect(x: number, y: number, width: number, height: number): this {\n this.rawContext.fillRect(x, y, width, height);\n return this;\n }\n\n public strokeRect(x: number, y: number, width: number, height: number): this {\n this.rawContext.strokeRect(x, y, width, height);\n return this;\n }\n\n public beginPath(): this {\n this.rawContext.beginPath();\n return this;\n }\n\n public closePath(): this {\n this.rawContext.closePath();\n return this;\n }\n\n public moveTo(x: number, y: number): this {\n this.rawContext.moveTo(x, y);\n return this;\n }\n\n public lineTo(x: number, y: number): this {\n this.rawContext.lineTo(x, y);\n return this;\n }\n\n public arc(x: number, y: number, radius: number, startAngle: number = 0, endAngle: number = Math.PI * 2, counterclockwise: boolean = false): this {\n this.rawContext.arc(x, y, radius, startAngle, endAngle, counterclockwise);\n return this;\n }\n\n public fill(): this {\n this.rawContext.fill();\n return this;\n }\n\n public stroke(): this {\n this.rawContext.stroke();\n return this;\n }\n\n public clip(): this {\n this.rawContext.clip();\n return this;\n }\n\n public drawImage(\n image: any,\n sx?: number,\n sy?: number,\n sw?: number,\n sh?: number,\n dx?: number,\n dy?: number,\n dw?: number,\n dh?: number\n ): this {\n if (sx === undefined) {\n this.rawContext.drawImage(image, 0, 0);\n } else if (sw === undefined) {\n this.rawContext.drawImage(image, sx, sy!);\n } else if (dx === undefined) {\n this.rawContext.drawImage(image, sx, sy!, sw, sh!);\n } else {\n this.rawContext.drawImage(image, sx, sy!, sw, sh!, dx, dy!, dw!, dh!);\n }\n return this;\n }\n}\n","import { Matrix2D } from '../math/Matrix2D';\n\n/**\n * Standard Canvas 2D Text Metrics Mock\n */\nexport interface ITextMetrics {\n width: number;\n actualBoundingBoxLeft: number;\n actualBoundingBoxRight: number;\n actualBoundingBoxAscent: number;\n actualBoundingBoxDescent: number;\n}\n\n/**\n * Minimal CanvasRenderingContext2D Duck-Type Interface\n * Matching methods and properties used by the framework rendering pipeline.\n */\nexport interface ICanvasRenderingContext2D {\n canvas: any;\n fillStyle: string | CanvasGradient | CanvasPattern;\n strokeStyle: string | CanvasGradient | CanvasPattern;\n lineWidth: number;\n lineCap: CanvasLineCap;\n lineJoin: CanvasLineJoin;\n miterLimit: number;\n globalAlpha: number;\n globalCompositeOperation: GlobalCompositeOperation;\n imageSmoothingEnabled: boolean;\n font: string;\n textAlign: CanvasTextAlign;\n textBaseline: CanvasTextBaseline;\n shadowBlur: number;\n shadowColor: string;\n shadowOffsetX: number;\n shadowOffsetY: number;\n\n save(): void;\n restore(): void;\n scale(x: number, y: number): void;\n rotate(angle: number): void;\n translate(x: number, y: number): void;\n transform(a: number, b: number, c: number, d: number, e: number, f: number): void;\n setTransform(a: number, b: number, c: number, d: number, e: number, f: number): void;\n resetTransform(): void;\n getTransform(): DOMMatrix;\n\n clearRect(x: number, y: number, w: number, h: number): void;\n fillRect(x: number, y: number, w: number, h: number): void;\n strokeRect(x: number, y: number, w: number, h: number): void;\n\n beginPath(): void;\n closePath(): void;\n moveTo(x: number, y: number): void;\n lineTo(x: number, y: number): void;\n arc(x: number, y: number, radius: number, startAngle: number, endAngle: number, counterclockwise?: boolean): void;\n rect(x: number, y: number, w: number, h: number): void;\n roundRect?(x: number, y: number, w: number, h: number, radii?: number | number[]): void;\n ellipse?(x: number, y: number, radiusX: number, radiusY: number, rotation: number, startAngle: number, endAngle: number, counterclockwise?: boolean): void;\n arcTo?(x1: number, y1: number, x2: number, y2: number, radius: number): void;\n fill(): void;\n stroke(): void;\n clip(): void;\n\n drawImage(image: any, sx: number, sy: number, sw?: number, sh?: number, dx?: number, dy?: number, dw?: number, dh?: number): void;\n fillText(text: string, x: number, y: number, maxWidth?: number): void;\n strokeText(text: string, x: number, y: number, maxWidth?: number): void;\n measureText(text: string): ITextMetrics;\n\n createLinearGradient?(x0: number, y0: number, x1: number, y1: number): CanvasGradient;\n createRadialGradient?(x0: number, y0: number, r0: number, x1: number, y1: number, r1: number): CanvasGradient;\n}\n\n/**\n * Snapshot for state stack in Canvas save/restore\n */\ninterface CanvasContextState {\n fillStyle: string | CanvasGradient | CanvasPattern;\n strokeStyle: string | CanvasGradient | CanvasPattern;\n lineWidth: number;\n lineCap: CanvasLineCap;\n lineJoin: CanvasLineJoin;\n miterLimit: number;\n globalAlpha: number;\n globalCompositeOperation: GlobalCompositeOperation;\n imageSmoothingEnabled: boolean;\n font: string;\n textAlign: CanvasTextAlign;\n textBaseline: CanvasTextBaseline;\n shadowBlur: number;\n shadowColor: string;\n shadowOffsetX: number;\n shadowOffsetY: number;\n transform: [number, number, number, number, number, number];\n}\n\n/**\n * In-memory Mock Canvas 2D Rendering Context\n * Runs in headless Node.js without native binary dependencies and records draw calls for test inspection.\n */\nexport class MockCanvasRenderingContext2D implements ICanvasRenderingContext2D {\n public canvas: any;\n public fillStyle: string | CanvasGradient | CanvasPattern = '#000000';\n public strokeStyle: string | CanvasGradient | CanvasPattern = '#000000';\n public lineWidth: number = 1;\n public lineCap: CanvasLineCap = 'butt';\n public lineJoin: CanvasLineJoin = 'miter';\n public miterLimit: number = 10;\n public globalAlpha: number = 1.0;\n public globalCompositeOperation: GlobalCompositeOperation = 'source-over';\n public imageSmoothingEnabled: boolean = true;\n public font: string = '10px sans-serif';\n public textAlign: CanvasTextAlign = 'start';\n public textBaseline: CanvasTextBaseline = 'alphabetic';\n public shadowBlur: number = 0;\n public shadowColor: string = 'rgba(0, 0, 0, 0)';\n public shadowOffsetX: number = 0;\n public shadowOffsetY: number = 0;\n\n public drawCalls: number = 0;\n public callHistory: Array<{ method: string; args: any[] }> = [];\n\n private _matrix: Matrix2D = new Matrix2D();\n private _stateStack: CanvasContextState[] = [];\n\n constructor(canvas: any) {\n this.canvas = canvas;\n }\n\n public save(): void {\n this.callHistory.push({ method: 'save', args: [] });\n this._stateStack.push({\n fillStyle: this.fillStyle,\n strokeStyle: this.strokeStyle,\n lineWidth: this.lineWidth,\n lineCap: this.lineCap,\n lineJoin: this.lineJoin,\n miterLimit: this.miterLimit,\n globalAlpha: this.globalAlpha,\n globalCompositeOperation: this.globalCompositeOperation,\n imageSmoothingEnabled: this.imageSmoothingEnabled,\n font: this.font,\n textAlign: this.textAlign,\n textBaseline: this.textBaseline,\n shadowBlur: this.shadowBlur,\n shadowColor: this.shadowColor,\n shadowOffsetX: this.shadowOffsetX,\n shadowOffsetY: this.shadowOffsetY,\n transform: [this._matrix.a, this._matrix.b, this._matrix.c, this._matrix.d, this._matrix.tx, this._matrix.ty]\n });\n }\n\n public restore(): void {\n this.callHistory.push({ method: 'restore', args: [] });\n const state = this._stateStack.pop();\n if (!state) return;\n\n this.fillStyle = state.fillStyle;\n this.strokeStyle = state.strokeStyle;\n this.lineWidth = state.lineWidth;\n this.lineCap = state.lineCap;\n this.lineJoin = state.lineJoin;\n this.miterLimit = state.miterLimit;\n this.globalAlpha = state.globalAlpha;\n this.globalCompositeOperation = state.globalCompositeOperation;\n this.imageSmoothingEnabled = state.imageSmoothingEnabled;\n this.font = state.font;\n this.textAlign = state.textAlign;\n this.textBaseline = state.textBaseline;\n this.shadowBlur = state.shadowBlur;\n this.shadowColor = state.shadowColor;\n this.shadowOffsetX = state.shadowOffsetX;\n this.shadowOffsetY = state.shadowOffsetY;\n this._matrix.set(\n state.transform[0],\n state.transform[1],\n state.transform[2],\n state.transform[3],\n state.transform[4],\n state.transform[5]\n );\n }\n\n public scale(x: number, y: number): void {\n this.callHistory.push({ method: 'scale', args: [x, y] });\n this._matrix.scale(x, y);\n }\n\n public rotate(angle: number): void {\n this.callHistory.push({ method: 'rotate', args: [angle] });\n this._matrix.rotate(angle);\n }\n\n public translate(x: number, y: number): void {\n this.callHistory.push({ method: 'translate', args: [x, y] });\n this._matrix.translate(x, y);\n }\n\n public transform(a: number, b: number, c: number, d: number, e: number, f: number): void {\n this.callHistory.push({ method: 'transform', args: [a, b, c, d, e, f] });\n const m = new Matrix2D(a, b, c, d, e, f);\n this._matrix.multiplyInPlace(m);\n }\n\n public setTransform(a: number, b: number, c: number, d: number, e: number, f: number): void {\n this.callHistory.push({ method: 'setTransform', args: [a, b, c, d, e, f] });\n this._matrix.set(a, b, c, d, e, f);\n }\n\n public resetTransform(): void {\n this.callHistory.push({ method: 'resetTransform', args: [] });\n this._matrix.identity();\n }\n\n public getTransform(): DOMMatrix {\n return {\n a: this._matrix.a,\n b: this._matrix.b,\n c: this._matrix.c,\n d: this._matrix.d,\n e: this._matrix.tx,\n f: this._matrix.ty,\n m11: this._matrix.a,\n m12: this._matrix.b,\n m21: this._matrix.c,\n m22: this._matrix.d,\n m41: this._matrix.tx,\n m42: this._matrix.ty\n } as unknown as DOMMatrix;\n }\n\n public clearRect(x: number, y: number, w: number, h: number): void {\n this.callHistory.push({ method: 'clearRect', args: [x, y, w, h] });\n }\n\n public fillRect(x: number, y: number, w: number, h: number): void {\n this.drawCalls++;\n this.callHistory.push({ method: 'fillRect', args: [x, y, w, h] });\n }\n\n public strokeRect(x: number, y: number, w: number, h: number): void {\n this.drawCalls++;\n this.callHistory.push({ method: 'strokeRect', args: [x, y, w, h] });\n }\n\n public beginPath(): void {\n this.callHistory.push({ method: 'beginPath', args: [] });\n }\n\n public closePath(): void {\n this.callHistory.push({ method: 'closePath', args: [] });\n }\n\n public moveTo(x: number, y: number): void {\n this.callHistory.push({ method: 'moveTo', args: [x, y] });\n }\n\n public lineTo(x: number, y: number): void {\n this.callHistory.push({ method: 'lineTo', args: [x, y] });\n }\n\n public arc(x: number, y: number, radius: number, startAngle: number, endAngle: number, counterclockwise: boolean = false): void {\n this.callHistory.push({ method: 'arc', args: [x, y, radius, startAngle, endAngle, counterclockwise] });\n }\n\n public rect(x: number, y: number, w: number, h: number): void {\n this.callHistory.push({ method: 'rect', args: [x, y, w, h] });\n }\n\n public roundRect(x: number, y: number, w: number, h: number, radii?: number | number[]): void {\n this.callHistory.push({ method: 'roundRect', args: [x, y, w, h, radii] });\n }\n\n public arcTo(x1: number, y1: number, x2: number, y2: number, radius: number): void {\n this.callHistory.push({ method: 'arcTo', args: [x1, y1, x2, y2, radius] });\n }\n\n public ellipse(x: number, y: number, radiusX: number, radiusY: number, rotation: number, startAngle: number, endAngle: number, counterclockwise: boolean = false): void {\n this.callHistory.push({ method: 'ellipse', args: [x, y, radiusX, radiusY, rotation, startAngle, endAngle, counterclockwise] });\n }\n\n public fill(): void {\n this.drawCalls++;\n this.callHistory.push({ method: 'fill', args: [] });\n }\n\n public stroke(): void {\n this.drawCalls++;\n this.callHistory.push({ method: 'stroke', args: [] });\n }\n\n public clip(): void {\n this.callHistory.push({ method: 'clip', args: [] });\n }\n\n public drawImage(image: any, ...args: any[]): void {\n this.drawCalls++;\n this.callHistory.push({ method: 'drawImage', args: [image, ...args] });\n }\n\n public fillText(text: string, x: number, y: number, maxWidth?: number): void {\n this.drawCalls++;\n this.callHistory.push({ method: 'fillText', args: [text, x, y, maxWidth] });\n }\n\n public strokeText(text: string, x: number, y: number, maxWidth?: number): void {\n this.drawCalls++;\n this.callHistory.push({ method: 'strokeText', args: [text, x, y, maxWidth] });\n }\n\n public measureText(text: string): ITextMetrics {\n const estimatedWidth = (text ? text.length : 0) * 8;\n return {\n width: estimatedWidth,\n actualBoundingBoxLeft: 0,\n actualBoundingBoxRight: estimatedWidth,\n actualBoundingBoxAscent: 8,\n actualBoundingBoxDescent: 2\n };\n }\n\n public createLinearGradient(_x0: number, _y0: number, _x1: number, _y1: number): CanvasGradient {\n return {\n addColorStop: (_offset: number, _color: string) => {}\n } as unknown as CanvasGradient;\n }\n\n public createRadialGradient(_x0: number, _y0: number, _r0: number, _x1: number, _y1: number, _r1: number): CanvasGradient {\n return {\n addColorStop: (_offset: number, _color: string) => {}\n } as unknown as CanvasGradient;\n }\n\n public clearMock(): void {\n this.drawCalls = 0;\n this.callHistory.length = 0;\n this._stateStack.length = 0;\n this._matrix.identity();\n }\n}\n\n/**\n * In-memory Mock Canvas Element\n */\nexport class MockCanvasElement {\n public width: number;\n public height: number;\n public style: {\n width: string;\n height: string;\n position: string;\n left: string;\n top: string;\n display: string;\n };\n private _context: MockCanvasRenderingContext2D;\n\n constructor(width: number = 800, height: number = 600) {\n this.width = width;\n this.height = height;\n this.style = {\n width: `${width}px`,\n height: `${height}px`,\n position: 'relative',\n left: '0px',\n top: '0px',\n display: 'block'\n };\n this._context = new MockCanvasRenderingContext2D(this);\n }\n\n public getContext(contextId: string): ICanvasRenderingContext2D | null {\n if (contextId === '2d') {\n return this._context;\n }\n return null;\n }\n\n public getBoundingClientRect(): {\n left: number;\n top: number;\n right: number;\n bottom: number;\n width: number;\n height: number;\n x: number;\n y: number;\n } {\n const w = parseFloat(this.style.width) || this.width;\n const h = parseFloat(this.style.height) || this.height;\n const x = parseFloat(this.style.left) || 0;\n const y = parseFloat(this.style.top) || 0;\n return {\n left: x,\n top: y,\n right: x + w,\n bottom: y + h,\n width: w,\n height: h,\n x,\n y\n };\n }\n\n public addEventListener(_type: string, _listener: any): void {}\n public removeEventListener(_type: string, _listener: any): void {}\n public dispatchEvent(_event: any): boolean { return true; }\n}\n\nexport function createMockCanvas(width: number = 800, height: number = 600): MockCanvasElement {\n return new MockCanvasElement(width, height);\n}\n\nexport const CanvasMock = {\n MockCanvasElement,\n MockCanvasRenderingContext2D,\n createMockCanvas\n};\n\n","import { Vector2 } from '../math/Vector2';\nimport { CanvasContext } from './CanvasContext';\nimport { ICanvasRenderingContext2D, MockCanvasElement, createMockCanvas } from './CanvasMock';\nimport { Camera2D } from './Camera2D';\n\nexport type ScaleMode = 'letterbox' | 'fit' | 'stretch' | 'none' | 'fill';\n\nexport interface RendererConfig {\n canvas?: HTMLCanvasElement | MockCanvasElement | string;\n width?: number; // Virtual / logical game width (default 800)\n height?: number; // Virtual / logical game height (default 600)\n scaleMode?: ScaleMode; // Scaling mode (default 'letterbox')\n pixelArt?: boolean; // Image smoothing disabled if true\n backgroundColor?: string; // Frame clear color (default '#11111b')\n highDPI?: boolean; // Enable devicePixelRatio buffer scaling (default true)\n maxPixelRatio?: number; // Clamp max DPR to preserve GPU fill-rate (default 2)\n dpr?: number; // Explicit DPR override for testing\n}\n\nexport interface RenderCommand {\n layer?: number;\n zIndex?: number;\n camera?: Camera2D | null;\n render: (ctx: CanvasContext) => void;\n}\n\nexport enum RenderLayer {\n BACKGROUND = -1000,\n DEFAULT = 0,\n ENTITIES = 100,\n EFFECTS = 200,\n FOREGROUND = 300,\n UI = 1000,\n DEBUG = 2000\n}\n\n/**\n * 2D Canvas Renderer managing viewport resolution, HiDPI buffer scaling,\n * letterbox/fit/stretch presentation, frame lifecycle, and layer composition.\n */\nexport class Renderer {\n public readonly canvas: any;\n public readonly ctx: CanvasContext;\n public readonly rawContext: ICanvasRenderingContext2D;\n\n public readonly virtualWidth: number;\n public readonly virtualHeight: number;\n public readonly scaleMode: ScaleMode;\n public readonly pixelArt: boolean;\n public readonly highDPI: boolean;\n public readonly maxPixelRatio: number;\n\n public backgroundColor: string;\n public dpr: number = 1.0;\n\n // Viewport transforms (Virtual -> CSS Display)\n public scaleX: number = 1.0;\n public scaleY: number = 1.0;\n public offsetX: number = 0;\n public offsetY: number = 0;\n public cssWidth: number = 0;\n public cssHeight: number = 0;\n\n public drawCalls: number = 0;\n private _isFrameActive: boolean = false;\n private _renderQueue: RenderCommand[] = [];\n\n constructor(config: RendererConfig = {}) {\n this.virtualWidth = config.width ?? 800;\n this.virtualHeight = config.height ?? 600;\n this.scaleMode = config.scaleMode ?? 'letterbox';\n this.pixelArt = config.pixelArt ?? false;\n this.highDPI = config.highDPI ?? true;\n this.maxPixelRatio = config.maxPixelRatio ?? 2;\n this.backgroundColor = config.backgroundColor ?? '#11111b';\n\n // Canvas Acquisition & Headless Fallback\n if (typeof config.canvas === 'string' && typeof document !== 'undefined') {\n const el = document.getElementById(config.canvas);\n if (!(el instanceof HTMLCanvasElement)) {\n throw new Error(`Canvas element with id \"${config.canvas}\" not found`);\n }\n this.canvas = el;\n } else if (config.canvas) {\n this.canvas = config.canvas;\n } else if (typeof document !== 'undefined' && typeof document.createElement === 'function') {\n this.canvas = document.createElement('canvas');\n document.body.appendChild(this.canvas);\n } else {\n // Automatic headless fallback for Node.js test environments\n this.canvas = createMockCanvas(this.virtualWidth, this.virtualHeight);\n }\n\n const context = this.canvas.getContext('2d');\n if (!context) {\n throw new Error('Failed to obtain 2D rendering context');\n }\n this.rawContext = context;\n this.ctx = new CanvasContext(this.rawContext, { pixelArt: this.pixelArt });\n\n // Explicit DPR override for testing or auto-detect from window\n if (config.dpr !== undefined) {\n this.dpr = config.dpr;\n } else if (this.highDPI && typeof window !== 'undefined' && window.devicePixelRatio) {\n this.dpr = Math.min(window.devicePixelRatio, this.maxPixelRatio);\n } else {\n this.dpr = 1.0;\n }\n\n this.resize(this.virtualWidth, this.virtualHeight);\n }\n\n // ==========================================\n // Viewport & Resolution Calculation\n // ==========================================\n\n /**\n * Recalculates canvas display dimensions, physical buffer size,\n * and scale factors according to container/window dimensions and active scaleMode.\n */\n public resize(containerWidth?: number, containerHeight?: number): void {\n let winWidth = containerWidth;\n let winHeight = containerHeight;\n\n if (winWidth === undefined || winHeight === undefined) {\n if (typeof window !== 'undefined') {\n winWidth = window.innerWidth;\n winHeight = window.innerHeight;\n } else {\n winWidth = this.virtualWidth;\n winHeight = this.virtualHeight;\n }\n }\n\n let targetW = this.virtualWidth;\n let targetH = this.virtualHeight;\n let offX = 0;\n let offY = 0;\n\n switch (this.scaleMode) {\n case 'letterbox': {\n const scale = Math.min(winWidth / this.virtualWidth, winHeight / this.virtualHeight);\n targetW = Math.floor(this.virtualWidth * scale);\n targetH = Math.floor(this.virtualHeight * scale);\n offX = Math.floor((winWidth - targetW) / 2);\n offY = Math.floor((winHeight - targetH) / 2);\n this.scaleX = targetW / this.virtualWidth;\n this.scaleY = targetH / this.virtualHeight;\n break;\n }\n case 'fit': {\n const scale = Math.min(winWidth / this.virtualWidth, winHeight / this.virtualHeight);\n targetW = Math.floor(this.virtualWidth * scale);\n targetH = Math.floor(this.virtualHeight * scale);\n offX = 0;\n offY = 0;\n this.scaleX = targetW / this.virtualWidth;\n this.scaleY = targetH / this.virtualHeight;\n break;\n }\n case 'stretch': {\n targetW = winWidth;\n targetH = winHeight;\n offX = 0;\n offY = 0;\n this.scaleX = winWidth / this.virtualWidth;\n this.scaleY = winHeight / this.virtualHeight;\n break;\n }\n case 'fill': {\n const scale = Math.max(winWidth / this.virtualWidth, winHeight / this.virtualHeight);\n targetW = Math.floor(this.virtualWidth * scale);\n targetH = Math.floor(this.virtualHeight * scale);\n offX = Math.floor((winWidth - targetW) / 2);\n offY = Math.floor((winHeight - targetH) / 2);\n this.scaleX = targetW / this.virtualWidth;\n this.scaleY = targetH / this.virtualHeight;\n break;\n }\n case 'none':\n default: {\n targetW = this.virtualWidth;\n targetH = this.virtualHeight;\n offX = 0;\n offY = 0;\n this.scaleX = 1.0;\n this.scaleY = 1.0;\n break;\n }\n }\n\n this.cssWidth = targetW;\n this.cssHeight = targetH;\n this.offsetX = offX;\n this.offsetY = offY;\n\n // Apply CSS dimensions\n if (this.canvas.style) {\n this.canvas.style.width = `${targetW}px`;\n this.canvas.style.height = `${targetH}px`;\n if (this.scaleMode === 'letterbox') {\n this.canvas.style.position = 'absolute';\n this.canvas.style.left = `${offX}px`;\n this.canvas.style.top = `${offY}px`;\n }\n }\n\n // Set internal high-DPI buffer resolution\n const bufferWidth = Math.round(targetW * this.dpr);\n const bufferHeight = Math.round(targetH * this.dpr);\n if (this.canvas.width !== bufferWidth || this.canvas.height !== bufferHeight) {\n this.canvas.width = bufferWidth;\n this.canvas.height = bufferHeight;\n }\n\n // Refresh smoothing rule on underlying context\n this.ctx.setImageSmoothing(!this.pixelArt);\n }\n\n // ==========================================\n // Screen / Canvas Coordinate Mapping\n // ==========================================\n\n /**\n * Converts browser client window coordinates (e.g., mouse / touch clientX, clientY)\n * to game virtual coordinates (0 to virtualWidth, 0 to virtualHeight).\n */\n public screenToVirtual(clientX: number, clientY: number, out?: Vector2): Vector2 {\n const dest = out ?? new Vector2();\n let rect = { left: 0, top: 0, width: this.cssWidth, height: this.cssHeight };\n\n if (typeof this.canvas.getBoundingClientRect === 'function') {\n rect = this.canvas.getBoundingClientRect();\n }\n\n const localX = clientX - rect.left;\n const localY = clientY - rect.top;\n\n const vx = rect.width > 0 ? (localX / rect.width) * this.virtualWidth : localX;\n const vy = rect.height > 0 ? (localY / rect.height) * this.virtualHeight : localY;\n\n return dest.set(vx, vy);\n }\n\n /**\n * Converts game virtual coordinates to browser client coordinates.\n */\n public virtualToScreen(vx: number, vy: number, out?: Vector2): Vector2 {\n const dest = out ?? new Vector2();\n let rect = { left: 0, top: 0, width: this.cssWidth, height: this.cssHeight };\n\n if (typeof this.canvas.getBoundingClientRect === 'function') {\n rect = this.canvas.getBoundingClientRect();\n }\n\n const sx = rect.left + (vx / this.virtualWidth) * rect.width;\n const sy = rect.top + (vy / this.virtualHeight) * rect.height;\n\n return dest.set(sx, sy);\n }\n\n // ==========================================\n // Frame Lifecycle & Clearing\n // ==========================================\n\n /**\n * Clears entire physical canvas buffer with background color.\n */\n public clear(color: string = this.backgroundColor): void {\n this.rawContext.save();\n this.rawContext.setTransform(1, 0, 0, 1, 0, 0);\n this.rawContext.fillStyle = color;\n this.rawContext.fillRect(0, 0, this.canvas.width, this.canvas.height);\n this.rawContext.restore();\n }\n\n /**\n * Begins frame rendering:\n * - Resets draw call counters\n * - Clears canvas with background color\n * - Sets initial high-DPI viewport transform\n */\n public beginFrame(): void {\n this._isFrameActive = true;\n this.drawCalls = 0;\n this._renderQueue.length = 0;\n\n this.clear();\n\n // Scale context to bridge virtual coordinates -> physical high-DPI buffer\n const rootScaleX = this.scaleX * this.dpr;\n const rootScaleY = this.scaleY * this.dpr;\n this.rawContext.setTransform(rootScaleX, 0, 0, rootScaleY, 0, 0);\n this.ctx.currentMatrix.set(rootScaleX, 0, 0, rootScaleY, 0, 0);\n }\n\n /**\n * Ends frame rendering:\n * - Flushes queued render commands sorted by layer & zIndex\n * - Restores context save depth to 0 if left unbalanced\n */\n public endFrame(): void {\n if (!this._isFrameActive) return;\n\n this.flushQueue();\n\n // Context cleanup: safety guard against leaking saves\n if (this.ctx.saveDepth > 0) {\n this.ctx.restoreTo(0);\n }\n\n if ((this.rawContext as any).drawCalls !== undefined) {\n this.drawCalls = (this.rawContext as any).drawCalls;\n }\n\n this._isFrameActive = false;\n }\n\n // ==========================================\n // Layer Composition & Render Queue\n // ==========================================\n\n /**\n * Submits a render command to be executed in layer & zIndex order on endFrame().\n */\n public submit(command: RenderCommand): void {\n this._renderQueue.push(command);\n }\n\n /**\n * Sorts and renders all queued render commands.\n */\n public flushQueue(): void {\n if (this._renderQueue.length === 0) return;\n\n // Stable sort: primary layer asc, secondary zIndex asc\n this._renderQueue.sort((a, b) => {\n const layerA = a.layer ?? 0;\n const layerB = b.layer ?? 0;\n if (layerA !== layerB) return layerA - layerB;\n\n const zA = a.zIndex ?? 0;\n const zB = b.zIndex ?? 0;\n return zA - zB;\n });\n\n let currentCamera: Camera2D | null | undefined = undefined;\n\n for (let i = 0; i < this._renderQueue.length; i++) {\n const cmd = this._renderQueue[i];\n\n // Switch camera transform if needed\n if (cmd.camera !== currentCamera) {\n if (currentCamera) {\n this.ctx.restore();\n }\n currentCamera = cmd.camera;\n if (currentCamera) {\n this.ctx.save();\n currentCamera.applyToContext(this.ctx);\n }\n }\n\n cmd.render(this.ctx);\n }\n\n if (currentCamera) {\n this.ctx.restore();\n }\n\n this._renderQueue.length = 0;\n }\n}\n","import { Vector2 } from '../math/Vector2';\nimport { Matrix2D } from '../math/Matrix2D';\nimport { Rect } from '../math/Rect';\nimport { MathUtils } from '../math/MathUtils';\nimport { CanvasContext } from './CanvasContext';\nimport { ICanvasRenderingContext2D } from './CanvasMock';\n\nexport interface CameraFollowTarget {\n position: Vector2;\n}\n\nexport interface Camera2DConfig {\n viewportWidth: number;\n viewportHeight: number;\n x?: number;\n y?: number;\n zoom?: number;\n rotation?: number;\n originX?: number; // 0.5 = center, 0 = top-left\n originY?: number;\n bounds?: Rect;\n}\n\n/**\n * 2D Camera subsystem handling viewport transformation, smooth target follow with deadzone,\n * screen-to-world unprojection, trauma screen shake, and frustum culling queries.\n */\nexport class Camera2D {\n public readonly position: Vector2 = new Vector2(0, 0);\n public readonly origin: Vector2 = new Vector2(0.5, 0.5); // Default: center origin\n public readonly offset: Vector2 = new Vector2(0, 0);\n\n public viewportWidth: number;\n public viewportHeight: number;\n\n private _zoom: number = 1.0;\n private _rotation: number = 0; // In radians\n\n // Target Following\n public target: Vector2 | CameraFollowTarget | null = null;\n public followLerp: number = 0.1;\n public deadzone: Rect | null = null;\n public bounds: Rect | null = null;\n\n // Trauma-based Screen Shake\n public trauma: number = 0;\n public traumaDecay: number = 1.5;\n public maxShakeOffset: number = 20; // Max pixels\n public maxShakeAngle: number = 0.05; // Max radians\n\n // Internal Cached Matrices & Dirty Flags\n private readonly _viewMatrix: Matrix2D = new Matrix2D();\n private readonly _invViewMatrix: Matrix2D = new Matrix2D();\n private readonly _visibleBounds: Rect = new Rect();\n private _isDirty: boolean = true;\n private _boundsDirty: boolean = true;\n\n // Pre-allocated scratch vectors for frustum corner unprojections (zero allocation during culling)\n private static readonly _scratchScreenTL: Vector2 = new Vector2();\n private static readonly _scratchScreenTR: Vector2 = new Vector2();\n private static readonly _scratchScreenBR: Vector2 = new Vector2();\n private static readonly _scratchScreenBL: Vector2 = new Vector2();\n\n private static readonly _scratchWorldTL: Vector2 = new Vector2();\n private static readonly _scratchWorldTR: Vector2 = new Vector2();\n private static readonly _scratchWorldBR: Vector2 = new Vector2();\n private static readonly _scratchWorldBL: Vector2 = new Vector2();\n\n private _lastPosX: number = NaN;\n private _lastPosY: number = NaN;\n private _lastOriginX: number = NaN;\n private _lastOriginY: number = NaN;\n private _lastOffsetX: number = NaN;\n private _lastOffsetY: number = NaN;\n private _lastViewportW: number = NaN;\n private _lastViewportH: number = NaN;\n\n // Transient shake values for current frame\n private _shakeOffsetX: number = 0;\n private _shakeOffsetY: number = 0;\n private _shakeAngle: number = 0;\n\n constructor(config: Camera2DConfig) {\n this.viewportWidth = config.viewportWidth;\n this.viewportHeight = config.viewportHeight;\n\n if (config.x !== undefined || config.y !== undefined) {\n this.position.set(config.x ?? 0, config.y ?? 0);\n }\n if (config.zoom !== undefined) {\n this.zoom = config.zoom;\n }\n if (config.rotation !== undefined) {\n this.rotation = config.rotation;\n }\n if (config.originX !== undefined || config.originY !== undefined) {\n this.origin.set(config.originX ?? 0.5, config.originY ?? 0.5);\n }\n if (config.bounds) {\n this.bounds = config.bounds.clone();\n }\n }\n\n // ==========================================\n // Properties with Dirty Flag Invalidation\n // ==========================================\n\n public get zoom(): number {\n return this._zoom;\n }\n\n public set zoom(value: number) {\n const clamped = Math.max(0.0001, value);\n if (this._zoom !== clamped) {\n this._zoom = clamped;\n this._isDirty = true;\n this._boundsDirty = true;\n }\n }\n\n public get rotation(): number {\n return this._rotation;\n }\n\n public set rotation(radians: number) {\n if (this._rotation !== radians) {\n this._rotation = radians;\n this._isDirty = true;\n this._boundsDirty = true;\n }\n }\n\n public setPosition(x: number, y: number): this {\n if (this.position.x !== x || this.position.y !== y) {\n this.position.set(x, y);\n this._isDirty = true;\n this._boundsDirty = true;\n }\n return this;\n }\n\n public setViewportSize(width: number, height: number): this {\n if (this.viewportWidth !== width || this.viewportHeight !== height) {\n this.viewportWidth = width;\n this.viewportHeight = height;\n this._isDirty = true;\n this._boundsDirty = true;\n }\n return this;\n }\n\n public markDirty(): this {\n this._isDirty = true;\n this._boundsDirty = true;\n return this;\n }\n\n // ==========================================\n // Target Follow & Deadzone\n // ==========================================\n\n public follow(target: Vector2 | CameraFollowTarget | null, lerp: number = 0.1, deadzone?: Rect): this {\n this.target = target;\n this.followLerp = lerp;\n this.deadzone = deadzone ?? null;\n return this;\n }\n\n public update(dt: number): void {\n // 1. Target Tracking with Deadzone & Lerp\n if (this.target) {\n const targetPos = 'position' in this.target ? this.target.position : this.target;\n\n if (this.deadzone) {\n const dx = targetPos.x - this.position.x;\n const dy = targetPos.y - this.position.y;\n const halfDeadW = this.deadzone.width * 0.5;\n const halfDeadH = this.deadzone.height * 0.5;\n\n let desiredX = this.position.x;\n let desiredY = this.position.y;\n\n if (Math.abs(dx) > halfDeadW) {\n desiredX = targetPos.x - Math.sign(dx) * halfDeadW;\n }\n if (Math.abs(dy) > halfDeadH) {\n desiredY = targetPos.y - Math.sign(dy) * halfDeadH;\n }\n\n this.position.x = MathUtils.lerp(this.position.x, desiredX, this.followLerp);\n this.position.y = MathUtils.lerp(this.position.y, desiredY, this.followLerp);\n } else {\n this.position.x = MathUtils.lerp(this.position.x, targetPos.x, this.followLerp);\n this.position.y = MathUtils.lerp(this.position.y, targetPos.y, this.followLerp);\n }\n this._isDirty = true;\n this._boundsDirty = true;\n }\n\n // 2. World Bounds Clamping\n this.clampToBounds();\n\n // 3. Trauma Shake Decay\n if (this.trauma > 0) {\n this.trauma = Math.max(0, this.trauma - this.traumaDecay * dt);\n const shakePower = this.trauma * this.trauma; // Non-linear response\n this._shakeOffsetX = (Math.random() * 2 - 1) * this.maxShakeOffset * shakePower;\n this._shakeOffsetY = (Math.random() * 2 - 1) * this.maxShakeOffset * shakePower;\n this._shakeAngle = (Math.random() * 2 - 1) * this.maxShakeAngle * shakePower;\n this._isDirty = true;\n this._boundsDirty = true;\n } else {\n if (this._shakeOffsetX !== 0 || this._shakeOffsetY !== 0 || this._shakeAngle !== 0) {\n this._shakeOffsetX = 0;\n this._shakeOffsetY = 0;\n this._shakeAngle = 0;\n this._isDirty = true;\n this._boundsDirty = true;\n }\n }\n }\n\n public addTrauma(amount: number): this {\n this.trauma = MathUtils.clamp01(this.trauma + amount);\n return this;\n }\n\n public clampToBounds(): void {\n if (!this.bounds) return;\n\n const prevX = this.position.x;\n const prevY = this.position.y;\n\n const halfW = (this.viewportWidth * this.origin.x) / this._zoom;\n const halfH = (this.viewportHeight * this.origin.y) / this._zoom;\n const remW = (this.viewportWidth * (1 - this.origin.x)) / this._zoom;\n const remH = (this.viewportHeight * (1 - this.origin.y)) / this._zoom;\n\n const minX = this.bounds.left + halfW;\n const maxX = this.bounds.right - remW;\n const minY = this.bounds.top + halfH;\n const maxY = this.bounds.bottom - remH;\n\n if (minX <= maxX) {\n this.position.x = MathUtils.clamp(this.position.x, minX, maxX);\n } else {\n this.position.x = this.bounds.centerX;\n }\n\n if (minY <= maxY) {\n this.position.y = MathUtils.clamp(this.position.y, minY, maxY);\n } else {\n this.position.y = this.bounds.centerY;\n }\n\n if (this.position.x !== prevX || this.position.y !== prevY) {\n this._isDirty = true;\n this._boundsDirty = true;\n }\n }\n\n // ==========================================\n // Matrix Evaluation & Coordinate Spaces\n // ==========================================\n\n /**\n * Updates cached view matrix and inverse matrix.\n */\n public updateMatrix(): void {\n if (\n Number.isNaN(this.position.x) ||\n Number.isNaN(this.position.y) ||\n Number.isNaN(this._rotation) ||\n Number.isNaN(this._zoom)\n ) {\n return;\n }\n\n if (\n this.position.x !== this._lastPosX ||\n this.position.y !== this._lastPosY ||\n this.origin.x !== this._lastOriginX ||\n this.origin.y !== this._lastOriginY ||\n this.offset.x !== this._lastOffsetX ||\n this.offset.y !== this._lastOffsetY ||\n this.viewportWidth !== this._lastViewportW ||\n this.viewportHeight !== this._lastViewportH\n ) {\n this._isDirty = true;\n this._boundsDirty = true;\n }\n\n if (!this._isDirty) return;\n\n const originScreenX = this.origin.x * this.viewportWidth + this.offset.x;\n const originScreenY = this.origin.y * this.viewportHeight + this.offset.y;\n\n const posX = this.position.x + this._shakeOffsetX;\n const posY = this.position.y + this._shakeOffsetY;\n const rot = this._rotation + this._shakeAngle;\n\n // View Matrix: Translate(Origin) -> Rotate(rot) -> Scale(zoom) -> Translate(-Pos)\n this._viewMatrix.identity();\n this._viewMatrix.translate(originScreenX, originScreenY);\n if (rot !== 0) {\n this._viewMatrix.rotate(rot);\n }\n if (this._zoom !== 1.0) {\n this._viewMatrix.scale(this._zoom, this._zoom);\n }\n this._viewMatrix.translate(-posX, -posY);\n\n // Inverse View Matrix (Screen to World)\n this._invViewMatrix.copy(this._viewMatrix).invert();\n\n this._lastPosX = this.position.x;\n this._lastPosY = this.position.y;\n this._lastOriginX = this.origin.x;\n this._lastOriginY = this.origin.y;\n this._lastOffsetX = this.offset.x;\n this._lastOffsetY = this.offset.y;\n this._lastViewportW = this.viewportWidth;\n this._lastViewportH = this.viewportHeight;\n\n this._isDirty = false;\n this._recomputeVisibleBounds();\n this._boundsDirty = false;\n }\n\n public getViewMatrix(): Matrix2D {\n this.updateMatrix();\n return this._viewMatrix;\n }\n\n public getInverseViewMatrix(): Matrix2D {\n this.updateMatrix();\n return this._invViewMatrix;\n }\n\n /**\n * Transforms world coordinates into screen coordinates.\n */\n public worldToScreen(worldPos: Vector2, out?: Vector2): Vector2 {\n this.updateMatrix();\n return this._viewMatrix.transformPoint(worldPos, out);\n }\n\n /**\n * Transforms screen / viewport coordinates into world coordinates.\n */\n public screenToWorld(screenPos: Vector2, out?: Vector2): Vector2 {\n this.updateMatrix();\n return this._invViewMatrix.transformPoint(screenPos, out);\n }\n\n /**\n * Applies camera transformation matrix to CanvasContext or raw context.\n */\n public applyToContext(ctx: CanvasContext | ICanvasRenderingContext2D | any): void {\n this.updateMatrix();\n if (ctx instanceof CanvasContext) {\n ctx.transformMatrix(this._viewMatrix);\n } else if (ctx && typeof ctx.transform === 'function') {\n this._viewMatrix.transformContext(ctx);\n }\n }\n\n // ==========================================\n // Frustum Culling & Viewport Bounds\n // ==========================================\n\n /**\n * Recomputes cached visible bounds using pre-allocated scratch vectors.\n * Zero heap allocations.\n */\n private _recomputeVisibleBounds(): void {\n if (this._rotation === 0 && this._shakeAngle === 0) {\n // Fast path: pure axis-aligned viewport\n Camera2D._scratchScreenTL.set(0, 0);\n Camera2D._scratchScreenBR.set(this.viewportWidth, this.viewportHeight);\n const worldTopLeft = this._invViewMatrix.transformPoint(Camera2D._scratchScreenTL, Camera2D._scratchWorldTL);\n const worldBottomRight = this._invViewMatrix.transformPoint(Camera2D._scratchScreenBR, Camera2D._scratchWorldBR);\n this._visibleBounds.set(\n worldTopLeft.x,\n worldTopLeft.y,\n worldBottomRight.x - worldTopLeft.x,\n worldBottomRight.y - worldTopLeft.y\n );\n return;\n }\n\n // Rotated path: unproject 4 corners and compute minimal enclosing AABB\n Camera2D._scratchScreenTL.set(0, 0);\n Camera2D._scratchScreenTR.set(this.viewportWidth, 0);\n Camera2D._scratchScreenBR.set(this.viewportWidth, this.viewportHeight);\n Camera2D._scratchScreenBL.set(0, this.viewportHeight);\n\n const p1 = this._invViewMatrix.transformPoint(Camera2D._scratchScreenTL, Camera2D._scratchWorldTL);\n const p2 = this._invViewMatrix.transformPoint(Camera2D._scratchScreenTR, Camera2D._scratchWorldTR);\n const p3 = this._invViewMatrix.transformPoint(Camera2D._scratchScreenBR, Camera2D._scratchWorldBR);\n const p4 = this._invViewMatrix.transformPoint(Camera2D._scratchScreenBL, Camera2D._scratchWorldBL);\n\n const minX = Math.min(p1.x, p2.x, p3.x, p4.x);\n const minY = Math.min(p1.y, p2.y, p3.y, p4.y);\n const maxX = Math.max(p1.x, p2.x, p3.x, p4.x);\n const maxY = Math.max(p1.y, p2.y, p3.y, p4.y);\n\n this._visibleBounds.set(minX, minY, maxX - minX, maxY - minY);\n }\n\n /**\n * Returns Axis-Aligned Bounding Box (AABB) in world space of the visible camera area.\n * Cached to eliminate recalculation and object allocation during frustum culling.\n */\n public getVisibleBounds(out?: Rect): Rect {\n this.updateMatrix();\n if (this._boundsDirty) {\n this._recomputeVisibleBounds();\n this._boundsDirty = false;\n }\n\n if (out && out !== this._visibleBounds) {\n return out.copy(this._visibleBounds);\n }\n return this._visibleBounds;\n }\n\n /**\n * Checks whether a bounding box in world space intersects the camera's visible frustum.\n */\n public isVisible(bounds: Rect): boolean {\n return this.getVisibleBounds().intersects(bounds);\n }\n}\n","import { Vector2 } from '../math/Vector2';\n\n/**\n * Standard mouse and pointer button codes.\n */\nexport enum MouseButton {\n Primary = 0, // Left click\n Middle = 1, // Scroll wheel click\n Secondary = 2, // Right click\n Back = 3,\n Forward = 4\n}\n\nexport type MouseButtonName = 'primary' | 'secondary' | 'middle' | 'left' | 'right';\n\n/**\n * Camera interface for decoupled world coordinate unprojection.\n */\nexport interface ICamera {\n screenToWorld(screenPos: Vector2, out?: Vector2): Vector2;\n}\n\n/**\n * Normalizes button identifiers (names or numbers) into standard button indices.\n */\nexport function normalizeButton(button: MouseButtonName | number = 0): number {\n if (typeof button === 'number') return button;\n switch (button) {\n case 'primary':\n case 'left':\n return MouseButton.Primary;\n case 'middle':\n return MouseButton.Middle;\n case 'secondary':\n case 'right':\n return MouseButton.Secondary;\n default:\n return 0;\n }\n}\n\n/**\n * Tracks pointer / mouse state, coordinates, button transitions, and click consumption.\n */\nexport class Pointer {\n /**\n * UI Click consumption flag.\n * UI elements set this to `true` when handling clicks.\n * Game entities MUST verify `!pointer.consumed` before processing clicks.\n */\n public consumed: boolean = false;\n\n /** Coordinates relative to browser client viewport */\n public readonly screenPosition: Vector2 = new Vector2(0, 0);\n\n /** Coordinates mapped to canvas viewport resolution */\n public readonly canvasPosition: Vector2 = new Vector2(0, 0);\n\n /** Previous frame canvas position */\n public readonly previousCanvasPosition: Vector2 = new Vector2(0, 0);\n\n /** Canvas movement delta since previous frame (zero-allocation) */\n public readonly delta: Vector2 = new Vector2(0, 0);\n\n /** Accumulated scroll wheel delta for current frame */\n public readonly wheelDelta: Vector2 = new Vector2(0, 0);\n\n /** Active pointer device type */\n public pointerType: 'mouse' | 'touch' | 'pen' = 'mouse';\n\n /** Pointer identifier (from DOM PointerEvent) */\n public pointerId: number = 0;\n\n /** Whether the pointer is currently within the canvas bounds */\n public isInside: boolean = false;\n\n // Active frame button states\n private _downButtons: Set<number> = new Set();\n private _justPressedButtons: Set<number> = new Set();\n private _justReleasedButtons: Set<number> = new Set();\n\n // Pending button states from asynchronous DOM events\n private _pendingDownButtons: Set<number> = new Set();\n private _pendingUpButtons: Set<number> = new Set();\n private _pendingWheelDelta: Vector2 = new Vector2(0, 0);\n\n // Scratchpad for zero-allocation world queries\n private _worldScratch: Vector2 = new Vector2(0, 0);\n\n /**\n * Check if a pointer/mouse button is currently held down.\n */\n public isDown(button: MouseButtonName | number = 0): boolean {\n return this._downButtons.has(normalizeButton(button));\n }\n\n /**\n * Check if a pointer/mouse button was pressed during this frame tick.\n */\n public isJustPressed(button: MouseButtonName | number = 0): boolean {\n return this._justPressedButtons.has(normalizeButton(button));\n }\n\n /**\n * Check if a pointer/mouse button was released during this frame tick.\n */\n public isJustReleased(button: MouseButtonName | number = 0): boolean {\n return this._justReleasedButtons.has(normalizeButton(button));\n }\n\n /**\n * Absorb the click for this frame so lower-priority layers (game entities) ignore it.\n */\n public consume(): void {\n this.consumed = true;\n }\n\n /**\n * Check if the click has already been absorbed by a higher-priority layer (UI).\n */\n public isConsumed(): boolean {\n return this.consumed;\n }\n\n /**\n * Calculate world coordinates by unprojecting through the given Camera2D.\n * @param camera Camera instance supporting screenToWorld.\n * @param out Optional output Vector2 to avoid garbage collection.\n */\n public getWorldPosition(camera: ICamera, out?: Vector2): Vector2 {\n return camera.screenToWorld(this.canvasPosition, out ?? this._worldScratch);\n }\n\n /** Convenience getter for canvas X */\n public get x(): number {\n return this.canvasPosition.x;\n }\n\n /** Convenience getter for canvas Y */\n public get y(): number {\n return this.canvasPosition.y;\n }\n\n /**\n * Update screen and canvas positions with bounding client rect transformation.\n */\n public updatePositions(clientX: number, clientY: number, target: HTMLElement | any): void {\n this.screenPosition.set(clientX, clientY);\n\n if (target && typeof target.getBoundingClientRect === 'function') {\n const rect = target.getBoundingClientRect();\n const canvas = target as HTMLCanvasElement;\n const width = canvas.width ?? rect.width;\n const height = canvas.height ?? rect.height;\n\n const scaleX = rect.width > 0 ? width / rect.width : 1;\n const scaleY = rect.height > 0 ? height / rect.height : 1;\n\n this.canvasPosition.set((clientX - rect.left) * scaleX, (clientY - rect.top) * scaleY);\n } else {\n this.canvasPosition.set(clientX, clientY);\n }\n }\n\n /**\n * Record a pointer down event into pending buffer.\n */\n public recordDown(button: number): void {\n this._pendingDownButtons.add(button);\n }\n\n /**\n * Record a pointer up event into pending buffer.\n */\n public recordUp(button: number): void {\n this._pendingUpButtons.add(button);\n }\n\n /**\n * Accumulate wheel delta into pending buffer.\n */\n public recordWheel(deltaX: number, deltaY: number): void {\n this._pendingWheelDelta.x += deltaX;\n this._pendingWheelDelta.y += deltaY;\n }\n\n /**\n * Frame update: promote pending DOM events to active frame state.\n */\n public update(): void {\n this._justPressedButtons.clear();\n this._justReleasedButtons.clear();\n\n // Process pending downs\n for (const btn of this._pendingDownButtons) {\n if (!this._downButtons.has(btn)) {\n this._justPressedButtons.add(btn);\n }\n this._downButtons.add(btn);\n }\n this._pendingDownButtons.clear();\n\n // Process pending ups\n for (const btn of this._pendingUpButtons) {\n if (this._downButtons.has(btn) || this._justPressedButtons.has(btn)) {\n this._justReleasedButtons.add(btn);\n }\n this._downButtons.delete(btn);\n }\n this._pendingUpButtons.clear();\n\n // Position delta\n this.delta.subVectors(this.canvasPosition, this.previousCanvasPosition);\n this.previousCanvasPosition.copy(this.canvasPosition);\n\n // Commit wheel delta\n this.wheelDelta.copy(this._pendingWheelDelta);\n this._pendingWheelDelta.set(0, 0);\n }\n\n /**\n * Late update: clear transitions, wheel delta, and reset click consumption flag.\n */\n public lateUpdate(): void {\n this._justPressedButtons.clear();\n this._justReleasedButtons.clear();\n this.wheelDelta.set(0, 0);\n this.consumed = false;\n }\n\n /**\n * Full reset of pointer state.\n */\n public reset(): void {\n this._downButtons.clear();\n this._justPressedButtons.clear();\n this._justReleasedButtons.clear();\n this._pendingDownButtons.clear();\n this._pendingUpButtons.clear();\n this._pendingWheelDelta.set(0, 0);\n this.wheelDelta.set(0, 0);\n this.delta.set(0, 0);\n this.consumed = false;\n }\n}\n","import { Vector2 } from '../math/Vector2';\nimport { Rect } from '../math/Rect';\nimport { CanvasContext } from '../rendering/CanvasContext';\n\nexport type VirtualJoystickMode = 'fixed' | 'floating';\n\nexport interface VirtualJoystickOptions {\n /** Mode: 'fixed' (constant anchor) or 'floating' (appears where touched). Default: 'floating' */\n mode?: VirtualJoystickMode;\n /** Anchor point when mode is 'fixed'. Default: (120, 480) */\n basePosition?: Vector2;\n /** Maximum stick displacement radius in pixels. Default: 60 */\n radius?: number;\n /** Normalized deadzone ratio in [0, 1]. Default: 0.15 */\n deadzone?: number;\n /** Optional bounding area on screen to trigger the joystick. Default: null (entire screen) */\n touchArea?: Rect | null;\n /** Initial visibility. Default: false for floating, true for fixed */\n visible?: boolean;\n /** Automatically hide when touch is released. Default: true for floating, false for fixed */\n autoHide?: boolean;\n}\n\n/**\n * On-screen touch joystick with deadzone, normalized 2D direction, and clamped magnitude.\n */\nexport class VirtualJoystick {\n /** Center origin of the joystick base in canvas coordinates */\n public readonly basePosition: Vector2 = new Vector2(0, 0);\n\n /** Current position of the draggable thumbstick handle */\n public readonly stickPosition: Vector2 = new Vector2(0, 0);\n\n /** Normalized 2D direction vector scaled by deadzone-adjusted magnitude in [-1, 1] */\n public readonly value: Vector2 = new Vector2(0, 0);\n\n /** Pure unit direction vector (length 1.0 or (0,0) within deadzone) */\n public readonly direction: Vector2 = new Vector2(0, 0);\n\n /** Clamped and deadzone-adjusted scalar magnitude in [0, 1] */\n public magnitude: number = 0;\n\n /** Maximum physical displacement radius */\n public radius: number = 60;\n\n /** Normalized deadzone threshold */\n public deadzone: number = 0.15;\n\n /** Operational mode ('fixed' or 'floating') */\n public mode: VirtualJoystickMode = 'floating';\n\n /** Whether the joystick automatically hides on release */\n public autoHide: boolean = true;\n\n /** Whether the joystick is currently visible */\n public visible: boolean = false;\n\n /** Whether a finger/pointer is actively dragging the joystick */\n public isActive: boolean = false;\n\n /** Pointer/touch identifier currently controlling the joystick */\n public activeTouchId: number | null = null;\n\n /** Optional touch activation zone */\n public touchArea: Rect | null = null;\n\n constructor(options: VirtualJoystickOptions = {}) {\n this.mode = options.mode ?? 'floating';\n this.radius = options.radius ?? 60;\n this.deadzone = options.deadzone ?? 0.15;\n this.touchArea = options.touchArea ?? null;\n this.autoHide = options.autoHide ?? (this.mode === 'floating');\n this.visible = options.visible ?? (this.mode === 'fixed');\n\n if (options.basePosition) {\n this.basePosition.copy(options.basePosition);\n } else if (this.mode === 'fixed') {\n this.basePosition.set(120, 480);\n }\n this.stickPosition.copy(this.basePosition);\n }\n\n /**\n * Handle touch start / pointer down.\n * Returns true if this joystick claimed the touch.\n */\n public handleTouchStart(id: number, pos: Vector2): boolean {\n if (this.isActive) return false;\n\n // Check touch area constraint if provided\n if (this.touchArea && !this.touchArea.containsPoint(pos)) {\n return false;\n }\n\n if (this.mode === 'floating') {\n this.basePosition.copy(pos);\n this.stickPosition.copy(pos);\n this.visible = true;\n } else {\n // In fixed mode, accept touch within radius * 1.5 of base if no explicit touchArea\n const dist = pos.distanceTo(this.basePosition);\n if (dist > this.radius * 1.5 && !this.touchArea) {\n return false;\n }\n this._updateStick(pos);\n }\n\n this.isActive = true;\n this.activeTouchId = id;\n return true;\n }\n\n /**\n * Handle touch move / pointer move.\n * Returns true if this touch belonged to the joystick.\n */\n public handleTouchMove(id: number, pos: Vector2): boolean {\n if (!this.isActive || this.activeTouchId !== id) return false;\n this._updateStick(pos);\n return true;\n }\n\n /**\n * Handle touch end / pointer up.\n * Returns true if this touch belonged to the joystick.\n */\n public handleTouchEnd(id: number): boolean {\n if (!this.isActive || this.activeTouchId !== id) return false;\n\n this.isActive = false;\n this.activeTouchId = null;\n this.stickPosition.copy(this.basePosition);\n this.value.set(0, 0);\n this.direction.set(0, 0);\n this.magnitude = 0;\n\n if (this.autoHide) {\n this.visible = false;\n }\n return true;\n }\n\n /**\n * Internal kinematic calculation: clamp stick, apply deadzone, compute direction & magnitude.\n */\n private _updateStick(pos: Vector2): void {\n const dx = pos.x - this.basePosition.x;\n const dy = pos.y - this.basePosition.y;\n const dist = Math.sqrt(dx * dx + dy * dy);\n\n // Clamp stick position to outer circle\n if (dist <= this.radius) {\n this.stickPosition.copy(pos);\n } else {\n const invDist = 1 / dist;\n this.stickPosition.set(\n this.basePosition.x + dx * invDist * this.radius,\n this.basePosition.y + dy * invDist * this.radius\n );\n }\n\n // Deadzone and normalized magnitude calculation\n const rawMagnitude = Math.min(dist / this.radius, 1.0);\n\n if (rawMagnitude <= this.deadzone || dist === 0) {\n this.value.set(0, 0);\n this.direction.set(0, 0);\n this.magnitude = 0;\n } else {\n const invDist = 1 / dist;\n const dirX = dx * invDist;\n const dirY = dy * invDist;\n const adjustedMag = (rawMagnitude - this.deadzone) / (1 - this.deadzone);\n\n this.direction.set(dirX, dirY);\n this.magnitude = adjustedMag;\n this.value.set(dirX * adjustedMag, dirY * adjustedMag);\n }\n }\n\n /**\n * Optional Canvas2D debug rendering helper.\n */\n public render(context: CanvasRenderingContext2D | any): void {\n if (!this.visible) return;\n\n const ctx = context instanceof CanvasContext ? context.rawContext : context;\n ctx.save();\n\n // Base circle\n ctx.beginPath();\n ctx.arc(this.basePosition.x, this.basePosition.y, this.radius, 0, Math.PI * 2);\n ctx.fillStyle = 'rgba(255, 255, 255, 0.15)';\n ctx.fill();\n ctx.lineWidth = 2;\n ctx.strokeStyle = 'rgba(255, 255, 255, 0.4)';\n ctx.stroke();\n\n // Stick handle\n const handleRadius = this.radius * 0.4;\n ctx.beginPath();\n ctx.arc(this.stickPosition.x, this.stickPosition.y, handleRadius, 0, Math.PI * 2);\n ctx.fillStyle = 'rgba(255, 255, 255, 0.5)';\n ctx.fill();\n ctx.lineWidth = 2;\n ctx.strokeStyle = '#ffffff';\n ctx.stroke();\n\n ctx.restore();\n }\n\n /**\n * Reset joystick to initial neutral state.\n */\n public reset(): void {\n this.isActive = false;\n this.activeTouchId = null;\n this.stickPosition.copy(this.basePosition);\n this.value.set(0, 0);\n this.direction.set(0, 0);\n this.magnitude = 0;\n if (this.autoHide) {\n this.visible = false;\n }\n }\n}\n","import { Vector2 } from '../math/Vector2';\nimport type { InputManager } from './InputManager';\n\nexport interface Axis1DConfig {\n /** Input code(s) that increase value towards +1.0 */\n positive: string | string[];\n /** Input code(s) that decrease value towards -1.0 */\n negative: string | string[];\n}\n\nexport interface Axis2DConfig {\n /** Input code(s) moving Up (Screen Y: -1) */\n up: string | string[];\n /** Input code(s) moving Down (Screen Y: +1) */\n down: string | string[];\n /** Input code(s) moving Left (Screen X: -1) */\n left: string | string[];\n /** Input code(s) moving Right (Screen X: +1) */\n right: string | string[];\n /** Whether to blend/incorporate VirtualJoystick input. Default: true */\n useJoystick?: boolean;\n /** Whether to normalize diagonal vector to length <= 1.0. Default: true */\n normalize?: boolean;\n}\n\nexport interface SerializedActionMap {\n actions: Record<string, string[]>;\n axes1D: Record<string, Axis1DConfig>;\n axes2D: Record<string, Axis2DConfig>;\n}\n\n/**\n * Maps semantic actions and 1D/2D composite axes to physical keys, mouse buttons, and joystick.\n */\nexport class ActionMap {\n private _input: InputManager;\n private _actions: Map<string, string[]> = new Map();\n private _axes1D: Map<string, Axis1DConfig> = new Map();\n private _axes2D: Map<string, Axis2DConfig> = new Map();\n\n // Reusable scratchpad vector for zero-allocation getVector() queries\n private _scratchVector: Vector2 = new Vector2(0, 0);\n\n constructor(input: InputManager) {\n this._input = input;\n }\n\n // ==========================================\n // Digital Action Mappings\n // ==========================================\n\n /**\n * Bind a semantic action to one or more physical input codes.\n */\n public bindAction(action: string, ...inputs: string[]): this {\n let list = this._actions.get(action);\n if (!list) {\n list = [];\n this._actions.set(action, list);\n }\n for (const input of inputs) {\n if (!list.includes(input)) {\n list.push(input);\n }\n }\n return this;\n }\n\n /**\n * Unbind an input code from an action, or unbind the entire action if input is omitted.\n */\n public unbindAction(action: string, input?: string): this {\n if (!input) {\n this._actions.delete(action);\n return this;\n }\n const list = this._actions.get(action);\n if (list) {\n const idx = list.indexOf(input);\n if (idx !== -1) list.splice(idx, 1);\n if (list.length === 0) this._actions.delete(action);\n }\n return this;\n }\n\n /**\n * Check if any input bound to this action is currently held down.\n */\n public isDown(action: string): boolean {\n const list = this._actions.get(action);\n if (!list) return false;\n for (let i = 0; i < list.length; i++) {\n if (this._isInputDown(list[i])) return true;\n }\n return false;\n }\n\n /**\n * Check if any input bound to this action was just pressed this frame tick.\n */\n public isJustPressed(action: string): boolean {\n const list = this._actions.get(action);\n if (!list) return false;\n for (let i = 0; i < list.length; i++) {\n if (this._isInputJustPressed(list[i])) return true;\n }\n return false;\n }\n\n /**\n * Check if any input bound to this action was just released this frame tick.\n */\n public isJustReleased(action: string): boolean {\n const list = this._actions.get(action);\n if (!list) return false;\n let released = false;\n for (let i = 0; i < list.length; i++) {\n if (this._isInputJustReleased(list[i])) {\n released = true;\n }\n }\n // Only true if released and no alternative bound key is still down\n return released && !this.isDown(action);\n }\n\n // ==========================================\n // 1D Composite Axis Mappings\n // ==========================================\n\n /**\n * Bind a 1D scalar axis (e.g. 'horizontal') with positive and negative inputs.\n */\n public bindAxis1D(name: string, config: Axis1DConfig): this {\n this._axes1D.set(name, {\n positive: Array.isArray(config.positive) ? [...config.positive] : [config.positive],\n negative: Array.isArray(config.negative) ? [...config.negative] : [config.negative]\n });\n return this;\n }\n\n /**\n * Unbind a 1D axis.\n */\n public unbindAxis1D(name: string): this {\n this._axes1D.delete(name);\n return this;\n }\n\n /**\n * Get 1D axis value in range [-1.0, 1.0].\n */\n public getAxis(name: string): number {\n const config = this._axes1D.get(name);\n if (!config) return 0;\n\n let pos = 0;\n let neg = 0;\n\n const posList = Array.isArray(config.positive) ? config.positive : [config.positive];\n for (let i = 0; i < posList.length; i++) {\n if (this._isInputDown(posList[i])) {\n pos = 1;\n break;\n }\n }\n\n const negList = Array.isArray(config.negative) ? config.negative : [config.negative];\n for (let i = 0; i < negList.length; i++) {\n if (this._isInputDown(negList[i])) {\n neg = 1;\n break;\n }\n }\n\n return pos - neg;\n }\n\n // ==========================================\n // 2D Composite Axis Mappings\n // ==========================================\n\n /**\n * Bind a 2D vector axis (e.g. 'move') with directional inputs and joystick blending.\n */\n public bindAxis2D(name: string, config: Axis2DConfig): this {\n this._axes2D.set(name, {\n up: Array.isArray(config.up) ? [...config.up] : [config.up],\n down: Array.isArray(config.down) ? [...config.down] : [config.down],\n left: Array.isArray(config.left) ? [...config.left] : [config.left],\n right: Array.isArray(config.right) ? [...config.right] : [config.right],\n useJoystick: config.useJoystick ?? true,\n normalize: config.normalize ?? true\n });\n return this;\n }\n\n /**\n * Unbind a 2D axis.\n */\n public unbindAxis2D(name: string): this {\n this._axes2D.delete(name);\n return this;\n }\n\n /**\n * Get 2D direction vector with optional diagonal normalization and joystick blending.\n * @param name Name of the 2D axis.\n * @param out Optional Vector2 destination to prevent allocations.\n */\n public getVector(name: string, out?: Vector2): Vector2 {\n const dest = out ?? this._scratchVector;\n dest.set(0, 0);\n\n const config = this._axes2D.get(name);\n if (!config) return dest;\n\n let up = false;\n let down = false;\n let left = false;\n let right = false;\n\n for (const code of config.up) if (this._isInputDown(code)) { up = true; break; }\n for (const code of config.down) if (this._isInputDown(code)) { down = true; break; }\n for (const code of config.left) if (this._isInputDown(code)) { left = true; break; }\n for (const code of config.right) if (this._isInputDown(code)) { right = true; break; }\n\n let kx = (right ? 1 : 0) - (left ? 1 : 0);\n // In Canvas space, Up is -1 and Down is +1\n let ky = (down ? 1 : 0) - (up ? 1 : 0);\n\n // If virtual joystick is active and enabled, incorporate it\n if (config.useJoystick && this._input.joystick.isActive && this._input.joystick.magnitude > 0) {\n const jx = this._input.joystick.value.x;\n const jy = this._input.joystick.value.y;\n\n if (kx === 0 && ky === 0) {\n dest.set(jx, jy);\n return dest;\n }\n // Combine digital and analog input\n kx += jx;\n ky += jy;\n }\n\n dest.set(kx, ky);\n\n // Diagonal normalization to avoid faster diagonal movement\n if (config.normalize && dest.lengthSq() > 1.0) {\n dest.normalizeInPlace();\n }\n\n return dest;\n }\n\n // ==========================================\n // Serialization & Helper Parsers\n // ==========================================\n\n public toJSON(): SerializedActionMap {\n const actions: Record<string, string[]> = {};\n for (const [k, v] of this._actions) actions[k] = [...v];\n\n const axes1D: Record<string, Axis1DConfig> = {};\n for (const [k, v] of this._axes1D) axes1D[k] = { ...v };\n\n const axes2D: Record<string, Axis2DConfig> = {};\n for (const [k, v] of this._axes2D) axes2D[k] = { ...v };\n\n return { actions, axes1D, axes2D };\n }\n\n public fromJSON(data: SerializedActionMap): this {\n if (data.actions) {\n this._actions.clear();\n for (const [k, v] of Object.entries(data.actions)) {\n this._actions.set(k, [...v]);\n }\n }\n if (data.axes1D) {\n this._axes1D.clear();\n for (const [k, v] of Object.entries(data.axes1D)) {\n this.bindAxis1D(k, v);\n }\n }\n if (data.axes2D) {\n this._axes2D.clear();\n for (const [k, v] of Object.entries(data.axes2D)) {\n this.bindAxis2D(k, v);\n }\n }\n return this;\n }\n\n private _isInputDown(binding: string): boolean {\n if (binding.startsWith('mouse:') || binding.startsWith('pointer:')) {\n const btn = this._parseMouseButton(binding);\n return this._input.pointer.isDown(btn);\n }\n return this._input.isDown(binding);\n }\n\n private _isInputJustPressed(binding: string): boolean {\n if (binding.startsWith('mouse:') || binding.startsWith('pointer:')) {\n const btn = this._parseMouseButton(binding);\n return this._input.pointer.isJustPressed(btn);\n }\n return this._input.isJustPressed(binding);\n }\n\n private _isInputJustReleased(binding: string): boolean {\n if (binding.startsWith('mouse:') || binding.startsWith('pointer:')) {\n const btn = this._parseMouseButton(binding);\n return this._input.pointer.isJustReleased(btn);\n }\n return this._input.isJustReleased(binding);\n }\n\n private _parseMouseButton(binding: string): number {\n const name = binding.split(':')[1]?.toLowerCase();\n switch (name) {\n case 'left':\n case 'primary':\n case '0':\n return 0;\n case 'middle':\n case '1':\n return 1;\n case 'right':\n case 'secondary':\n case '2':\n return 2;\n default:\n return 0;\n }\n }\n}\n","import { Pointer } from './Pointer';\nimport { VirtualJoystick, type VirtualJoystickOptions } from './VirtualJoystick';\nimport { ActionMap } from './ActionMap';\nimport { Vector2 } from '../math/Vector2';\n\nexport interface InputConfig {\n /** DOM element to listen to for pointer/mouse/touch events. Defaults to null (headless safe) */\n target?: HTMLElement | any;\n /** Keys whose default browser behavior should be prevented (e.g. Space, Arrow keys) */\n preventDefaultKeys?: string[];\n /** Prevent default context menu on right click. Default: true */\n preventContextMenu?: boolean;\n}\n\nexport interface TouchData {\n id: number;\n canvasPosition: Vector2;\n screenPosition: Vector2;\n}\n\n/**\n * Normalizes keyboard codes and common case-insensitive indie developer aliases.\n */\nexport function normalizeKeyCode(code: string): string {\n if (!code) return '';\n const lower = code.toLowerCase();\n\n // Single letter shortcuts: 'w' -> 'KeyW'\n if (lower.length === 1 && lower >= 'a' && lower <= 'z') {\n return 'Key' + lower.toUpperCase();\n }\n // Single digit shortcuts: '1' -> 'Digit1'\n if (lower.length === 1 && lower >= '0' && lower <= '9') {\n return 'Digit' + lower;\n }\n\n switch (lower) {\n case 'space':\n case 'spacebar':\n return 'Space';\n case 'enter':\n case 'return':\n return 'Enter';\n case 'esc':\n case 'escape':\n return 'Escape';\n case 'shift':\n return 'ShiftLeft';\n case 'ctrl':\n case 'control':\n return 'ControlLeft';\n case 'alt':\n return 'AltLeft';\n case 'tab':\n return 'Tab';\n case 'backspace':\n return 'Backspace';\n case 'up':\n case 'arrowup':\n return 'ArrowUp';\n case 'down':\n case 'arrowdown':\n return 'ArrowDown';\n case 'left':\n case 'arrowleft':\n return 'ArrowLeft';\n case 'right':\n case 'arrowright':\n return 'ArrowRight';\n default:\n return code;\n }\n}\n\n/**\n * Production-grade Unified Input Subsystem.\n * Manages keyboard, pointer, multi-touch, virtual joystick, and semantic action mapping\n * with frame-synchronized buffers and headless simulation capabilities.\n */\nexport class InputManager {\n public readonly pointer: Pointer;\n public readonly joystick: VirtualJoystick;\n public readonly actions: ActionMap;\n\n private _target: HTMLElement | any = null;\n private _preventDefaultKeys: Set<string>;\n private _preventContextMenu: boolean;\n\n // Active frame keyboard states\n private _downKeys: Set<string> = new Set();\n private _justPressedKeys: Set<string> = new Set();\n private _justReleasedKeys: Set<string> = new Set();\n\n // Pending keyboard events from asynchronous DOM thread in chronological sequence\n private _pendingKeyEvents: Array<{ type: 'down' | 'up'; code: string }> = [];\n\n // Multi-touch tracking\n private _touches: Map<number, TouchData> = new Map();\n\n // Bound listener references for clean detachment\n private _boundKeyDown: ((e: KeyboardEvent) => void) | null = null;\n private _boundKeyUp: ((e: KeyboardEvent) => void) | null = null;\n private _boundPointerDown: ((e: PointerEvent) => void) | null = null;\n private _boundPointerMove: ((e: PointerEvent) => void) | null = null;\n private _boundPointerUp: ((e: PointerEvent) => void) | null = null;\n private _boundPointerCancel: ((e: PointerEvent) => void) | null = null;\n private _boundWheel: ((e: WheelEvent) => void) | null = null;\n private _boundContextMenu: ((e: MouseEvent) => void) | null = null;\n private _boundBlur: (() => void) | null = null;\n private _isAttached: boolean = false;\n\n constructor(config: InputConfig | HTMLElement | any = {}) {\n const opts = (typeof HTMLElement !== 'undefined' && config instanceof HTMLElement)\n ? { target: config }\n : config;\n\n this.pointer = new Pointer();\n this.joystick = new VirtualJoystick();\n this.actions = new ActionMap(this);\n\n this._preventDefaultKeys = new Set(\n opts.preventDefaultKeys ?? ['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight', 'Space', 'Tab']\n );\n this._preventContextMenu = opts.preventContextMenu ?? true;\n\n if (opts.target) {\n this.attach(opts.target);\n }\n }\n\n // ==========================================\n // Lifecycle & Listener Attachment\n // ==========================================\n\n /**\n * Attach DOM event listeners to a canvas or window target.\n * Safe to call in browser environments; no-op in headless Node.js.\n */\n public attach(target?: HTMLElement | any): void {\n if (this._isAttached) this.detach();\n\n this._target = target ?? (typeof document !== 'undefined' ? document.body : null);\n if (!this._target && typeof window === 'undefined') return;\n\n this._boundKeyDown = (e: KeyboardEvent) => {\n const code = e.code || e.key;\n if (this._preventDefaultKeys.has(code) || this._preventDefaultKeys.has(e.code)) {\n if (typeof e.preventDefault === 'function') {\n e.preventDefault();\n }\n }\n this._pendingKeyEvents.push({ type: 'down', code });\n };\n\n this._boundKeyUp = (e: KeyboardEvent) => {\n const code = e.code || e.key;\n this._pendingKeyEvents.push({ type: 'up', code });\n };\n\n this._boundPointerDown = (e: PointerEvent) => {\n this.pointer.updatePositions(e.clientX, e.clientY, this._target);\n this.pointer.pointerType = (e.pointerType as 'mouse' | 'touch' | 'pen') || 'mouse';\n this.pointer.pointerId = e.pointerId;\n this.pointer.isInside = true;\n this.pointer.recordDown(e.button);\n\n if (e.pointerType === 'touch') {\n this._touches.set(e.pointerId, {\n id: e.pointerId,\n screenPosition: new Vector2(e.clientX, e.clientY),\n canvasPosition: this.pointer.canvasPosition.clone()\n });\n this.joystick.handleTouchStart(e.pointerId, this.pointer.canvasPosition);\n }\n };\n\n this._boundPointerMove = (e: PointerEvent) => {\n this.pointer.updatePositions(e.clientX, e.clientY, this._target);\n this.pointer.isInside = true;\n\n if (e.pointerType === 'touch') {\n const touch = this._touches.get(e.pointerId);\n if (touch) {\n touch.screenPosition.set(e.clientX, e.clientY);\n touch.canvasPosition.copy(this.pointer.canvasPosition);\n }\n this.joystick.handleTouchMove(e.pointerId, this.pointer.canvasPosition);\n }\n };\n\n this._boundPointerUp = (e: PointerEvent) => {\n this.pointer.updatePositions(e.clientX, e.clientY, this._target);\n this.pointer.recordUp(e.button);\n\n if (e.pointerType === 'touch') {\n this._touches.delete(e.pointerId);\n this.joystick.handleTouchEnd(e.pointerId);\n }\n };\n\n this._boundPointerCancel = (e: PointerEvent) => {\n this.pointer.recordUp(e.button);\n if (e.pointerType === 'touch') {\n this._touches.delete(e.pointerId);\n this.joystick.handleTouchEnd(e.pointerId);\n }\n };\n\n this._boundWheel = (e: WheelEvent) => {\n this.pointer.recordWheel(e.deltaX, e.deltaY);\n };\n\n this._boundContextMenu = (e: MouseEvent) => {\n if (this._preventContextMenu && typeof e.preventDefault === 'function') {\n e.preventDefault();\n }\n };\n\n this._boundBlur = () => {\n this.reset();\n };\n\n if (typeof window !== 'undefined') {\n window.addEventListener('keydown', this._boundKeyDown, { passive: false });\n window.addEventListener('keyup', this._boundKeyUp, { passive: false });\n window.addEventListener('blur', this._boundBlur);\n }\n\n if (this._target && typeof this._target.addEventListener === 'function') {\n this._target.addEventListener('pointerdown', this._boundPointerDown);\n this._target.addEventListener('pointermove', this._boundPointerMove);\n this._target.addEventListener('pointerup', this._boundPointerUp);\n this._target.addEventListener('pointercancel', this._boundPointerCancel);\n this._target.addEventListener('wheel', this._boundWheel, { passive: false });\n this._target.addEventListener('contextmenu', this._boundContextMenu);\n }\n\n this._isAttached = true;\n }\n\n /**\n * Detach all event listeners and unregister from DOM.\n */\n public detach(): void {\n if (!this._isAttached) return;\n\n if (typeof window !== 'undefined') {\n if (this._boundKeyDown) window.removeEventListener('keydown', this._boundKeyDown);\n if (this._boundKeyUp) window.removeEventListener('keyup', this._boundKeyUp);\n if (this._boundBlur) window.removeEventListener('blur', this._boundBlur);\n }\n\n if (this._target && typeof this._target.removeEventListener === 'function') {\n if (this._boundPointerDown) this._target.removeEventListener('pointerdown', this._boundPointerDown);\n if (this._boundPointerMove) this._target.removeEventListener('pointermove', this._boundPointerMove);\n if (this._boundPointerUp) this._target.removeEventListener('pointerup', this._boundPointerUp);\n if (this._boundPointerCancel) this._target.removeEventListener('pointercancel', this._boundPointerCancel);\n if (this._boundWheel) this._target.removeEventListener('wheel', this._boundWheel);\n if (this._boundContextMenu) this._target.removeEventListener('contextmenu', this._boundContextMenu);\n }\n\n this._isAttached = false;\n }\n\n // ==========================================\n // Frame Update Lifecycle\n // ==========================================\n\n /**\n * Called at the start of each frame tick before scene update.\n * Flushes pending asynchronous DOM events into active frame state.\n */\n public update(): void {\n this._justPressedKeys.clear();\n this._justReleasedKeys.clear();\n\n // Commit pending events in exact chronological arrival sequence\n for (let i = 0; i < this._pendingKeyEvents.length; i++) {\n const evt = this._pendingKeyEvents[i];\n const norm = normalizeKeyCode(evt.code);\n\n if (evt.type === 'down') {\n if (!this._downKeys.has(norm)) {\n this._justPressedKeys.add(norm);\n }\n this._downKeys.add(norm);\n } else if (evt.type === 'up') {\n if (this._downKeys.has(norm) || this._justPressedKeys.has(norm)) {\n this._justReleasedKeys.add(norm);\n }\n this._downKeys.delete(norm);\n }\n }\n this._pendingKeyEvents.length = 0;\n\n // Update child subsystems\n this.pointer.update();\n }\n\n /**\n * Called at the end of each frame tick after rendering.\n * Clears transitions, resets click consumption and wheel deltas.\n */\n public lateUpdate(): void {\n this._justPressedKeys.clear();\n this._justReleasedKeys.clear();\n this.pointer.lateUpdate();\n }\n\n // ==========================================\n // Keyboard Queries\n // ==========================================\n\n /**\n * Returns true if the key is currently held down.\n */\n public isDown(code: string): boolean {\n return this._downKeys.has(normalizeKeyCode(code));\n }\n\n /**\n * Returns true if the key was pressed this frame tick.\n */\n public isJustPressed(code: string): boolean {\n return this._justPressedKeys.has(normalizeKeyCode(code));\n }\n\n /**\n * Returns true if the key was released this frame tick.\n */\n public isJustReleased(code: string): boolean {\n return this._justReleasedKeys.has(normalizeKeyCode(code));\n }\n\n /**\n * Reset all keys, pointers, touches, and buffers.\n */\n public reset(): void {\n this._downKeys.clear();\n this._justPressedKeys.clear();\n this._justReleasedKeys.clear();\n this._pendingKeyEvents.length = 0;\n this._touches.clear();\n this.pointer.reset();\n this.joystick.reset();\n }\n\n // ==========================================\n // Headless Simulation API (For Automated Tests)\n // ==========================================\n\n public simulateKeyDown(code: string): void {\n this._pendingKeyEvents.push({ type: 'down', code });\n }\n\n public simulateKeyUp(code: string): void {\n this._pendingKeyEvents.push({ type: 'up', code });\n }\n\n public simulateKeyPress(code: string): void {\n this._pendingKeyEvents.push({ type: 'down', code });\n this._pendingKeyEvents.push({ type: 'up', code });\n }\n\n public simulatePointerDown(canvasX: number, canvasY: number, button: number = 0): void {\n this.pointer.screenPosition.set(canvasX, canvasY);\n this.pointer.canvasPosition.set(canvasX, canvasY);\n this.pointer.recordDown(button);\n }\n\n public simulatePointerUp(canvasX: number, canvasY: number, button: number = 0): void {\n this.pointer.screenPosition.set(canvasX, canvasY);\n this.pointer.canvasPosition.set(canvasX, canvasY);\n this.pointer.recordUp(button);\n }\n\n public simulatePointerMove(canvasX: number, canvasY: number): void {\n this.pointer.screenPosition.set(canvasX, canvasY);\n this.pointer.canvasPosition.set(canvasX, canvasY);\n }\n\n public simulateWheel(deltaX: number, deltaY: number): void {\n this.pointer.recordWheel(deltaX, deltaY);\n }\n\n public simulateTouchStart(id: number, canvasX: number, canvasY: number): void {\n const pos = new Vector2(canvasX, canvasY);\n this._touches.set(id, {\n id,\n canvasPosition: pos.clone(),\n screenPosition: pos.clone()\n });\n this.simulatePointerDown(canvasX, canvasY, 0);\n this.joystick.handleTouchStart(id, pos);\n }\n\n public simulateTouchMove(id: number, canvasX: number, canvasY: number): void {\n const pos = new Vector2(canvasX, canvasY);\n const touch = this._touches.get(id);\n if (touch) {\n touch.canvasPosition.copy(pos);\n touch.screenPosition.copy(pos);\n }\n this.simulatePointerMove(canvasX, canvasY);\n this.joystick.handleTouchMove(id, pos);\n }\n\n public simulateTouchEnd(id: number): void {\n this._touches.delete(id);\n this.simulatePointerUp(this.pointer.canvasPosition.x, this.pointer.canvasPosition.y, 0);\n this.joystick.handleTouchEnd(id);\n }\n\n public simulateBlur(): void {\n this.reset();\n }\n\n /**\n * Configure on-screen virtual joystick.\n */\n public setupVirtualJoystick(options?: VirtualJoystickOptions): void {\n if (options) {\n if (options.mode !== undefined) this.joystick.mode = options.mode;\n if (options.radius !== undefined) this.joystick.radius = options.radius;\n if (options.deadzone !== undefined) this.joystick.deadzone = options.deadzone;\n if (options.touchArea !== undefined) this.joystick.touchArea = options.touchArea;\n if (options.autoHide !== undefined) this.joystick.autoHide = options.autoHide;\n if (options.visible !== undefined) this.joystick.visible = options.visible;\n if (options.basePosition) this.joystick.basePosition.copy(options.basePosition);\n this.joystick.reset();\n }\n }\n\n public destroy(): void {\n this.detach();\n this.reset();\n }\n}\n","import { Vector2 } from '../math/Vector2';\nimport { MathUtils } from '../math/MathUtils';\nimport { Transform2D } from '../math/Transform2D';\n\nexport enum BodyType {\n Dynamic = 'dynamic',\n Static = 'static',\n Kinematic = 'kinematic'\n}\n\nexport interface RigidBodyConfig {\n bodyType?: BodyType;\n position?: Vector2;\n velocity?: Vector2;\n acceleration?: Vector2;\n rotation?: number;\n angularVelocity?: number;\n mass?: number;\n inertia?: number;\n fixedRotation?: boolean;\n linearDamping?: number;\n angularDamping?: number;\n gravityScale?: number;\n restitution?: number;\n friction?: number;\n isBullet?: boolean;\n canSleep?: boolean;\n}\n\n/**\n * Production-grade 2D RigidBody implementing Symplectic Euler integration,\n * accurate inertia tensor calculation, force/impulse APIs, and Transform2D sync.\n */\nexport class RigidBody2D {\n private static _nextId: number = 1;\n public readonly id: number;\n\n public bodyType: BodyType;\n\n // Linear motion state\n public readonly position: Vector2;\n public readonly velocity: Vector2;\n public readonly acceleration: Vector2;\n public readonly force: Vector2;\n\n // Angular motion state\n public rotation: number; // in radians\n public angularVelocity: number; // in rad/s\n public torque: number;\n\n // Physical mass properties\n private _mass: number = 1.0;\n private _invMass: number = 1.0;\n private _inertia: number = 1.0;\n private _invInertia: number = 1.0;\n public fixedRotation: boolean = false;\n\n // Material and simulation settings\n public linearDamping: number = 0.0;\n public angularDamping: number = 0.0;\n public gravityScale: number = 1.0;\n public restitution: number = 0.0;\n public friction: number = 0.5;\n\n // Sleep & CCD guards\n public isBullet: boolean = false;\n public isSleeping: boolean = false;\n public canSleep: boolean = true;\n public sleepTimer: number = 0;\n\n public static linearSleepTolerance: number = 2.0; // px/s\n public static angularSleepTolerance: number = 0.05; // rad/s\n public static timeToSleep: number = 0.5; // seconds\n\n // Scene graph synchronization\n public transform: Transform2D | null = null;\n public userData: any = null;\n\n // Collision and trigger callbacks\n public onCollisionEnter?: (\n other: RigidBody2D | null,\n myCollider: any,\n otherCollider: any,\n manifold: any\n ) => void;\n public onCollisionStay?: (\n other: RigidBody2D | null,\n myCollider: any,\n otherCollider: any,\n manifold: any\n ) => void;\n public onCollisionExit?: (\n other: RigidBody2D | null,\n myCollider: any,\n otherCollider: any\n ) => void;\n public onTriggerEnter?: (\n other: RigidBody2D | null,\n myCollider: any,\n otherCollider: any\n ) => void;\n public onTriggerStay?: (\n other: RigidBody2D | null,\n myCollider: any,\n otherCollider: any\n ) => void;\n public onTriggerExit?: (\n other: RigidBody2D | null,\n myCollider: any,\n otherCollider: any\n ) => void;\n\n public hasCustomInertia: boolean = false;\n\n constructor(config: RigidBodyConfig = {}) {\n this.id = RigidBody2D._nextId++;\n this.bodyType = config.bodyType ?? BodyType.Dynamic;\n\n this.position = config.position ? config.position.clone() : new Vector2(0, 0);\n this.velocity = config.velocity ? config.velocity.clone() : new Vector2(0, 0);\n this.acceleration = config.acceleration ? config.acceleration.clone() : new Vector2(0, 0);\n this.force = new Vector2(0, 0);\n\n this.rotation = config.rotation ?? 0;\n this.angularVelocity = config.angularVelocity ?? 0;\n this.torque = 0;\n\n this.fixedRotation = config.fixedRotation ?? false;\n this.linearDamping = config.linearDamping ?? 0.0;\n this.angularDamping = config.angularDamping ?? 0.0;\n this.gravityScale = config.gravityScale ?? 1.0;\n this.restitution = config.restitution ?? 0.0;\n this.friction = config.friction ?? 0.5;\n this.isBullet = config.isBullet ?? false;\n this.canSleep = config.canSleep ?? true;\n\n if (config.mass !== undefined && config.inertia !== undefined) {\n this.setMassAndInertia(config.mass, config.inertia);\n this.hasCustomInertia = true;\n } else if (config.mass !== undefined) {\n this.setMass(config.mass);\n } else {\n this.setMass(1.0);\n }\n\n if (config.inertia !== undefined) {\n this.setInertia(config.inertia);\n this.hasCustomInertia = true;\n }\n }\n\n // ==========================================\n // Mass & Inertia Getters / Setters\n // ==========================================\n\n public get mass(): number {\n return this._mass;\n }\n\n public get invMass(): number {\n if (this.bodyType === BodyType.Static || this.bodyType === BodyType.Kinematic) {\n return 0;\n }\n return this._invMass;\n }\n\n public get inertia(): number {\n return this._inertia;\n }\n\n public get invInertia(): number {\n if (\n this.bodyType === BodyType.Static ||\n this.bodyType === BodyType.Kinematic ||\n this.fixedRotation\n ) {\n return 0;\n }\n return this._invInertia;\n }\n\n public setMass(mass: number): this {\n if (mass <= 0) {\n this._mass = 0;\n this._invMass = 0;\n this._inertia = 0;\n this._invInertia = 0;\n this.bodyType = BodyType.Static;\n } else {\n this._mass = mass;\n this._invMass = 1.0 / mass;\n }\n this.wakeUp();\n return this;\n }\n\n public setInertia(inertia: number): this {\n this.hasCustomInertia = true;\n if (inertia <= 0) {\n this._inertia = 0;\n this._invInertia = 0;\n } else {\n this._inertia = inertia;\n this._invInertia = 1.0 / inertia;\n }\n this.wakeUp();\n return this;\n }\n\n public setMassAndInertia(mass: number, inertia: number): this {\n this.setMass(mass);\n this.setInertia(inertia);\n return this;\n }\n\n /**\n * Helper to configure moment of inertia for uniform circular disk:\n * I = 0.5 * M * R^2 + M * d^2 (Parallel Axis Theorem)\n */\n public setCircleMass(mass: number, radius: number, offset?: Vector2): this {\n this.setMass(mass);\n const dSq = offset ? offset.lengthSq() : 0;\n const inertia = 0.5 * mass * radius * radius + mass * dSq;\n this.setInertia(inertia);\n return this;\n }\n\n /**\n * Helper to configure moment of inertia for uniform box:\n * I = (1/12) * M * (W^2 + H^2) + M * d^2 (Parallel Axis Theorem)\n */\n public setBoxMass(mass: number, width: number, height: number, offset?: Vector2): this {\n this.setMass(mass);\n const dSq = offset ? offset.lengthSq() : 0;\n const inertia = (1 / 12) * mass * (width * width + height * height) + mass * dSq;\n this.setInertia(inertia);\n return this;\n }\n\n // ==========================================\n // Force, Torque & Impulse APIs\n // ==========================================\n\n /**\n * Applies continuous linear force (e.g. thruster, wind, attraction).\n * If point is specified (in world space), generates rotational torque via r x F.\n */\n public applyForce(force: Vector2, point?: Vector2): void {\n if (this.bodyType !== BodyType.Dynamic) return;\n this.wakeUp();\n\n this.force.addInPlace(force);\n\n if (point && !this.fixedRotation) {\n const rx = point.x - this.position.x;\n const ry = point.y - this.position.y;\n this.torque += rx * force.y - ry * force.x;\n }\n }\n\n /**\n * Applies instantaneous linear impulse (e.g. jump, explosion, projectile impact).\n * Modifies velocity immediately.\n */\n public applyImpulse(impulse: Vector2, point?: Vector2): void {\n if (this.bodyType !== BodyType.Dynamic) return;\n this.wakeUp();\n\n const invM = this.invMass;\n this.velocity.x += impulse.x * invM;\n this.velocity.y += impulse.y * invM;\n\n if (point && !this.fixedRotation) {\n const rx = point.x - this.position.x;\n const ry = point.y - this.position.y;\n const angularImpulse = rx * impulse.y - ry * impulse.x;\n this.angularVelocity += angularImpulse * this.invInertia;\n }\n }\n\n public applyTorque(torque: number): void {\n if (this.bodyType !== BodyType.Dynamic || this.fixedRotation) return;\n this.wakeUp();\n this.torque += torque;\n }\n\n public applyAngularImpulse(impulse: number): void {\n if (this.bodyType !== BodyType.Dynamic || this.fixedRotation) return;\n this.wakeUp();\n this.angularVelocity += impulse * this.invInertia;\n }\n\n public clearForces(): void {\n this.force.set(0, 0);\n this.torque = 0;\n }\n\n // ==========================================\n // Numerical Integration (Symplectic Euler)\n // ==========================================\n\n /**\n * Phase 1 of Symplectic Euler: Integrate velocities from forces, gravity, and damping.\n * Run BEFORE ContactSolver.\n */\n public integrateVelocities(dt: number, worldGravity: Vector2): void {\n if (this.isSleeping || this.bodyType === BodyType.Static) {\n return;\n }\n\n if (this.bodyType === BodyType.Kinematic) {\n // Kinematic bodies ignore forces and gravity\n return;\n }\n\n // Dynamic Body: v += (a + F/m + g*scale) * dt\n const invM = this.invMass;\n const ax = this.acceleration.x + this.force.x * invM + worldGravity.x * this.gravityScale;\n const ay = this.acceleration.y + this.force.y * invM + worldGravity.y * this.gravityScale;\n\n this.velocity.x += ax * dt;\n this.velocity.y += ay * dt;\n\n if (!this.fixedRotation) {\n const alpha = this.torque * this.invInertia;\n this.angularVelocity += alpha * dt;\n } else {\n this.angularVelocity = 0;\n }\n\n // Damping (exponential decay approximation)\n const linDamp = MathUtils.clamp01(1.0 - this.linearDamping * dt);\n this.velocity.x *= linDamp;\n this.velocity.y *= linDamp;\n\n if (!this.fixedRotation) {\n const angDamp = MathUtils.clamp01(1.0 - this.angularDamping * dt);\n this.angularVelocity *= angDamp;\n }\n }\n\n /**\n * Phase 2 of Symplectic Euler: Provisional position integration from integrated velocities.\n * Run prior to narrowphase collision detection and ContactSolver resolution.\n */\n public integratePositions(dt: number): void {\n if (this.isSleeping || this.bodyType === BodyType.Static) {\n return;\n }\n\n // x += v * dt\n this.position.x += this.velocity.x * dt;\n this.position.y += this.velocity.y * dt;\n\n if (!this.fixedRotation) {\n this.rotation += this.angularVelocity * dt;\n this.rotation = MathUtils.normalizeAngle(this.rotation);\n }\n }\n\n /**\n * Evaluates sleep state machine against post-solver settled velocities.\n * Called at Phase 9 of PhysicsWorld2D._internalSubStep after contact resolution.\n */\n public updateSleep(dt: number): void {\n if (!this.canSleep || this.bodyType !== BodyType.Dynamic || this.isSleeping) {\n return;\n }\n\n const linSpeedSq = this.velocity.lengthSq();\n const angSpeed = Math.abs(this.angularVelocity);\n\n const linTol = RigidBody2D.linearSleepTolerance;\n const angTol = RigidBody2D.angularSleepTolerance;\n\n if (linSpeedSq < linTol * linTol && angSpeed < angTol) {\n this.sleepTimer += dt;\n if (this.sleepTimer >= RigidBody2D.timeToSleep) {\n this.sleep();\n }\n } else {\n this.sleepTimer = 0;\n }\n }\n\n // ==========================================\n // Sleep State Machine\n // ==========================================\n\n public sleep(): void {\n if (!this.canSleep || this.bodyType !== BodyType.Dynamic) return;\n this.isSleeping = true;\n this.velocity.set(0, 0);\n this.angularVelocity = 0;\n this.clearForces();\n }\n\n public wakeUp(): void {\n this.isSleeping = false;\n this.sleepTimer = 0;\n }\n\n // ==========================================\n // Scene Graph Synchronization\n // ==========================================\n\n public syncFromTransform(): void {\n if (this.transform) {\n this.position.copy(this.transform.position);\n this.rotation = this.transform.rotation;\n }\n }\n\n public syncToTransform(): void {\n if (this.transform) {\n this.transform.setPosition(this.position.x, this.position.y);\n this.transform.setRotation(this.rotation);\n }\n }\n}\n","import { Vector2 } from '../math/Vector2';\nimport { MathUtils } from '../math/MathUtils';\nimport { RigidBody2D, BodyType } from './RigidBody2D';\n\nexport interface ContactManifold {\n bodyA: RigidBody2D;\n bodyB: RigidBody2D;\n colliderA?: any;\n colliderB?: any;\n collided: boolean;\n /** Unit contact normal pointing from bodyA towards bodyB */\n normal: Vector2;\n /** Penetration depth (scalar >= 0) */\n penetration: number;\n /** World space contact points (1 for Circle, 1 or 2 for Box edge contacts) */\n contactPoints: Vector2[];\n /** Combined Coulomb friction */\n friction?: number;\n /** Combined restitution */\n restitution?: number;\n}\n\nexport interface SolverConfig {\n velocityIterations?: number;\n positionIterations?: number;\n baumgarte?: number;\n penetrationSlop?: number;\n restitutionVelocityThreshold?: number;\n enableWarmStarting?: boolean;\n}\n\n/** Internal runtime constraint data per contact point */\ninterface ContactConstraintPoint {\n point: Vector2;\n rA: Vector2;\n rB: Vector2;\n normalMass: number;\n tangentMass: number;\n normalImpulse: number;\n tangentImpulse: number;\n velocityBias: number;\n rA_cross_n: number;\n rB_cross_n: number;\n rA_cross_t: number;\n rB_cross_t: number;\n}\n\ninterface ContactConstraint {\n bodyA: RigidBody2D;\n bodyB: RigidBody2D;\n normal: Vector2;\n tangent: Vector2;\n friction: number;\n points: ContactConstraintPoint[];\n}\n\n/**\n * Production-grade Sequential Impulse Contact Solver.\n * Solves normal restitution, Coulomb friction cone, and Baumgarte / position projection.\n */\nexport class ContactSolver {\n public velocityIterations: number;\n public positionIterations: number;\n public baumgarte: number;\n public penetrationSlop: number;\n public restitutionVelocityThreshold: number;\n public enableWarmStarting: boolean;\n\n private _constraints: ContactConstraint[] = [];\n\n constructor(config: SolverConfig = {}) {\n this.velocityIterations = config.velocityIterations ?? 8;\n this.positionIterations = config.positionIterations ?? 3;\n this.baumgarte = config.baumgarte ?? 0.2;\n this.penetrationSlop = config.penetrationSlop ?? 0.02; // pixels\n this.restitutionVelocityThreshold = config.restitutionVelocityThreshold ?? 30.0; // px/s\n this.enableWarmStarting = config.enableWarmStarting ?? false;\n }\n\n /**\n * Prepares constraints from narrowphase manifolds: computes effective masses,\n * Baumgarte velocity bias, restitution bounce targets, and initial warm starting.\n */\n public preStep(manifolds: readonly ContactManifold[], dt: number): void {\n this._constraints = [];\n\n for (let m = 0; m < manifolds.length; m++) {\n const manifold = manifolds[m];\n if (!manifold.collided || manifold.contactPoints.length === 0) continue;\n\n const bodyA = manifold.bodyA;\n const bodyB = manifold.bodyB;\n\n // Both bodies static or sleeping cannot experience impulse\n if (\n (bodyA.bodyType === BodyType.Static || bodyA.isSleeping) &&\n (bodyB.bodyType === BodyType.Static || bodyB.isSleeping)\n ) {\n continue;\n }\n\n // Wake up bodies in active contact\n if (bodyA.isSleeping && bodyB.bodyType !== BodyType.Static) bodyA.wakeUp();\n if (bodyB.isSleeping && bodyA.bodyType !== BodyType.Static) bodyB.wakeUp();\n\n const normal = manifold.normal.clone();\n // Tangent: perpendicular to normal (-ny, nx)\n const tangent = new Vector2(-normal.y, normal.x);\n\n // Material combination\n const combinedFriction =\n manifold.friction ?? Math.sqrt(bodyA.friction * bodyB.friction);\n const combinedRestitution =\n manifold.restitution ?? Math.max(bodyA.restitution, bodyB.restitution);\n\n const invMassA = bodyA.invMass;\n const invMassB = bodyB.invMass;\n const invInertiaA = bodyA.invInertia;\n const invInertiaB = bodyB.invInertia;\n\n const constraintPoints: ContactConstraintPoint[] = [];\n\n for (let p = 0; p < manifold.contactPoints.length; p++) {\n const pt = manifold.contactPoints[p];\n\n const rA = new Vector2(pt.x - bodyA.position.x, pt.y - bodyA.position.y);\n const rB = new Vector2(pt.x - bodyB.position.x, pt.y - bodyB.position.y);\n\n // 2D scalar cross products\n const rA_cross_n = rA.x * normal.y - rA.y * normal.x;\n const rB_cross_n = rB.x * normal.y - rB.y * normal.x;\n const rA_cross_t = rA.x * tangent.y - rA.y * tangent.x;\n const rB_cross_t = rB.x * tangent.y - rB.y * tangent.x;\n\n // Normal effective mass Kn\n const Kn =\n invMassA +\n invMassB +\n invInertiaA * rA_cross_n * rA_cross_n +\n invInertiaB * rB_cross_n * rB_cross_n;\n const normalMass = Kn > 1e-12 ? 1.0 / Kn : 0.0;\n\n // Tangent effective mass Kt\n const Kt =\n invMassA +\n invMassB +\n invInertiaA * rA_cross_t * rA_cross_t +\n invInertiaB * rB_cross_t * rB_cross_t;\n const tangentMass = Kt > 1e-12 ? 1.0 / Kt : 0.0;\n\n // Relative velocity at contact point: vB(P) - vA(P)\n const vAx = bodyA.velocity.x - bodyA.angularVelocity * rA.y;\n const vAy = bodyA.velocity.y + bodyA.angularVelocity * rA.x;\n const vBx = bodyB.velocity.x - bodyB.angularVelocity * rB.y;\n const vBy = bodyB.velocity.y + bodyB.angularVelocity * rB.x;\n\n const relVx = vBx - vAx;\n const relVy = vBy - vAy;\n const vn = relVx * normal.x + relVy * normal.y;\n\n // Restitution threshold guard\n let vBounce = 0;\n if (vn < -this.restitutionVelocityThreshold) {\n vBounce = -combinedRestitution * vn;\n }\n\n // Baumgarte position bias: applied to velocity solver only if position iterations are disabled\n let vBias = 0;\n if (this.positionIterations === 0 && dt > 0) {\n const penetration = Math.max(0, manifold.penetration - this.penetrationSlop);\n vBias = (this.baumgarte / dt) * penetration;\n }\n\n constraintPoints.push({\n point: pt,\n rA,\n rB,\n normalMass,\n tangentMass,\n normalImpulse: 0,\n tangentImpulse: 0,\n velocityBias: vBounce + vBias,\n rA_cross_n,\n rB_cross_n,\n rA_cross_t,\n rB_cross_t\n });\n }\n\n this._constraints.push({\n bodyA,\n bodyB,\n normal,\n tangent,\n friction: combinedFriction,\n points: constraintPoints\n });\n }\n }\n\n /**\n * Resolves velocity constraints over iterative passes.\n * Alternates between normal non-penetration impulse (using 2x2 block solver for 2-point manifolds)\n * and tangent friction impulse clamped against Coulomb friction cone.\n */\n public solveVelocityConstraints(): void {\n const constraints = this._constraints;\n\n for (let iter = 0; iter < this.velocityIterations; iter++) {\n for (let c = 0; c < constraints.length; c++) {\n const constraint = constraints[c];\n const bodyA = constraint.bodyA;\n const bodyB = constraint.bodyB;\n const normal = constraint.normal;\n const tangent = constraint.tangent;\n const friction = constraint.friction;\n\n const invMassA = bodyA.invMass;\n const invMassB = bodyB.invMass;\n const invInertiaA = bodyA.invInertia;\n const invInertiaB = bodyB.invInertia;\n\n const points = constraint.points;\n\n // ----------------------------------------------------\n // Pass 1: Solve Normal Non-Penetration Constraint FIRST\n // ----------------------------------------------------\n if (points.length === 1) {\n const cp = points[0];\n const vAx = bodyA.velocity.x - bodyA.angularVelocity * cp.rA.y;\n const vAy = bodyA.velocity.y + bodyA.angularVelocity * cp.rA.x;\n const vBx = bodyB.velocity.x - bodyB.angularVelocity * cp.rB.y;\n const vBy = bodyB.velocity.y + bodyB.angularVelocity * cp.rB.x;\n\n const vn = (vBx - vAx) * normal.x + (vBy - vAy) * normal.y;\n let deltaLambdaN = cp.normalMass * (cp.velocityBias - vn);\n\n const oldNormalImpulse = cp.normalImpulse;\n cp.normalImpulse = Math.max(oldNormalImpulse + deltaLambdaN, 0.0);\n deltaLambdaN = cp.normalImpulse - oldNormalImpulse;\n\n const impulseNx = deltaLambdaN * normal.x;\n const impulseNy = deltaLambdaN * normal.y;\n\n bodyA.velocity.x -= impulseNx * invMassA;\n bodyA.velocity.y -= impulseNy * invMassA;\n bodyA.angularVelocity -= cp.rA_cross_n * deltaLambdaN * invInertiaA;\n\n bodyB.velocity.x += impulseNx * invMassB;\n bodyB.velocity.y += impulseNy * invMassB;\n bodyB.angularVelocity += cp.rB_cross_n * deltaLambdaN * invInertiaB;\n } else if (points.length === 2) {\n // 2-Point Block Solver (Erin Catto Box2D formulation)\n const cp1 = points[0];\n const cp2 = points[1];\n\n const rn1A = cp1.rA_cross_n;\n const rn1B = cp1.rB_cross_n;\n const rn2A = cp2.rA_cross_n;\n const rn2B = cp2.rB_cross_n;\n\n const k11 = invMassA + invMassB + invInertiaA * rn1A * rn1A + invInertiaB * rn1B * rn1B;\n const k22 = invMassA + invMassB + invInertiaA * rn2A * rn2A + invInertiaB * rn2B * rn2B;\n const k12 = invMassA + invMassB + invInertiaA * rn1A * rn2A + invInertiaB * rn1B * rn2B;\n\n const det = k11 * k22 - k12 * k12;\n\n if (det > 1e-12) {\n const invK11 = k22 / det;\n const invK22 = k11 / det;\n const invK12 = -k12 / det;\n\n const v1Ax = bodyA.velocity.x - bodyA.angularVelocity * cp1.rA.y;\n const v1Ay = bodyA.velocity.y + bodyA.angularVelocity * cp1.rA.x;\n const v1Bx = bodyB.velocity.x - bodyB.angularVelocity * cp1.rB.y;\n const v1By = bodyB.velocity.y + bodyB.angularVelocity * cp1.rB.x;\n const vn1 = (v1Bx - v1Ax) * normal.x + (v1By - v1Ay) * normal.y;\n\n const v2Ax = bodyA.velocity.x - bodyA.angularVelocity * cp2.rA.y;\n const v2Ay = bodyA.velocity.y + bodyA.angularVelocity * cp2.rA.x;\n const v2Bx = bodyB.velocity.x - bodyB.angularVelocity * cp2.rB.y;\n const v2By = bodyB.velocity.y + bodyB.angularVelocity * cp2.rB.x;\n const vn2 = (v2Bx - v2Ax) * normal.x + (v2By - v2Ay) * normal.y;\n\n const a1 = cp1.normalImpulse;\n const a2 = cp2.normalImpulse;\n\n const b1 = (vn1 - cp1.velocityBias) - (k11 * a1 + k12 * a2);\n const b2 = (vn2 - cp2.velocityBias) - (k12 * a1 + k22 * a2);\n\n let x1 = 0;\n let x2 = 0;\n\n // Case 1: Both points active\n const testX1 = -(invK11 * b1 + invK12 * b2);\n const testX2 = -(invK12 * b1 + invK22 * b2);\n\n if (testX1 >= 0 && testX2 >= 0) {\n x1 = testX1;\n x2 = testX2;\n } else {\n // Case 2: Point 1 active, Point 2 clamped\n const c2X1 = -b1 / k11;\n const vn2Prime = k12 * c2X1 + b2;\n if (c2X1 >= 0 && vn2Prime >= 0) {\n x1 = c2X1;\n x2 = 0;\n } else {\n // Case 3: Point 2 active, Point 1 clamped\n const c3X2 = -b2 / k22;\n const vn1Prime = k12 * c3X2 + b1;\n if (c3X2 >= 0 && vn1Prime >= 0) {\n x1 = 0;\n x2 = c3X2;\n } else if (b1 >= 0 && b2 >= 0) {\n // Case 4: Both clamped\n x1 = 0;\n x2 = 0;\n } else {\n x1 = Math.max(0, testX1);\n x2 = Math.max(0, testX2);\n }\n }\n }\n\n const deltaLambdaN1 = x1 - a1;\n const deltaLambdaN2 = x2 - a2;\n\n cp1.normalImpulse = x1;\n cp2.normalImpulse = x2;\n\n const P1x = deltaLambdaN1 * normal.x;\n const P1y = deltaLambdaN1 * normal.y;\n const P2x = deltaLambdaN2 * normal.x;\n const P2y = deltaLambdaN2 * normal.y;\n const Px = P1x + P2x;\n const Py = P1y + P2y;\n\n bodyA.velocity.x -= Px * invMassA;\n bodyA.velocity.y -= Py * invMassA;\n bodyA.angularVelocity -= (rn1A * deltaLambdaN1 + rn2A * deltaLambdaN2) * invInertiaA;\n\n bodyB.velocity.x += Px * invMassB;\n bodyB.velocity.y += Py * invMassB;\n bodyB.angularVelocity += (rn1B * deltaLambdaN1 + rn2B * deltaLambdaN2) * invInertiaB;\n } else {\n // Degenerate determinant fallback to 1D\n for (let p = 0; p < 2; p++) {\n const cp = points[p];\n const vAx = bodyA.velocity.x - bodyA.angularVelocity * cp.rA.y;\n const vAy = bodyA.velocity.y + bodyA.angularVelocity * cp.rA.x;\n const vBx = bodyB.velocity.x - bodyB.angularVelocity * cp.rB.y;\n const vBy = bodyB.velocity.y + bodyB.angularVelocity * cp.rB.x;\n\n const vn = (vBx - vAx) * normal.x + (vBy - vAy) * normal.y;\n let deltaLambdaN = cp.normalMass * (cp.velocityBias - vn);\n\n const oldNormalImpulse = cp.normalImpulse;\n cp.normalImpulse = Math.max(oldNormalImpulse + deltaLambdaN, 0.0);\n deltaLambdaN = cp.normalImpulse - oldNormalImpulse;\n\n const impulseNx = deltaLambdaN * normal.x;\n const impulseNy = deltaLambdaN * normal.y;\n\n bodyA.velocity.x -= impulseNx * invMassA;\n bodyA.velocity.y -= impulseNy * invMassA;\n bodyA.angularVelocity -= cp.rA_cross_n * deltaLambdaN * invInertiaA;\n\n bodyB.velocity.x += impulseNx * invMassB;\n bodyB.velocity.y += impulseNy * invMassB;\n bodyB.angularVelocity += cp.rB_cross_n * deltaLambdaN * invInertiaB;\n }\n }\n } else {\n // Fallback for > 2 points if any\n for (let p = 0; p < points.length; p++) {\n const cp = points[p];\n const vAx = bodyA.velocity.x - bodyA.angularVelocity * cp.rA.y;\n const vAy = bodyA.velocity.y + bodyA.angularVelocity * cp.rA.x;\n const vBx = bodyB.velocity.x - bodyB.angularVelocity * cp.rB.y;\n const vBy = bodyB.velocity.y + bodyB.angularVelocity * cp.rB.x;\n\n const vn = (vBx - vAx) * normal.x + (vBy - vAy) * normal.y;\n let deltaLambdaN = cp.normalMass * (cp.velocityBias - vn);\n\n const oldNormalImpulse = cp.normalImpulse;\n cp.normalImpulse = Math.max(oldNormalImpulse + deltaLambdaN, 0.0);\n deltaLambdaN = cp.normalImpulse - oldNormalImpulse;\n\n const impulseNx = deltaLambdaN * normal.x;\n const impulseNy = deltaLambdaN * normal.y;\n\n bodyA.velocity.x -= impulseNx * invMassA;\n bodyA.velocity.y -= impulseNy * invMassA;\n bodyA.angularVelocity -= cp.rA_cross_n * deltaLambdaN * invInertiaA;\n\n bodyB.velocity.x += impulseNx * invMassB;\n bodyB.velocity.y += impulseNy * invMassB;\n bodyB.angularVelocity += cp.rB_cross_n * deltaLambdaN * invInertiaB;\n }\n }\n\n // ----------------------------------------------------\n // Pass 2: Solve Tangent Friction SECOND\n // ----------------------------------------------------\n for (let p = 0; p < points.length; p++) {\n const cp = points[p];\n\n const vAx = bodyA.velocity.x - bodyA.angularVelocity * cp.rA.y;\n const vAy = bodyA.velocity.y + bodyA.angularVelocity * cp.rA.x;\n const vBx = bodyB.velocity.x - bodyB.angularVelocity * cp.rB.y;\n const vBy = bodyB.velocity.y + bodyB.angularVelocity * cp.rB.x;\n\n const vt = (vBx - vAx) * tangent.x + (vBy - vAy) * tangent.y;\n let deltaLambdaT = cp.tangentMass * -vt;\n\n const maxFriction = friction * cp.normalImpulse;\n const oldTangentImpulse = cp.tangentImpulse;\n cp.tangentImpulse = MathUtils.clamp(\n oldTangentImpulse + deltaLambdaT,\n -maxFriction,\n maxFriction\n );\n deltaLambdaT = cp.tangentImpulse - oldTangentImpulse;\n\n const impulseTx = deltaLambdaT * tangent.x;\n const impulseTy = deltaLambdaT * tangent.y;\n\n bodyA.velocity.x -= impulseTx * invMassA;\n bodyA.velocity.y -= impulseTy * invMassA;\n bodyA.angularVelocity -= cp.rA_cross_t * deltaLambdaT * invInertiaA;\n\n bodyB.velocity.x += impulseTx * invMassB;\n bodyB.velocity.y += impulseTy * invMassB;\n bodyB.angularVelocity += cp.rB_cross_t * deltaLambdaT * invInertiaB;\n }\n }\n }\n }\n\n /**\n * Position iteration solver: resolves residual geometric penetration directly\n * on body positions/rotations without altering linear/angular velocities.\n */\n public solvePositionConstraints(manifolds: readonly ContactManifold[]): boolean {\n const slop = this.penetrationSlop;\n const betaPos = 0.5; // Position projection correction factor\n let allSolved = true;\n\n for (let iter = 0; iter < this.positionIterations; iter++) {\n let maxPenetration = 0;\n\n for (let m = 0; m < manifolds.length; m++) {\n const manifold = manifolds[m];\n if (!manifold.collided || manifold.contactPoints.length === 0) continue;\n\n const bodyA = manifold.bodyA;\n const bodyB = manifold.bodyB;\n\n const invMassA = bodyA.invMass;\n const invMassB = bodyB.invMass;\n const invInertiaA = bodyA.invInertia;\n const invInertiaB = bodyB.invInertia;\n\n if (invMassA + invMassB === 0) continue;\n\n const normal = manifold.normal;\n const penetration = manifold.penetration;\n const C = Math.max(0, penetration - slop);\n if (C > maxPenetration) maxPenetration = C;\n\n if (C <= 0) continue;\n allSolved = false;\n\n // Apply symmetric position projection for 2-point manifolds or per-point for 1-point\n const numPts = manifold.contactPoints.length;\n if (numPts === 2) {\n const pt1 = manifold.contactPoints[0];\n const pt2 = manifold.contactPoints[1];\n\n const rx1A = pt1.x - bodyA.position.x;\n const ry1A = pt1.y - bodyA.position.y;\n const rx1B = pt1.x - bodyB.position.x;\n const ry1B = pt1.y - bodyB.position.y;\n\n const rx2A = pt2.x - bodyA.position.x;\n const ry2A = pt2.y - bodyA.position.y;\n const rx2B = pt2.x - bodyB.position.x;\n const ry2B = pt2.y - bodyB.position.y;\n\n const rn1A = rx1A * normal.y - ry1A * normal.x;\n const rn1B = rx1B * normal.y - ry1B * normal.x;\n const rn2A = rx2A * normal.y - ry2A * normal.x;\n const rn2B = rx2B * normal.y - ry2B * normal.x;\n\n const Kn1 = invMassA + invMassB + invInertiaA * rn1A * rn1A + invInertiaB * rn1B * rn1B;\n const Kn2 = invMassA + invMassB + invInertiaA * rn2A * rn2A + invInertiaB * rn2B * rn2B;\n\n const imp1 = Kn1 > 1e-12 ? (betaPos * C) / Kn1 / 2 : 0;\n const imp2 = Kn2 > 1e-12 ? (betaPos * C) / Kn2 / 2 : 0;\n const totalImp = imp1 + imp2;\n\n const Px = totalImp * normal.x;\n const Py = totalImp * normal.y;\n\n bodyA.position.x -= Px * invMassA;\n bodyA.position.y -= Py * invMassA;\n bodyA.rotation -= (rn1A * imp1 + rn2A * imp2) * invInertiaA;\n\n bodyB.position.x += Px * invMassB;\n bodyB.position.y += Py * invMassB;\n bodyB.rotation += (rn1B * imp1 + rn2B * imp2) * invInertiaB;\n\n manifold.penetration = Math.max(0, manifold.penetration - totalImp * (invMassA + invMassB));\n } else {\n for (let p = 0; p < numPts; p++) {\n const pt = manifold.contactPoints[p];\n const rxA = pt.x - bodyA.position.x;\n const ryA = pt.y - bodyA.position.y;\n const rxB = pt.x - bodyB.position.x;\n const ryB = pt.y - bodyB.position.y;\n\n const rnA = rxA * normal.y - ryA * normal.x;\n const rnB = rxB * normal.y - ryB * normal.x;\n\n const Kn = invMassA + invMassB + invInertiaA * rnA * rnA + invInertiaB * rnB * rnB;\n if (Kn < 1e-12) continue;\n\n const impulseMag = (betaPos * C) / Kn / numPts;\n const Px = impulseMag * normal.x;\n const Py = impulseMag * normal.y;\n\n bodyA.position.x -= Px * invMassA;\n bodyA.position.y -= Py * invMassA;\n bodyA.rotation -= rnA * impulseMag * invInertiaA;\n\n bodyB.position.x += Px * invMassB;\n bodyB.position.y += Py * invMassB;\n bodyB.rotation += rnB * impulseMag * invInertiaB;\n\n manifold.penetration = Math.max(0, manifold.penetration - impulseMag * (invMassA + invMassB));\n }\n }\n }\n\n if (maxPenetration <= slop) {\n return true;\n }\n }\n\n return allSolved;\n }\n}\n","import { Vector2 } from '../math/Vector2';\nimport { Rect } from '../math/Rect';\nimport { Collider2D } from './Collider2D';\nimport { Ray2D } from './Raycast';\nimport { BodyType } from './RigidBody2D';\n\nexport class ColliderPair {\n public colliderA!: Collider2D;\n public colliderB!: Collider2D;\n\n public get 0(): Collider2D {\n return this.colliderA;\n }\n\n public get 1(): Collider2D {\n return this.colliderB;\n }\n\n public *[Symbol.iterator](): Generator<Collider2D> {\n yield this.colliderA;\n yield this.colliderB;\n }\n}\n\nexport class GridCell {\n public key: number = 0;\n public cx: number = 0;\n public cy: number = 0;\n public readonly colliders: Collider2D[] = [];\n\n public clear(): void {\n this.colliders.length = 0;\n }\n}\n\nexport interface SpatialGridConfig {\n cellSize?: number;\n initialCapacity?: number;\n}\n\n/**\n * Production-grade, zero-allocation Broadphase Spatial Hash Grid.\n * Employs 32-bit packed SMI keys, Minimum Shared Cell deduplication,\n * and Amanatides-Woo Fast Voxel Traversal for raycasting.\n */\nexport class SpatialGrid {\n public readonly cellSize: number;\n public readonly invCellSize: number;\n\n // Active hash cells indexed by 32-bit packed SMI integer key\n private readonly _cells: Map<number, GridCell> = new Map();\n private readonly _activeCells: GridCell[] = [];\n\n // Memory pooling\n private readonly _cellPool: GridCell[] = [];\n private readonly _pairs: ColliderPair[] = [];\n private _pairCount: number = 0;\n\n // Monotonic query counter for zero-allocation query deduplication\n private _queryStamp: number = 1;\n\n constructor(config: SpatialGridConfig = {}) {\n this.cellSize = config.cellSize ?? 64;\n this.invCellSize = 1.0 / this.cellSize;\n\n const initialCap = config.initialCapacity ?? 256;\n for (let i = 0; i < initialCap; i++) {\n this._cellPool.push(new GridCell());\n this._pairs.push(new ColliderPair());\n }\n }\n\n // ==========================================\n // Key Encoding (Zero Heap Allocation)\n // ==========================================\n\n /**\n * Encodes 2D cell coordinates (cx, cy) into a single 32-bit signed integer.\n * Coordinates in [-32768, 32767] produce Small Integers (SMIs) in V8.\n */\n public getCellKey(cx: number, cy: number): number {\n return ((cx & 0xFFFF) << 16) | (cy & 0xFFFF);\n }\n\n // ==========================================\n // Broadphase Lifecycle Management\n // ==========================================\n\n /**\n * Registers a collider across all grid cells overlapping its AABB bounds.\n */\n public insert(collider: Collider2D): void {\n const b = collider.bounds;\n const minCx = Math.floor(b.x * this.invCellSize);\n const minCy = Math.floor(b.y * this.invCellSize);\n const maxCx = Math.floor((b.x + b.width) * this.invCellSize);\n const maxCy = Math.floor((b.y + b.height) * this.invCellSize);\n\n collider._gridMinCx = minCx;\n collider._gridMinCy = minCy;\n collider._gridMaxCx = maxCx;\n collider._gridMaxCy = maxCy;\n\n for (let cy = minCy; cy <= maxCy; cy++) {\n for (let cx = minCx; cx <= maxCx; cx++) {\n const key = this.getCellKey(cx, cy);\n let cell = this._cells.get(key);\n if (!cell) {\n cell = this.acquireCell(key, cx, cy);\n this._cells.set(key, cell);\n this._activeCells.push(cell);\n }\n cell.colliders.push(collider);\n }\n }\n }\n\n /**\n * Removes a collider from all currently occupied cells via fast swap-and-pop.\n */\n public remove(collider: Collider2D): void {\n const minCx = collider._gridMinCx;\n const minCy = collider._gridMinCy;\n const maxCx = collider._gridMaxCx;\n const maxCy = collider._gridMaxCy;\n\n for (let cy = minCy; cy <= maxCy; cy++) {\n for (let cx = minCx; cx <= maxCx; cx++) {\n const key = this.getCellKey(cx, cy);\n const cell = this._cells.get(key);\n if (!cell) continue;\n\n const idx = cell.colliders.indexOf(collider);\n if (idx !== -1) {\n const last = cell.colliders.pop()!;\n if (idx < cell.colliders.length) {\n cell.colliders[idx] = last;\n }\n }\n\n if (cell.colliders.length === 0) {\n this._cells.delete(key);\n const cellIdx = this._activeCells.indexOf(cell);\n if (cellIdx !== -1) {\n const lastCell = this._activeCells.pop()!;\n if (cellIdx < this._activeCells.length) {\n this._activeCells[cellIdx] = lastCell;\n }\n }\n this.releaseCell(cell);\n }\n }\n }\n }\n\n /**\n * Updates collider cell occupancy. Exits in O(1) if cell boundaries were not crossed.\n */\n public update(collider: Collider2D): void {\n const b = collider.updateBounds();\n const newMinCx = Math.floor(b.x * this.invCellSize);\n const newMinCy = Math.floor(b.y * this.invCellSize);\n const newMaxCx = Math.floor((b.x + b.width) * this.invCellSize);\n const newMaxCy = Math.floor((b.y + b.height) * this.invCellSize);\n\n // O(1) Fast Path: No boundary crossed\n if (\n newMinCx === collider._gridMinCx &&\n newMinCy === collider._gridMinCy &&\n newMaxCx === collider._gridMaxCx &&\n newMaxCy === collider._gridMaxCy\n ) {\n return;\n }\n\n this.remove(collider);\n this.insert(collider);\n }\n\n /**\n * Clears all cells and recycles them to pool.\n */\n public clear(): void {\n for (let i = 0; i < this._activeCells.length; i++) {\n this.releaseCell(this._activeCells[i]);\n }\n this._activeCells.length = 0;\n this._cells.clear();\n this._pairCount = 0;\n }\n\n // ==========================================\n // Candidate Pair Generation & Pruning\n // ==========================================\n\n /**\n * Generates candidate pairs for narrowphase collision detection.\n * Employs Minimum Shared Cell deduplication and full bitfield/sleeping pruning.\n */\n public generateCandidatePairs(): readonly ColliderPair[] {\n this._pairCount = 0;\n const activeCells = this._activeCells;\n\n for (let c = 0; c < activeCells.length; c++) {\n const cell = activeCells[c];\n const colliders = cell.colliders;\n const count = colliders.length;\n if (count < 2) continue;\n\n const cx = cell.cx;\n const cy = cell.cy;\n\n for (let i = 0; i < count; i++) {\n const colA = colliders[i];\n\n for (let j = i + 1; j < count; j++) {\n const colB = colliders[j];\n\n // 1. Minimum Shared Cell Deduplication:\n // Emit only in the minimal cell shared by both bounding boxes\n const minSharedCx = colA._gridMinCx > colB._gridMinCx ? colA._gridMinCx : colB._gridMinCx;\n if (cx !== minSharedCx) continue;\n\n const minSharedCy = colA._gridMinCy > colB._gridMinCy ? colA._gridMinCy : colB._gridMinCy;\n if (cy !== minSharedCy) continue;\n\n // 2. Self-body pruning (compound colliders on same rigid body)\n if (colA.body && colB.body && colA.body === colB.body) continue;\n\n const bodyA = colA.body;\n const bodyB = colB.body;\n\n // 3. Static vs Static pruning\n const isStaticA = !bodyA || bodyA.bodyType === BodyType.Static;\n const isStaticB = !bodyB || bodyB.bodyType === BodyType.Static;\n if (isStaticA && isStaticB) continue;\n\n // 4. Sleeping body pruning\n if (bodyA && bodyB && bodyA.isSleeping && bodyB.isSleeping) continue;\n if (\n bodyA &&\n bodyB &&\n ((bodyA.isSleeping && isStaticB) || (bodyB.isSleeping && isStaticA))\n ) {\n continue;\n }\n\n // 5. Collision layer & mask bitfield filtering\n if (\n (colA.layer & colB.mask) === 0 ||\n (colB.layer & colA.mask) === 0\n ) {\n continue;\n }\n\n // 6. Broadphase AABB overlap pre-check\n if (!colA.bounds.intersects(colB.bounds)) {\n continue;\n }\n\n // Accepted candidate pair\n this.addPair(colA, colB);\n }\n }\n }\n\n this._pairs.length = this._pairCount;\n return this._pairs;\n }\n\n private addPair(a: Collider2D, b: Collider2D): void {\n let pair = this._pairs[this._pairCount];\n if (!pair) {\n pair = new ColliderPair();\n this._pairs[this._pairCount] = pair;\n }\n pair.colliderA = a;\n pair.colliderB = b;\n this._pairCount++;\n }\n\n // ==========================================\n // Spatial Queries\n // ==========================================\n\n public queryAABB(aabb: Rect, out: Collider2D[] = []): Collider2D[] {\n out.length = 0;\n const minCx = Math.floor(aabb.x * this.invCellSize);\n const minCy = Math.floor(aabb.y * this.invCellSize);\n const maxCx = Math.floor((aabb.x + aabb.width) * this.invCellSize);\n const maxCy = Math.floor((aabb.y + aabb.height) * this.invCellSize);\n\n const stamp = ++this._queryStamp;\n\n for (let cy = minCy; cy <= maxCy; cy++) {\n for (let cx = minCx; cx <= maxCx; cx++) {\n const key = this.getCellKey(cx, cy);\n const cell = this._cells.get(key);\n if (!cell) continue;\n\n const colliders = cell.colliders;\n for (let i = 0; i < colliders.length; i++) {\n const col = colliders[i];\n if (col._queryStamp === stamp) continue;\n col._queryStamp = stamp;\n\n if (col.bounds.intersects(aabb)) {\n out.push(col);\n }\n }\n }\n }\n return out;\n }\n\n public queryPoint(point: Vector2, out: Collider2D[] = []): Collider2D[] {\n out.length = 0;\n const cx = Math.floor(point.x * this.invCellSize);\n const cy = Math.floor(point.y * this.invCellSize);\n\n const key = this.getCellKey(cx, cy);\n const cell = this._cells.get(key);\n if (!cell) return out;\n\n const colliders = cell.colliders;\n for (let i = 0; i < colliders.length; i++) {\n const col = colliders[i];\n if (col.containsPoint(point)) {\n out.push(col);\n }\n }\n return out;\n }\n\n /**\n * Raycast query using Amanatides & Woo Fast Voxel Traversal (DDA).\n * Traverses intersected cells in strict front-to-back ray order.\n * Hardened against Infinity, NaN, non-positive distances, and infinite loops.\n */\n public queryRay(ray: Ray2D, maxDistance: number = 1000, out: Collider2D[] = []): Collider2D[] {\n out.length = 0;\n\n // Fast-path: If grid contains zero colliders, return immediately in O(1)\n if (this._activeCells.length === 0) {\n return out;\n }\n\n // Defensive clamping against Infinity, NaN, and negative distances\n const effectiveDistance = Number.isFinite(maxDistance) && maxDistance > 0\n ? Math.min(maxDistance, 100000)\n : (maxDistance <= 0 ? 0 : 10000);\n\n // If effective distance is 0, only inspect the single cell containing ray.origin\n if (effectiveDistance === 0) {\n const cx = Math.floor(ray.origin.x * this.invCellSize);\n const cy = Math.floor(ray.origin.y * this.invCellSize);\n const cell = this._cells.get(this.getCellKey(cx, cy));\n if (cell) {\n const stamp = ++this._queryStamp;\n for (let i = 0; i < cell.colliders.length; i++) {\n const col = cell.colliders[i];\n if (col._queryStamp === stamp) continue;\n col._queryStamp = stamp;\n\n if (col.intersectsRay(ray, 0)) {\n out.push(col);\n }\n }\n }\n return out;\n }\n\n const stamp = ++this._queryStamp;\n\n const cellSize = this.cellSize;\n const invCellSize = this.invCellSize;\n\n let cx = Math.floor(ray.origin.x * invCellSize);\n let cy = Math.floor(ray.origin.y * invCellSize);\n\n const endX = ray.origin.x + ray.direction.x * effectiveDistance;\n const endY = ray.origin.y + ray.direction.y * effectiveDistance;\n const endCx = Math.floor(endX * invCellSize);\n const endCy = Math.floor(endY * invCellSize);\n\n const stepX = ray.direction.x > 0 ? 1 : ray.direction.x < 0 ? -1 : 0;\n const stepY = ray.direction.y > 0 ? 1 : ray.direction.y < 0 ? -1 : 0;\n\n const tDeltaX = ray.direction.x !== 0 ? Math.abs(cellSize / ray.direction.x) : Infinity;\n const tDeltaY = ray.direction.y !== 0 ? Math.abs(cellSize / ray.direction.y) : Infinity;\n\n let tMaxX: number;\n if (stepX > 0) {\n tMaxX = ((cx + 1) * cellSize - ray.origin.x) / ray.direction.x;\n } else if (stepX < 0) {\n tMaxX = (cx * cellSize - ray.origin.x) / ray.direction.x;\n } else {\n tMaxX = Infinity;\n }\n\n let tMaxY: number;\n if (stepY > 0) {\n tMaxY = ((cy + 1) * cellSize - ray.origin.y) / ray.direction.y;\n } else if (stepY < 0) {\n tMaxY = (cy * cellSize - ray.origin.y) / ray.direction.y;\n } else {\n tMaxY = Infinity;\n }\n\n // Defensive loop step limiter to prevent lockups under any arithmetic anomalies\n const maxSteps = 10000;\n let steps = 0;\n\n // Traversal loop\n while (true) {\n if (++steps > maxSteps) break;\n\n const key = this.getCellKey(cx, cy);\n const cell = this._cells.get(key);\n if (cell) {\n const colliders = cell.colliders;\n for (let i = 0; i < colliders.length; i++) {\n const col = colliders[i];\n if (col._queryStamp === stamp) continue;\n col._queryStamp = stamp;\n\n if (col.intersectsRay(ray, effectiveDistance)) {\n out.push(col);\n }\n }\n }\n\n if (cx === endCx && cy === endCy) break;\n if (tMaxX > effectiveDistance && tMaxY > effectiveDistance) break;\n\n if (tMaxX < tMaxY) {\n cx += stepX;\n tMaxX += tDeltaX;\n } else {\n cy += stepY;\n tMaxY += tDeltaY;\n }\n }\n\n return out;\n }\n\n // ==========================================\n // Cell Pool Management\n // ==========================================\n\n private acquireCell(key: number, cx: number, cy: number): GridCell {\n const cell = this._cellPool.pop() ?? new GridCell();\n cell.key = key;\n cell.cx = cx;\n cell.cy = cy;\n cell.colliders.length = 0;\n return cell;\n }\n\n private releaseCell(cell: GridCell): void {\n cell.clear();\n this._cellPool.push(cell);\n }\n\n public get activeCellCount(): number {\n return this._activeCells.length;\n }\n\n public get pooledCellCount(): number {\n return this._cellPool.length;\n }\n}\n","import { Vector2 } from '../math/Vector2';\nimport { RigidBody2D } from './RigidBody2D';\nimport { ContactManifold } from './ContactSolver';\nimport { Collider2D } from './Collider2D';\nimport { EventEmitter } from '../core/EventEmitter';\n\nexport interface ActiveCollisionPair {\n key: string;\n colliderA: Collider2D;\n colliderB: Collider2D;\n bodyA: RigidBody2D | null;\n bodyB: RigidBody2D | null;\n manifold: ContactManifold;\n isTrigger: boolean;\n}\n\nexport interface CollisionFSMEvents {\n 'collision:enter': {\n colliderA: Collider2D;\n colliderB: Collider2D;\n bodyA: RigidBody2D | null;\n bodyB: RigidBody2D | null;\n manifold: ContactManifold;\n };\n 'collision:stay': {\n colliderA: Collider2D;\n colliderB: Collider2D;\n bodyA: RigidBody2D | null;\n bodyB: RigidBody2D | null;\n manifold: ContactManifold;\n };\n 'collision:exit': {\n colliderA: Collider2D;\n colliderB: Collider2D;\n bodyA: RigidBody2D | null;\n bodyB: RigidBody2D | null;\n };\n 'trigger:enter': {\n colliderA: Collider2D;\n colliderB: Collider2D;\n bodyA: RigidBody2D | null;\n bodyB: RigidBody2D | null;\n };\n 'trigger:stay': {\n colliderA: Collider2D;\n colliderB: Collider2D;\n bodyA: RigidBody2D | null;\n bodyB: RigidBody2D | null;\n };\n 'trigger:exit': {\n colliderA: Collider2D;\n colliderB: Collider2D;\n bodyA: RigidBody2D | null;\n bodyB: RigidBody2D | null;\n };\n}\n\nexport function getPairKey(idA: number, idB: number): string {\n return idA < idB ? `${idA}:${idB}` : `${idB}:${idA}`;\n}\n\nexport class CollisionFSM {\n private _previousCollisions: Map<string, ActiveCollisionPair> = new Map();\n private _currentCollisions: Map<string, ActiveCollisionPair> = new Map();\n\n private _previousTriggers: Map<string, ActiveCollisionPair> = new Map();\n private _currentTriggers: Map<string, ActiveCollisionPair> = new Map();\n\n private _emitter: { emit(event: any, payload: any): boolean };\n\n constructor(emitter: { emit(event: any, payload: any): boolean }) {\n this._emitter = emitter;\n }\n\n /**\n * Process all narrowphase manifolds for the current frame/sub-step.\n * Dispatches Enter and Stay events, and returns solid manifolds for ContactSolver.\n */\n public processManifolds(rawManifolds: readonly ContactManifold[]): ContactManifold[] {\n const solidManifolds: ContactManifold[] = [];\n this._currentCollisions.clear();\n this._currentTriggers.clear();\n\n for (let i = 0; i < rawManifolds.length; i++) {\n const manifold = rawManifolds[i];\n if (!manifold.collided) continue;\n\n const colA = manifold.colliderA as Collider2D;\n const colB = manifold.colliderB as Collider2D;\n const bodyA = manifold.bodyA ?? colA?.body ?? null;\n const bodyB = manifold.bodyB ?? colB?.body ?? null;\n\n const key = getPairKey(colA.id, colB.id);\n const isTrigger = colA.isTrigger || colB.isTrigger;\n\n const pair: ActiveCollisionPair = {\n key,\n colliderA: colA,\n colliderB: colB,\n bodyA,\n bodyB,\n manifold,\n isTrigger\n };\n\n if (isTrigger) {\n this._currentTriggers.set(key, pair);\n if (!this._previousTriggers.has(key)) {\n this._dispatchTriggerEnter(pair);\n } else {\n this._dispatchTriggerStay(pair);\n }\n } else {\n this._currentCollisions.set(key, pair);\n solidManifolds.push(manifold);\n\n if (!this._previousCollisions.has(key)) {\n this._dispatchCollisionEnter(pair);\n } else {\n this._dispatchCollisionStay(pair);\n }\n }\n }\n\n // Process Exits for triggers\n for (const [key, pair] of this._previousTriggers) {\n if (!this._currentTriggers.has(key)) {\n this._dispatchTriggerExit(pair);\n }\n }\n\n // Process Exits for solid collisions\n for (const [key, pair] of this._previousCollisions) {\n if (!this._currentCollisions.has(key)) {\n this._dispatchCollisionExit(pair);\n }\n }\n\n return solidManifolds;\n }\n\n /**\n * Swaps pair tracking maps at the end of the physics sub-step.\n */\n public endStep(): void {\n this._previousCollisions.clear();\n for (const [key, val] of this._currentCollisions) {\n this._previousCollisions.set(key, val);\n }\n\n this._previousTriggers.clear();\n for (const [key, val] of this._currentTriggers) {\n this._previousTriggers.set(key, val);\n }\n }\n\n /**\n * Evicts any pairs referencing a deleted collider or body and dispatches exit events.\n */\n public handleColliderRemoved(collider: Collider2D): void {\n for (const [key, pair] of this._previousCollisions) {\n if (pair.colliderA.id === collider.id || pair.colliderB.id === collider.id) {\n this._dispatchCollisionExit(pair);\n this._previousCollisions.delete(key);\n }\n }\n for (const [key, pair] of this._previousTriggers) {\n if (pair.colliderA.id === collider.id || pair.colliderB.id === collider.id) {\n this._dispatchTriggerExit(pair);\n this._previousTriggers.delete(key);\n }\n }\n }\n\n private _createInvertedManifold(manifold: ContactManifold): ContactManifold {\n return {\n ...manifold,\n normal: new Vector2(-manifold.normal.x, -manifold.normal.y),\n bodyA: manifold.bodyB,\n bodyB: manifold.bodyA,\n colliderA: manifold.colliderB,\n colliderB: manifold.colliderA\n };\n }\n\n private _dispatchTriggerEnter(pair: ActiveCollisionPair): void {\n const { colliderA, colliderB, bodyA, bodyB } = pair;\n colliderA.onTriggerEnter?.(colliderB);\n colliderB.onTriggerEnter?.(colliderA);\n bodyA?.onTriggerEnter?.(bodyB, colliderA, colliderB);\n bodyB?.onTriggerEnter?.(bodyA, colliderB, colliderA);\n this._emitter.emit('trigger:enter', { colliderA, colliderB, bodyA, bodyB });\n }\n\n private _dispatchTriggerStay(pair: ActiveCollisionPair): void {\n const { colliderA, colliderB, bodyA, bodyB } = pair;\n colliderA.onTriggerStay?.(colliderB);\n colliderB.onTriggerStay?.(colliderA);\n bodyA?.onTriggerStay?.(bodyB, colliderA, colliderB);\n bodyB?.onTriggerStay?.(bodyA, colliderB, colliderA);\n this._emitter.emit('trigger:stay', { colliderA, colliderB, bodyA, bodyB });\n }\n\n private _dispatchTriggerExit(pair: ActiveCollisionPair): void {\n const { colliderA, colliderB, bodyA, bodyB } = pair;\n colliderA.onTriggerExit?.(colliderB);\n colliderB.onTriggerExit?.(colliderA);\n bodyA?.onTriggerExit?.(bodyB, colliderA, colliderB);\n bodyB?.onTriggerExit?.(bodyA, colliderB, colliderA);\n this._emitter.emit('trigger:exit', { colliderA, colliderB, bodyA, bodyB });\n }\n\n private _dispatchCollisionEnter(pair: ActiveCollisionPair): void {\n const { colliderA, colliderB, bodyA, bodyB, manifold } = pair;\n const invManifold = this._createInvertedManifold(manifold);\n\n colliderA.onCollisionEnter?.(colliderB, manifold);\n colliderB.onCollisionEnter?.(colliderA, invManifold);\n bodyA?.onCollisionEnter?.(bodyB, colliderA, colliderB, manifold);\n bodyB?.onCollisionEnter?.(bodyA, colliderB, colliderA, invManifold);\n this._emitter.emit('collision:enter', { colliderA, colliderB, bodyA, bodyB, manifold });\n }\n\n private _dispatchCollisionStay(pair: ActiveCollisionPair): void {\n const { colliderA, colliderB, bodyA, bodyB, manifold } = pair;\n const invManifold = this._createInvertedManifold(manifold);\n\n colliderA.onCollisionStay?.(colliderB, manifold);\n colliderB.onCollisionStay?.(colliderA, invManifold);\n bodyA?.onCollisionStay?.(bodyB, colliderA, colliderB, manifold);\n bodyB?.onCollisionStay?.(bodyA, colliderB, colliderA, invManifold);\n this._emitter.emit('collision:stay', { colliderA, colliderB, bodyA, bodyB, manifold });\n }\n\n private _dispatchCollisionExit(pair: ActiveCollisionPair): void {\n const { colliderA, colliderB, bodyA, bodyB } = pair;\n colliderA.onCollisionExit?.(colliderB);\n colliderB.onCollisionExit?.(colliderA);\n bodyA?.onCollisionExit?.(bodyB, colliderA, colliderB);\n bodyB?.onCollisionExit?.(bodyA, colliderB, colliderA);\n this._emitter.emit('collision:exit', { colliderA, colliderB, bodyA, bodyB });\n }\n}\n","import { Vector2 } from '../math/Vector2';\nimport { Rect } from '../math/Rect';\nimport type { RigidBody2D } from './RigidBody2D';\nimport type { ContactManifold } from './ContactSolver';\nimport type { Ray2D, RaycastHit2D } from './Raycast';\n\nexport enum ColliderType {\n Circle = 'circle',\n Box = 'box'\n}\n\nexport interface ColliderConfig {\n body?: RigidBody2D | null;\n offset?: Vector2;\n isTrigger?: boolean;\n density?: number;\n friction?: number;\n restitution?: number;\n layer?: number;\n collisionLayer?: number;\n mask?: number;\n collisionMask?: number;\n userData?: any;\n}\n\nlet nextColliderId = 1;\n\n/**\n * Abstract Base Collider representing geometry attached to a RigidBody2D\n * or existing as a static sensor/trigger.\n */\nexport abstract class Collider2D {\n public readonly id: number = nextColliderId++;\n protected _body: RigidBody2D | null = null;\n\n public get body(): RigidBody2D | null {\n return this._body;\n }\n\n public set body(val: RigidBody2D | null) {\n this._body = val;\n this.updateBodyInertia();\n }\n\n public abstract readonly type: ColliderType;\n public readonly offset: Vector2 = new Vector2(0, 0);\n public isTrigger: boolean = false;\n public density: number = 1.0;\n public friction: number = 0.5;\n public restitution: number = 0.0;\n public layer: number = 0x0001;\n public mask: number = 0xFFFFFFFF;\n public userData: any = null;\n\n public abstract computeInertia(mass: number): number;\n\n public updateBodyInertia(): void {\n if (this._body && !this._body.hasCustomInertia && this._body.mass > 0) {\n const I = this.computeInertia(this._body.mass);\n if (I > 0) {\n this._body.setInertia(I);\n this._body.hasCustomInertia = false;\n }\n }\n }\n\n // Cached world-space Axis-Aligned Bounding Box\n public readonly bounds: Rect = new Rect();\n\n // Internal SpatialGrid tracking\n public _gridMinCx: number = 0;\n public _gridMinCy: number = 0;\n public _gridMaxCx: number = 0;\n public _gridMaxCy: number = 0;\n public _queryStamp: number = 0;\n\n // Collision and trigger callbacks\n public onCollisionEnter?: (other: Collider2D, manifold: ContactManifold) => void;\n public onCollisionStay?: (other: Collider2D, manifold: ContactManifold) => void;\n public onCollisionExit?: (other: Collider2D) => void;\n public onTriggerEnter?: (other: Collider2D) => void;\n public onTriggerStay?: (other: Collider2D) => void;\n public onTriggerExit?: (other: Collider2D) => void;\n\n constructor(configOrOffsetX?: ColliderConfig | number, offsetY?: number) {\n if (typeof configOrOffsetX === 'object' && configOrOffsetX !== null) {\n const cfg = configOrOffsetX;\n this.body = cfg.body ?? null;\n if (cfg.offset) this.offset.copy(cfg.offset);\n this.isTrigger = cfg.isTrigger ?? false;\n this.density = cfg.density ?? 1.0;\n this.friction = cfg.friction ?? 0.5;\n this.restitution = cfg.restitution ?? 0.0;\n this.layer = cfg.collisionLayer ?? cfg.layer ?? 0x0001;\n this.mask = cfg.collisionMask ?? cfg.mask ?? 0xFFFFFFFF;\n this.userData = cfg.userData ?? null;\n } else if (typeof configOrOffsetX === 'number') {\n this.offset.set(configOrOffsetX, offsetY ?? 0);\n }\n }\n\n public get collisionLayer(): number {\n return this.layer;\n }\n\n public set collisionLayer(val: number) {\n this.layer = val;\n }\n\n public get collisionMask(): number {\n return this.mask;\n }\n\n public set collisionMask(val: number) {\n this.mask = val;\n }\n\n public setOffset(x: number, y: number): this {\n this.offset.set(x, y);\n return this;\n }\n\n public setMaterial(friction: number, restitution: number, density: number = this.density): this {\n this.friction = Math.max(0, friction);\n this.restitution = Math.max(0, Math.min(1, restitution));\n this.density = Math.max(1e-6, density);\n return this;\n }\n\n public setFilter(layer: number, mask: number): this {\n this.layer = layer;\n this.mask = mask;\n return this;\n }\n\n public getWorldPosition(out?: Vector2): Vector2 {\n const dest = out ?? new Vector2();\n if (this.body !== null) {\n const cos = Math.cos(this.body.rotation);\n const sin = Math.sin(this.body.rotation);\n dest.x = this.body.position.x + (this.offset.x * cos - this.offset.y * sin);\n dest.y = this.body.position.y + (this.offset.x * sin + this.offset.y * cos);\n } else {\n dest.copy(this.offset);\n }\n return dest;\n }\n\n public getWorldRotation(): number {\n return this.body !== null ? this.body.rotation : 0;\n }\n\n public getAABB(out?: Rect): Rect {\n this.updateBounds();\n if (out) {\n return out.copy(this.bounds);\n }\n return this.bounds;\n }\n\n public updateWorldBounds(): Rect {\n return this.updateBounds();\n }\n\n public abstract updateBounds(): Rect;\n public abstract containsPoint(point: Vector2): boolean;\n public abstract intersectsRay(ray: Ray2D, maxDistance?: number): boolean;\n public abstract raycast(ray: Ray2D): RaycastHit2D | null;\n public abstract intersectsCircle(center: Vector2, radius: number): boolean;\n public abstract intersectsBox(center: Vector2, width: number, height: number, rotation?: number): boolean;\n public abstract computeMassAndInertia(density?: number): { mass: number; inertia: number };\n public abstract clone(): Collider2D;\n}\n","import { Vector2 } from '../math/Vector2';\nimport type { Collider2D } from './Collider2D';\nimport type { RigidBody2D } from './RigidBody2D';\n\nexport class Ray2D {\n public origin: Vector2;\n public direction: Vector2;\n public maxDistance: number;\n\n constructor(\n origin: Vector2 = new Vector2(0, 0),\n direction: Vector2 = new Vector2(1, 0),\n maxDistance: number = Infinity\n ) {\n this.origin = origin.clone();\n this.direction = direction.clone().normalizeInPlace();\n this.maxDistance = Math.max(0, maxDistance);\n }\n\n public set(origin: Vector2, direction: Vector2, maxDistance: number = this.maxDistance): this {\n this.origin.copy(origin);\n this.direction.copy(direction).normalizeInPlace();\n this.maxDistance = Math.max(0, maxDistance);\n return this;\n }\n\n public getPoint(t: number, out?: Vector2): Vector2 {\n const dest = out ?? new Vector2();\n dest.x = this.origin.x + this.direction.x * t;\n dest.y = this.origin.y + this.direction.y * t;\n return dest;\n }\n}\n\nexport interface RaycastHit2D {\n collider: Collider2D;\n body: RigidBody2D | null;\n point: Vector2;\n normal: Vector2;\n fraction: number; // in [0, 1]\n distance: number;\n}\n\nexport class Raycast {\n /**\n * Evaluates ray intersection against a Circle.\n */\n public static intersectCircle(\n ray: Ray2D,\n center: Vector2,\n radius: number\n ): { fraction: number; point: Vector2; normal: Vector2 } | null {\n const ox = ray.origin.x - center.x;\n const oy = ray.origin.y - center.y;\n const dx = ray.direction.x;\n const dy = ray.direction.y;\n\n const b = ox * dx + oy * dy;\n const c = ox * ox + oy * oy - radius * radius;\n\n // Ray origin outside circle and pointing away\n if (c > 0 && b > 0) return null;\n\n const discriminant = b * b - c;\n if (discriminant < 0) return null;\n\n const sqrtDisc = Math.sqrt(discriminant);\n let t = -b - sqrtDisc;\n\n if (t < 0) {\n t = 0; // Origin inside circle\n }\n\n if (t > ray.maxDistance) return null;\n\n const hitX = ray.origin.x + dx * t;\n const hitY = ray.origin.y + dy * t;\n const hitPoint = new Vector2(hitX, hitY);\n\n let hitNormal: Vector2;\n if (t > 0 && radius > 1e-6) {\n hitNormal = new Vector2((hitX - center.x) / radius, (hitY - center.y) / radius);\n } else {\n hitNormal = ray.direction.clone().negateInPlace();\n }\n\n const fraction = ray.maxDistance > 0 && Number.isFinite(ray.maxDistance)\n ? t / ray.maxDistance\n : 0;\n\n return {\n fraction,\n point: hitPoint,\n normal: hitNormal\n };\n }\n\n /**\n * Evaluates ray intersection against an Oriented Bounding Box (OBB).\n */\n public static intersectBox(\n ray: Ray2D,\n center: Vector2,\n halfWidth: number,\n halfHeight: number,\n rotation: number = 0\n ): { fraction: number; point: Vector2; normal: Vector2 } | null {\n const c = Math.cos(rotation);\n const s = Math.sin(rotation);\n\n // Relative to box center\n const rx = ray.origin.x - center.x;\n const ry = ray.origin.y - center.y;\n\n // Transform into box local space (rotate by -rotation)\n const localOriginX = rx * c + ry * s;\n const localOriginY = -rx * s + ry * c;\n\n const localDirX = ray.direction.x * c + ray.direction.y * s;\n const localDirY = -ray.direction.x * s + ray.direction.y * c;\n\n let tmin = -Infinity;\n let tmax = Infinity;\n let normalAxis = 0; // 1 = X, 2 = Y\n let normalSign = 1;\n\n // X slab\n if (Math.abs(localDirX) < 1e-8) {\n if (localOriginX < -halfWidth || localOriginX > halfWidth) return null;\n } else {\n const invD = 1.0 / localDirX;\n let t1 = (-halfWidth - localOriginX) * invD;\n let t2 = (halfWidth - localOriginX) * invD;\n let sign = -1;\n if (t1 > t2) {\n const tmp = t1; t1 = t2; t2 = tmp;\n sign = 1;\n }\n if (t1 > tmin) {\n tmin = t1;\n normalAxis = 1;\n normalSign = sign;\n }\n tmax = Math.min(tmax, t2);\n if (tmin > tmax) return null;\n }\n\n // Y slab\n if (Math.abs(localDirY) < 1e-8) {\n if (localOriginY < -halfHeight || localOriginY > halfHeight) return null;\n } else {\n const invD = 1.0 / localDirY;\n let t1 = (-halfHeight - localOriginY) * invD;\n let t2 = (halfHeight - localOriginY) * invD;\n let sign = -1;\n if (t1 > t2) {\n const tmp = t1; t1 = t2; t2 = tmp;\n sign = 1;\n }\n if (t1 > tmin) {\n tmin = t1;\n normalAxis = 2;\n normalSign = sign;\n }\n tmax = Math.min(tmax, t2);\n if (tmin > tmax) return null;\n }\n\n if (tmax < 0) return null;\n\n const tHit = tmin >= 0 ? tmin : 0;\n if (tHit > ray.maxDistance) return null;\n\n // Local normal\n let localNx = 0;\n let localNy = 0;\n if (tHit > 0) {\n if (normalAxis === 1) localNx = normalSign;\n else if (normalAxis === 2) localNy = normalSign;\n } else {\n localNx = -localDirX;\n localNy = -localDirY;\n }\n\n // Transform local normal to world space (rotate by +rotation)\n const worldNx = localNx * c - localNy * s;\n const worldNy = localNx * s + localNy * c;\n\n const hitPoint = new Vector2(\n ray.origin.x + ray.direction.x * tHit,\n ray.origin.y + ray.direction.y * tHit\n );\n\n const fraction = ray.maxDistance > 0 && Number.isFinite(ray.maxDistance)\n ? tHit / ray.maxDistance\n : 0;\n\n return {\n fraction,\n point: hitPoint,\n normal: new Vector2(worldNx, worldNy).normalizeInPlace()\n };\n }\n}\n","import { Collider2D, ColliderType, ColliderConfig } from './Collider2D';\nimport { Vector2 } from '../math/Vector2';\nimport { Rect } from '../math/Rect';\nimport { Ray2D, RaycastHit2D, Raycast } from './Raycast';\n\nexport interface CircleColliderConfig extends ColliderConfig {\n radius: number;\n}\n\nexport class CircleCollider2D extends Collider2D {\n public readonly type = ColliderType.Circle;\n public radius: number = 10;\n\n constructor(\n configOrRadius: CircleColliderConfig | number,\n offsetX: number = 0,\n offsetY: number = 0\n ) {\n if (typeof configOrRadius === 'object' && configOrRadius !== null) {\n super(configOrRadius);\n this.radius = Math.max(1e-4, configOrRadius.radius ?? 10);\n } else {\n super(offsetX, offsetY);\n this.radius = Math.max(1e-4, typeof configOrRadius === 'number' ? configOrRadius : 10);\n }\n this.updateBounds();\n this.updateBodyInertia();\n }\n\n public computeInertia(mass: number): number {\n const r = this.radius !== undefined ? this.radius : 10;\n const dSq = this.offset ? this.offset.lengthSq() : 0;\n return 0.5 * mass * r * r + mass * dSq;\n }\n\n public get worldCenter(): Vector2 {\n return this.getWorldPosition();\n }\n\n public setRadius(radius: number): this {\n this.radius = Math.max(1e-4, radius);\n this.updateBounds();\n this.updateBodyInertia();\n return this;\n }\n\n public override updateBounds(): Rect {\n const pos = this.getWorldPosition(Vector2.temp1);\n const r = this.radius;\n return this.bounds.set(pos.x - r, pos.y - r, r * 2, r * 2);\n }\n\n public override containsPoint(point: Vector2): boolean {\n const center = this.getWorldPosition(Vector2.temp1);\n const dx = point.x - center.x;\n const dy = point.y - center.y;\n return dx * dx + dy * dy <= this.radius * this.radius;\n }\n\n public override intersectsRay(ray: Ray2D, maxDistance: number = ray.maxDistance): boolean {\n const center = this.getWorldPosition(Vector2.temp1);\n const hit = Raycast.intersectCircle(\n ray.maxDistance !== maxDistance ? new Ray2D(ray.origin, ray.direction, maxDistance) : ray,\n center,\n this.radius\n );\n return hit !== null;\n }\n\n public override raycast(ray: Ray2D): RaycastHit2D | null {\n const center = this.getWorldPosition(Vector2.temp1);\n const hit = Raycast.intersectCircle(ray, center, this.radius);\n if (!hit) return null;\n\n const dist = hit.point.distanceTo(ray.origin);\n return {\n collider: this,\n body: this.body,\n point: hit.point,\n normal: hit.normal,\n fraction: hit.fraction,\n distance: dist\n };\n }\n\n public override intersectsCircle(center: Vector2, radius: number): boolean {\n const myCenter = this.getWorldPosition(Vector2.temp1);\n const dx = center.x - myCenter.x;\n const dy = center.y - myCenter.y;\n const rSum = this.radius + radius;\n return dx * dx + dy * dy <= rSum * rSum;\n }\n\n public override intersectsBox(\n center: Vector2,\n width: number,\n height: number,\n rotation: number = 0\n ): boolean {\n const myCenter = this.getWorldPosition(Vector2.temp1);\n const hw = width * 0.5;\n const hh = height * 0.5;\n\n // Transform circle into box local space\n const rx = myCenter.x - center.x;\n const ry = myCenter.y - center.y;\n const c = Math.cos(rotation);\n const s = Math.sin(rotation);\n\n const lx = rx * c + ry * s;\n const ly = -rx * s + ry * c;\n\n const clampedX = Math.max(-hw, Math.min(hw, lx));\n const clampedY = Math.max(-hh, Math.min(hh, ly));\n\n const dx = lx - clampedX;\n const dy = ly - clampedY;\n return dx * dx + dy * dy <= this.radius * this.radius;\n }\n\n public override computeMassAndInertia(\n density: number = this.density\n ): { mass: number; inertia: number } {\n const r = this.radius;\n const area = Math.PI * r * r;\n const mass = area * density;\n const inertiaCm = 0.5 * mass * r * r;\n const offsetDistSq = this.offset.lengthSq();\n const inertia = inertiaCm + mass * offsetDistSq;\n return { mass, inertia };\n }\n\n public override clone(): CircleCollider2D {\n const copy = new CircleCollider2D({\n body: this.body,\n radius: this.radius,\n offset: this.offset.clone(),\n isTrigger: this.isTrigger,\n density: this.density,\n friction: this.friction,\n restitution: this.restitution,\n layer: this.layer,\n mask: this.mask,\n userData: this.userData\n });\n return copy;\n }\n}\n","import { Collider2D, ColliderType, ColliderConfig } from './Collider2D';\nimport { Vector2 } from '../math/Vector2';\nimport { Rect } from '../math/Rect';\nimport { Ray2D, RaycastHit2D, Raycast } from './Raycast';\n\nexport interface BoxColliderConfig extends ColliderConfig {\n width?: number;\n height?: number;\n size?: Vector2;\n rotation?: number;\n}\n\nexport class BoxCollider2D extends Collider2D {\n public readonly type = ColliderType.Box;\n public readonly size: Vector2 = new Vector2(20, 20);\n public readonly halfExtents: Vector2 = new Vector2(10, 10);\n public rotation: number = 0; // Local rotation in radians\n\n constructor(\n configOrWidth?: BoxColliderConfig | number,\n height: number = 20,\n offsetX: number = 0,\n offsetY: number = 0,\n rotation: number = 0\n ) {\n if (typeof configOrWidth === 'object' && configOrWidth !== null) {\n super(configOrWidth);\n const cfg = configOrWidth;\n const w = cfg.width ?? (cfg.size ? cfg.size.x : 20);\n const h = cfg.height ?? (cfg.size ? cfg.size.y : 20);\n this.setSize(w, h);\n this.rotation = cfg.rotation ?? 0;\n } else {\n super(offsetX, offsetY);\n const w = typeof configOrWidth === 'number' ? configOrWidth : 20;\n this.setSize(w, height);\n this.rotation = rotation;\n }\n this.updateBounds();\n this.updateBodyInertia();\n }\n\n public computeInertia(mass: number): number {\n const sx = this.size ? this.size.x : 20;\n const sy = this.size ? this.size.y : 20;\n const dSq = this.offset ? this.offset.lengthSq() : 0;\n return (1 / 12) * mass * (sx * sx + sy * sy) + mass * dSq;\n }\n\n public get width(): number {\n return this.size.x;\n }\n\n public set width(val: number) {\n this.setSize(val, this.size.y);\n }\n\n public get height(): number {\n return this.size.y;\n }\n\n public set height(val: number) {\n this.setSize(this.size.x, val);\n }\n\n public setSize(width: number, height: number): this {\n const w = Math.max(1e-4, width);\n const h = Math.max(1e-4, height);\n this.size.set(w, h);\n this.halfExtents.set(w * 0.5, h * 0.5);\n this.updateBounds();\n this.updateBodyInertia();\n return this;\n }\n\n public override getWorldRotation(): number {\n return (this.body !== null ? this.body.rotation : 0) + this.rotation;\n }\n\n public getVertices(out?: Vector2[]): Vector2[] {\n const center = this.getWorldPosition(Vector2.temp1);\n const rot = this.getWorldRotation();\n const cos = Math.cos(rot);\n const sin = Math.sin(rot);\n const hx = this.halfExtents.x;\n const hy = this.halfExtents.y;\n\n const v0 = out && out[0] ? out[0] : new Vector2();\n const v1 = out && out[1] ? out[1] : new Vector2();\n const v2 = out && out[2] ? out[2] : new Vector2();\n const v3 = out && out[3] ? out[3] : new Vector2();\n\n // CCW vertices in world coordinates\n // Top-Left (-hx, -hy)\n v0.set(center.x + (-hx * cos - -hy * sin), center.y + (-hx * sin + -hy * cos));\n // Top-Right (hx, -hy)\n v1.set(center.x + (hx * cos - -hy * sin), center.y + (hx * sin + -hy * cos));\n // Bottom-Right (hx, hy)\n v2.set(center.x + (hx * cos - hy * sin), center.y + (hx * sin + hy * cos));\n // Bottom-Left (-hx, hy)\n v3.set(center.x + (-hx * cos - hy * sin), center.y + (-hx * sin + hy * cos));\n\n return [v0, v1, v2, v3];\n }\n\n public getNormals(out?: Vector2[]): Vector2[] {\n const rot = this.getWorldRotation();\n const cos = Math.cos(rot);\n const sin = Math.sin(rot);\n\n const n0 = out && out[0] ? out[0] : new Vector2();\n const n1 = out && out[1] ? out[1] : new Vector2();\n\n n0.set(cos, sin); // local X axis in world\n n1.set(-sin, cos); // local Y axis in world\n\n return [n0, n1];\n }\n\n public override updateBounds(): Rect {\n const center = this.getWorldPosition(Vector2.temp1);\n const rot = this.getWorldRotation();\n const cos = Math.abs(Math.cos(rot));\n const sin = Math.abs(Math.sin(rot));\n\n const ex = this.halfExtents.x * cos + this.halfExtents.y * sin;\n const ey = this.halfExtents.x * sin + this.halfExtents.y * cos;\n\n return this.bounds.set(center.x - ex, center.y - ey, ex * 2, ey * 2);\n }\n\n public override containsPoint(point: Vector2): boolean {\n const center = this.getWorldPosition(Vector2.temp1);\n const rot = this.getWorldRotation();\n\n const rx = point.x - center.x;\n const ry = point.y - center.y;\n const c = Math.cos(rot);\n const s = Math.sin(rot);\n\n // Transform into box local space\n const lx = rx * c + ry * s;\n const ly = -rx * s + ry * c;\n\n const hx = this.halfExtents.x;\n const hy = this.halfExtents.y;\n return lx >= -hx && lx <= hx && ly >= -hy && ly <= hy;\n }\n\n public override intersectsRay(ray: Ray2D, maxDistance: number = ray.maxDistance): boolean {\n const center = this.getWorldPosition(Vector2.temp1);\n const rot = this.getWorldRotation();\n const hit = Raycast.intersectBox(\n ray.maxDistance !== maxDistance ? new Ray2D(ray.origin, ray.direction, maxDistance) : ray,\n center,\n this.halfExtents.x,\n this.halfExtents.y,\n rot\n );\n return hit !== null;\n }\n\n public override raycast(ray: Ray2D): RaycastHit2D | null {\n const center = this.getWorldPosition(Vector2.temp1);\n const rot = this.getWorldRotation();\n const hit = Raycast.intersectBox(\n ray,\n center,\n this.halfExtents.x,\n this.halfExtents.y,\n rot\n );\n if (!hit) return null;\n\n const dist = hit.point.distanceTo(ray.origin);\n return {\n collider: this,\n body: this.body,\n point: hit.point,\n normal: hit.normal,\n fraction: hit.fraction,\n distance: dist\n };\n }\n\n public override intersectsCircle(center: Vector2, radius: number): boolean {\n const myCenter = this.getWorldPosition(Vector2.temp1);\n const rot = this.getWorldRotation();\n const hw = this.halfExtents.x;\n const hh = this.halfExtents.y;\n\n const rx = center.x - myCenter.x;\n const ry = center.y - myCenter.y;\n const c = Math.cos(rot);\n const s = Math.sin(rot);\n\n const lx = rx * c + ry * s;\n const ly = -rx * s + ry * c;\n\n const clampedX = Math.max(-hw, Math.min(hw, lx));\n const clampedY = Math.max(-hh, Math.min(hh, ly));\n\n const dx = lx - clampedX;\n const dy = ly - clampedY;\n return dx * dx + dy * dy <= radius * radius;\n }\n\n public override intersectsBox(\n center: Vector2,\n width: number,\n height: number,\n rotation: number = 0\n ): boolean {\n // 2D OBB vs OBB SAT intersection test\n const vertsA = this.getVertices();\n const axesA = this.getNormals();\n\n const cB = Math.cos(rotation);\n const sB = Math.sin(rotation);\n const hxB = width * 0.5;\n const hyB = height * 0.5;\n\n const vertsB = [\n new Vector2(center.x + (-hxB * cB - -hyB * sB), center.y + (-hxB * sB + -hyB * cB)),\n new Vector2(center.x + (hxB * cB - -hyB * sB), center.y + (hxB * sB + -hyB * cB)),\n new Vector2(center.x + (hxB * cB - hyB * sB), center.y + (hxB * sB + hyB * cB)),\n new Vector2(center.x + (-hxB * cB - hyB * sB), center.y + (-hxB * sB + hyB * cB))\n ];\n\n const axesB = [new Vector2(cB, sB), new Vector2(-sB, cB)];\n const allAxes = [axesA[0], axesA[1], axesB[0], axesB[1]];\n\n for (let i = 0; i < 4; i++) {\n const axis = allAxes[i];\n let minA = vertsA[0].x * axis.x + vertsA[0].y * axis.y;\n let maxA = minA;\n for (let j = 1; j < 4; j++) {\n const val = vertsA[j].x * axis.x + vertsA[j].y * axis.y;\n if (val < minA) minA = val;\n if (val > maxA) maxA = val;\n }\n\n let minB = vertsB[0].x * axis.x + vertsB[0].y * axis.y;\n let maxB = minB;\n for (let j = 1; j < 4; j++) {\n const val = vertsB[j].x * axis.x + vertsB[j].y * axis.y;\n if (val < minB) minB = val;\n if (val > maxB) maxB = val;\n }\n\n if (maxA < minB || maxB < minA) return false;\n }\n\n return true;\n }\n\n public override computeMassAndInertia(\n density: number = this.density\n ): { mass: number; inertia: number } {\n const w = this.size.x;\n const h = this.size.y;\n const area = w * h;\n const mass = area * density;\n const inertiaCm = (1 / 12) * mass * (w * w + h * h);\n const offsetDistSq = this.offset.lengthSq();\n const inertia = inertiaCm + mass * offsetDistSq;\n return { mass, inertia };\n }\n\n public override clone(): BoxCollider2D {\n const copy = new BoxCollider2D({\n body: this.body,\n width: this.size.x,\n height: this.size.y,\n rotation: this.rotation,\n offset: this.offset.clone(),\n isTrigger: this.isTrigger,\n density: this.density,\n friction: this.friction,\n restitution: this.restitution,\n layer: this.layer,\n mask: this.mask,\n userData: this.userData\n });\n return copy;\n }\n}\n","import { Vector2 } from '../math/Vector2';\nimport { Collider2D } from './Collider2D';\nimport { CircleCollider2D } from './CircleCollider2D';\nimport { BoxCollider2D } from './BoxCollider2D';\nimport { ContactManifold } from './ContactSolver';\nimport { Ray2D, RaycastHit2D, Raycast } from './Raycast';\n\nexport class Narrowphase {\n // Pre-allocated vertex and normal buffers for zero-allocation hot paths\n private static readonly _vertsA: Vector2[] = [new Vector2(), new Vector2(), new Vector2(), new Vector2()];\n private static readonly _vertsB: Vector2[] = [new Vector2(), new Vector2(), new Vector2(), new Vector2()];\n private static readonly _axesA: Vector2[] = [new Vector2(), new Vector2()];\n private static readonly _axesB: Vector2[] = [new Vector2(), new Vector2()];\n\n public static test(colliderA: Collider2D, colliderB: Collider2D): ContactManifold | null {\n return this.collide(colliderA, colliderB);\n }\n\n public static collide(colliderA: Collider2D, colliderB: Collider2D): ContactManifold | null {\n if (colliderA instanceof CircleCollider2D && colliderB instanceof CircleCollider2D) {\n return this.collideCircleVsCircle(colliderA, colliderB);\n }\n if (colliderA instanceof CircleCollider2D && colliderB instanceof BoxCollider2D) {\n return this.collideCircleVsBox(colliderA, colliderB);\n }\n if (colliderA instanceof BoxCollider2D && colliderB instanceof CircleCollider2D) {\n const manifold = this.collideCircleVsBox(colliderB, colliderA);\n if (manifold === null) return null;\n manifold.normal.negateInPlace();\n manifold.bodyA = colliderA.body!;\n manifold.bodyB = colliderB.body!;\n manifold.colliderA = colliderA;\n manifold.colliderB = colliderB;\n return manifold;\n }\n if (colliderA instanceof BoxCollider2D && colliderB instanceof BoxCollider2D) {\n return this.collideBoxVsBox(colliderA, colliderB);\n }\n return null;\n }\n\n // ==========================================\n // Circle vs Circle\n // ==========================================\n\n public static testCircleCircle(circleA: CircleCollider2D, circleB: CircleCollider2D): ContactManifold | null {\n return this.collideCircleVsCircle(circleA, circleB);\n }\n\n public static collideCircleVsCircle(circleA: CircleCollider2D, circleB: CircleCollider2D): ContactManifold | null {\n const posA = circleA.getWorldPosition();\n const posB = circleB.getWorldPosition();\n const rA = circleA.radius;\n const rB = circleB.radius;\n\n const dx = posB.x - posA.x;\n const dy = posB.y - posA.y;\n const distSq = dx * dx + dy * dy;\n const radiusSum = rA + rB;\n\n if (distSq > radiusSum * radiusSum) return null;\n\n const dist = Math.sqrt(distSq);\n let normal: Vector2;\n let penetration: number;\n let contactPoint: Vector2;\n\n if (dist < 1e-6) {\n // Degenerate concentric circles fallback\n normal = new Vector2(1, 0);\n penetration = radiusSum;\n contactPoint = posA.clone();\n } else {\n normal = new Vector2(dx / dist, dy / dist);\n penetration = radiusSum - dist;\n contactPoint = new Vector2(\n posA.x + normal.x * (rA - penetration * 0.5),\n posA.y + normal.y * (rA - penetration * 0.5)\n );\n }\n\n return {\n collided: true,\n bodyA: circleA.body!,\n bodyB: circleB.body!,\n colliderA: circleA,\n colliderB: circleB,\n normal,\n penetration,\n contactPoints: [contactPoint],\n friction: Math.sqrt(circleA.friction * circleB.friction),\n restitution: Math.max(circleA.restitution, circleB.restitution)\n };\n }\n\n // ==========================================\n // Circle vs Box\n // ==========================================\n\n public static testCircleBox(circle: CircleCollider2D, box: BoxCollider2D): ContactManifold | null {\n return this.collideCircleVsBox(circle, box);\n }\n\n public static collideCircleVsBox(circle: CircleCollider2D, box: BoxCollider2D): ContactManifold | null {\n const circlePos = circle.getWorldPosition();\n const boxPos = box.getWorldPosition();\n const boxRot = box.getWorldRotation();\n const radius = circle.radius;\n const hx = box.halfExtents.x;\n const hy = box.halfExtents.y;\n\n // Transform circle center to box local space\n const relX = circlePos.x - boxPos.x;\n const relY = circlePos.y - boxPos.y;\n const cosB = Math.cos(boxRot);\n const sinB = Math.sin(boxRot);\n\n // rotate by -boxRot\n const localX = relX * cosB + relY * sinB;\n const localY = -relX * sinB + relY * cosB;\n\n // Clamp to box half-extents\n const clampedX = Math.max(-hx, Math.min(hx, localX));\n const clampedY = Math.max(-hy, Math.min(hy, localY));\n\n const diffX = localX - clampedX;\n const diffY = localY - clampedY;\n const distSq = diffX * diffX + diffY * diffY;\n\n const localToWorld = (lx: number, ly: number): Vector2 => {\n return new Vector2(\n boxPos.x + (lx * cosB - ly * sinB),\n boxPos.y + (lx * sinB + ly * cosB)\n );\n };\n\n let normLx: number;\n let normLy: number;\n let penetration: number;\n let contactPoint: Vector2;\n\n if (distSq > 1e-12) {\n // Circle center is outside box\n const dist = Math.sqrt(distSq);\n if (dist > radius) return null;\n\n // Normal pointing from Circle to Box: -(diff / dist)\n normLx = -diffX / dist;\n normLy = -diffY / dist;\n penetration = radius - dist;\n contactPoint = localToWorld(clampedX, clampedY);\n } else {\n // Circle center is inside box: push out along minimal edge\n const dx = hx - Math.abs(localX);\n const dy = hy - Math.abs(localY);\n\n let contactLx: number;\n let contactLy: number;\n\n if (dx < dy) {\n const signX = localX >= 0 ? 1 : -1;\n // Pushing from circle to box\n normLx = -signX;\n normLy = 0;\n penetration = radius + dx;\n contactLx = signX * hx;\n contactLy = localY;\n } else {\n const signY = localY >= 0 ? 1 : -1;\n normLx = 0;\n normLy = -signY;\n penetration = radius + dy;\n contactLx = localX;\n contactLy = signY * hy;\n }\n\n contactPoint = localToWorld(contactLx, contactLy);\n }\n\n const normal = new Vector2(\n normLx * cosB - normLy * sinB,\n normLx * sinB + normLy * cosB\n );\n\n return {\n collided: true,\n bodyA: circle.body!,\n bodyB: box.body!,\n colliderA: circle,\n colliderB: box,\n normal,\n penetration,\n contactPoints: [contactPoint],\n friction: Math.sqrt(circle.friction * box.friction),\n restitution: Math.max(circle.restitution, box.restitution)\n };\n }\n\n // ==========================================\n // Box vs Box (SAT + Sutherland-Hodgman)\n // ==========================================\n\n public static testBoxBox(boxA: BoxCollider2D, boxB: BoxCollider2D): ContactManifold | null {\n return this.collideBoxVsBox(boxA, boxB);\n }\n\n public static collideBoxVsBox(boxA: BoxCollider2D, boxB: BoxCollider2D): ContactManifold | null {\n const vertsA = boxA.getVertices(this._vertsA);\n const vertsB = boxB.getVertices(this._vertsB);\n const axesA = boxA.getNormals(this._axesA);\n const axesB = boxB.getNormals(this._axesB);\n\n const allAxes = [axesA[0], axesA[1], axesB[0], axesB[1]];\n let minPenetration = Infinity;\n let bestAxis: Vector2 | null = null;\n let bestAxisIndex = -1;\n\n for (let i = 0; i < 4; i++) {\n const axis = allAxes[i];\n const projA = this.projectBox(vertsA, axis);\n const projB = this.projectBox(vertsB, axis);\n\n const overlap = Math.min(projA.max, projB.max) - Math.max(projA.min, projB.min);\n if (overlap <= 0) {\n return null; // Separating axis exists\n }\n\n if (overlap < minPenetration) {\n minPenetration = overlap;\n bestAxis = axis;\n bestAxisIndex = i;\n }\n }\n\n if (!bestAxis) return null;\n\n // Normal must point from Box A to Box B\n const posA = boxA.getWorldPosition();\n const posB = boxB.getWorldPosition();\n let normal = bestAxis.clone();\n if ((posB.x - posA.x) * normal.x + (posB.y - posA.y) * normal.y < 0) {\n normal.negateInPlace();\n }\n\n // Sutherland-Hodgman contact clipping\n const aIsRef = bestAxisIndex < 2;\n const refVerts = aIsRef ? vertsA : vertsB;\n const incVerts = aIsRef ? vertsB : vertsA;\n const targetNormal = aIsRef ? normal : normal.clone().negateInPlace();\n\n // 1. Identify reference edge on reference box\n let bestEdgeDot = -Infinity;\n let refEdgeIdx = 0;\n for (let i = 0; i < 4; i++) {\n const p1 = refVerts[i];\n const p2 = refVerts[(i + 1) % 4];\n const ex = p2.x - p1.x;\n const ey = p2.y - p1.y;\n const len = Math.sqrt(ex * ex + ey * ey);\n const normX = ey / len;\n const normY = -ex / len;\n const dot = normX * targetNormal.x + normY * targetNormal.y;\n if (dot > bestEdgeDot) {\n bestEdgeDot = dot;\n refEdgeIdx = i;\n }\n }\n\n const refV1 = refVerts[refEdgeIdx];\n const refV2 = refVerts[(refEdgeIdx + 1) % 4];\n const refEdgeX = refV2.x - refV1.x;\n const refEdgeY = refV2.y - refV1.y;\n const refEdgeLen = Math.sqrt(refEdgeX * refEdgeX + refEdgeY * refEdgeY);\n const refDirX = refEdgeX / refEdgeLen;\n const refDirY = refEdgeY / refEdgeLen;\n const refNormX = refEdgeY / refEdgeLen;\n const refNormY = -refEdgeX / refEdgeLen;\n\n // 2. Identify incident edge on incident box\n let incEdgeIdx = 0;\n let bestIncDot = Infinity;\n for (let i = 0; i < 4; i++) {\n const p1 = incVerts[i];\n const p2 = incVerts[(i + 1) % 4];\n const ex = p2.x - p1.x;\n const ey = p2.y - p1.y;\n const len = Math.sqrt(ex * ex + ey * ey);\n const normX = ey / len;\n const normY = -ex / len;\n const dot = normX * refNormX + normY * refNormY;\n if (dot < bestIncDot) {\n bestIncDot = dot;\n incEdgeIdx = i;\n }\n }\n\n let incidentSegment = [\n incVerts[incEdgeIdx].clone(),\n incVerts[(incEdgeIdx + 1) % 4].clone()\n ];\n\n // 3. Clip against side planes of reference edge\n // Side Plane 1: at refV1, normal = -refDir\n incidentSegment = this.clipSegment(\n incidentSegment,\n -refDirX,\n -refDirY,\n -refDirX * refV1.x - refDirY * refV1.y\n );\n if (incidentSegment.length < 2) return null;\n\n // Side Plane 2: at refV2, normal = +refDir\n incidentSegment = this.clipSegment(\n incidentSegment,\n refDirX,\n refDirY,\n refDirX * refV2.x + refDirY * refV2.y\n );\n if (incidentSegment.length < 2) return null;\n\n // 4. Keep points behind reference face\n const contactPoints: Vector2[] = [];\n const refPlaneOffset = refNormX * refV1.x + refNormY * refV1.y;\n\n for (const pt of incidentSegment) {\n const depth = refNormX * pt.x + refNormY * pt.y - refPlaneOffset;\n if (depth <= 0.001) {\n contactPoints.push(pt);\n }\n }\n\n if (contactPoints.length === 0) {\n // Fallback: use midpoint of incident segment\n contactPoints.push(\n new Vector2(\n (incidentSegment[0].x + incidentSegment[1].x) * 0.5,\n (incidentSegment[0].y + incidentSegment[1].y) * 0.5\n )\n );\n }\n\n return {\n collided: true,\n bodyA: boxA.body!,\n bodyB: boxB.body!,\n colliderA: boxA,\n colliderB: boxB,\n normal,\n penetration: minPenetration,\n contactPoints,\n friction: Math.sqrt(boxA.friction * boxB.friction),\n restitution: Math.max(boxA.restitution, boxB.restitution)\n };\n }\n\n private static projectBox(vertices: Vector2[], axis: Vector2): { min: number; max: number } {\n let min = vertices[0].x * axis.x + vertices[0].y * axis.y;\n let max = min;\n for (let i = 1; i < 4; i++) {\n const val = vertices[i].x * axis.x + vertices[i].y * axis.y;\n if (val < min) min = val;\n if (val > max) max = val;\n }\n return { min, max };\n }\n\n private static clipSegment(vIn: Vector2[], nx: number, ny: number, offset: number): Vector2[] {\n const vOut: Vector2[] = [];\n const d0 = nx * vIn[0].x + ny * vIn[0].y - offset;\n const d1 = nx * vIn[1].x + ny * vIn[1].y - offset;\n\n if (d0 <= 0) vOut.push(vIn[0]);\n if (d1 <= 0) vOut.push(vIn[1]);\n\n if (d0 * d1 < 0) {\n const t = d0 / (d0 - d1);\n const intersect = new Vector2(\n vIn[0].x + (vIn[1].x - vIn[0].x) * t,\n vIn[0].y + (vIn[1].y - vIn[0].y) * t\n );\n if (d0 > 0) {\n vOut.unshift(intersect);\n } else {\n vOut.push(intersect);\n }\n }\n return vOut;\n }\n\n // ==========================================\n // Raycasting\n // ==========================================\n\n public static raycast(ray: Ray2D, collider: Collider2D): RaycastHit2D | null {\n return collider.raycast(ray);\n }\n\n public static raycastCircle(ray: Ray2D, circle: CircleCollider2D): RaycastHit2D | null {\n return circle.raycast(ray);\n }\n\n public static raycastBox(ray: Ray2D, box: BoxCollider2D): RaycastHit2D | null {\n return box.raycast(ray);\n }\n}\n","import { Vector2 } from '../math/Vector2';\nimport { Rect } from '../math/Rect';\nimport { EventEmitter } from '../core/EventEmitter';\nimport { RigidBody2D, BodyType } from './RigidBody2D';\nimport { Collider2D } from './Collider2D';\nimport { ContactSolver, ContactManifold } from './ContactSolver';\nimport { SpatialGrid } from './SpatialGrid';\nimport { CollisionFSM, CollisionFSMEvents } from './CollisionFSM';\nimport { Ray2D, RaycastHit2D } from './Raycast';\nimport { Narrowphase } from './Narrowphase';\n\nexport interface PhysicsWorldConfig {\n gravity?: Vector2;\n velocityIterations?: number;\n positionIterations?: number;\n subSteps?: number;\n fixedDeltaTime?: number;\n allowSleep?: boolean;\n baumgarte?: number;\n penetrationSlop?: number;\n restitutionVelocityThreshold?: number;\n spatialCellSize?: number;\n enableWarmStarting?: boolean;\n}\n\nexport interface PhysicsWorldEvents extends CollisionFSMEvents {\n 'step:pre': { dt: number; subStep: number };\n 'step:post': { dt: number; subStep: number };\n 'body:add': { body: RigidBody2D };\n 'body:remove': { body: RigidBody2D };\n 'collider:add': { collider: Collider2D };\n 'collider:remove': { collider: Collider2D };\n}\n\n/**\n * Master 2D Physics World orchestrator managing the 11-step simulation pipeline,\n * sub-stepping, spatial indexing, collision lifecycle, and spatial queries.\n */\nexport class PhysicsWorld2D extends EventEmitter<PhysicsWorldEvents> {\n public gravity: Vector2;\n public velocityIterations: number;\n public positionIterations: number;\n public subSteps: number;\n public fixedDeltaTime: number;\n public allowSleep: boolean;\n\n private _bodies: RigidBody2D[] = [];\n private _colliders: Collider2D[] = [];\n private _spatialGrid: SpatialGrid;\n private _contactSolver: ContactSolver;\n private _collisionFSM: CollisionFSM;\n\n constructor(config: PhysicsWorldConfig = {}) {\n super();\n\n this.gravity = config.gravity ? config.gravity.clone() : new Vector2(0, 980);\n this.velocityIterations = config.velocityIterations ?? 8;\n this.positionIterations = config.positionIterations ?? 3;\n this.subSteps = config.subSteps ?? 1;\n this.fixedDeltaTime = config.fixedDeltaTime ?? 1 / 60;\n this.allowSleep = config.allowSleep ?? true;\n\n this._spatialGrid = new SpatialGrid({\n cellSize: config.spatialCellSize ?? 64\n });\n\n this._contactSolver = new ContactSolver({\n velocityIterations: this.velocityIterations,\n positionIterations: this.positionIterations,\n baumgarte: config.baumgarte ?? 0.2,\n penetrationSlop: config.penetrationSlop ?? 0.02,\n restitutionVelocityThreshold: config.restitutionVelocityThreshold ?? 30.0,\n enableWarmStarting: config.enableWarmStarting ?? false\n });\n\n this._collisionFSM = new CollisionFSM(this);\n }\n\n // ==========================================\n // Registration APIs\n // ==========================================\n\n public addBody(body: RigidBody2D): this {\n if (this._bodies.includes(body)) return this;\n this._bodies.push(body);\n body.wakeUp();\n this.emit('body:add', { body });\n return this;\n }\n\n public removeBody(body: RigidBody2D): this {\n const idx = this._bodies.indexOf(body);\n if (idx === -1) return this;\n this._bodies.splice(idx, 1);\n\n // Remove any attached colliders\n for (let i = this._colliders.length - 1; i >= 0; i--) {\n if (this._colliders[i].body === body) {\n this.removeCollider(this._colliders[i]);\n }\n }\n\n this.emit('body:remove', { body });\n return this;\n }\n\n public addCollider(collider: Collider2D): this {\n if (this._colliders.includes(collider)) return this;\n this._colliders.push(collider);\n collider.updateWorldBounds();\n this._spatialGrid.insert(collider);\n this.emit('collider:add', { collider });\n return this;\n }\n\n public removeCollider(collider: Collider2D): this {\n const idx = this._colliders.indexOf(collider);\n if (idx === -1) return this;\n this._colliders.splice(idx, 1);\n\n this._spatialGrid.remove(collider);\n this._collisionFSM.handleColliderRemoved(collider);\n this.emit('collider:remove', { collider });\n return this;\n }\n\n public getBodies(): readonly RigidBody2D[] {\n return this._bodies;\n }\n\n public getColliders(): readonly Collider2D[] {\n return this._colliders;\n }\n\n public getBodyById(id: number): RigidBody2D | undefined {\n return this._bodies.find((b) => b.id === id);\n }\n\n public override clear<K extends keyof PhysicsWorldEvents>(event?: K): this {\n super.clear(event);\n if (event === undefined) {\n this._bodies = [];\n this._colliders = [];\n this._spatialGrid.clear();\n }\n return this;\n }\n\n // ==========================================\n // Simulation Step Pipeline\n // ==========================================\n\n public step(dt: number = this.fixedDeltaTime): void {\n if (dt <= 0) return;\n\n const subSteps = Math.max(1, this.subSteps);\n const subDt = dt / subSteps;\n\n for (let s = 0; s < subSteps; s++) {\n this.emit('step:pre', { dt: subDt, subStep: s });\n this._internalSubStep(subDt);\n this.emit('step:post', { dt: subDt, subStep: s });\n }\n }\n\n private _internalSubStep(dt: number): void {\n // Phase 1: Sync Inbound Transforms\n for (let i = 0; i < this._bodies.length; i++) {\n const b = this._bodies[i];\n if (b.transform && b.transform.isDirty) {\n b.syncFromTransform();\n }\n }\n\n // Phase 2: Symplectic Euler Integration (Velocity + Provisional Positions)\n for (let i = 0; i < this._bodies.length; i++) {\n this._bodies[i].integrateVelocities(dt, this.gravity);\n this._bodies[i].integratePositions(dt);\n }\n\n // Phase 3: Update Broadphase Bounds in SpatialGrid\n for (let i = 0; i < this._colliders.length; i++) {\n const c = this._colliders[i];\n c.updateWorldBounds();\n this._spatialGrid.update(c);\n }\n\n // Phase 4: Broadphase Candidate Pair Query & Multi-Tier Pruning\n const candidatePairs = this._spatialGrid.generateCandidatePairs();\n const rawManifolds: ContactManifold[] = [];\n\n for (let i = 0; i < candidatePairs.length; i++) {\n const pair = candidatePairs[i];\n const colA = pair.colliderA;\n const colB = pair.colliderB;\n const bodyA = colA.body;\n const bodyB = colB.body;\n\n // Filter 1: Static vs Static\n const isStaticA = !bodyA || bodyA.bodyType === BodyType.Static;\n const isStaticB = !bodyB || bodyB.bodyType === BodyType.Static;\n if (isStaticA && isStaticB) continue;\n\n // Filter 2: Sleeping vs Sleeping\n if (bodyA && bodyB && bodyA.isSleeping && bodyB.isSleeping) continue;\n if (\n bodyA &&\n bodyB &&\n ((bodyA.isSleeping && isStaticB) || (bodyB.isSleeping && isStaticA))\n ) {\n continue;\n }\n\n // Filter 3: Same Body\n if (bodyA && bodyB && bodyA === bodyB) continue;\n\n // Filter 4: Layer / Mask Bitfields\n if ((colA.layer & colB.mask) === 0 || (colB.layer & colA.mask) === 0) continue;\n\n // Phase 5: Narrowphase Detection & Manifold Generation\n const manifold = Narrowphase.collide(colA, colB);\n if (manifold && manifold.collided) {\n rawManifolds.push(manifold);\n }\n }\n\n // Phase 6: Collision & Trigger Lifecycle FSM\n const solidManifolds = this._collisionFSM.processManifolds(rawManifolds);\n\n // Phase 7: ContactSolver Velocity Resolution\n if (solidManifolds.length > 0) {\n this._contactSolver.preStep(solidManifolds, dt);\n this._contactSolver.solveVelocityConstraints();\n this._contactSolver.solvePositionConstraints(solidManifolds);\n }\n\n // Phase 8: Two-Way Sync Outbound to Transform2D\n for (let i = 0; i < this._bodies.length; i++) {\n const b = this._bodies[i];\n if (b.transform) {\n b.syncToTransform();\n }\n }\n\n // Phase 9: Sleep State Machine Update\n if (this.allowSleep) {\n for (let i = 0; i < this._bodies.length; i++) {\n this._bodies[i].updateSleep(dt);\n }\n }\n\n // Phase 10: End-of-Step Cleanup\n for (let i = 0; i < this._bodies.length; i++) {\n this._bodies[i].clearForces();\n }\n this._collisionFSM.endStep();\n }\n\n // ==========================================\n // Spatial Query APIs\n // ==========================================\n\n public raycast(ray: Ray2D, mask: number = 0xFFFFFFFF): RaycastHit2D | null {\n const queryDist = Number.isFinite(ray.maxDistance) && ray.maxDistance > 0\n ? Math.min(ray.maxDistance, 100000)\n : 10000;\n const candidates = this._spatialGrid.queryRay(ray, queryDist);\n let closestHit: RaycastHit2D | null = null;\n let minDistance = Infinity;\n\n for (let i = 0; i < candidates.length; i++) {\n const col = candidates[i];\n if ((col.layer & mask) === 0) continue;\n\n const hit = col.raycast(ray);\n if (hit && hit.distance < minDistance) {\n minDistance = hit.distance;\n closestHit = hit;\n }\n }\n\n return closestHit;\n }\n\n public raycastAll(ray: Ray2D, mask: number = 0xFFFFFFFF): RaycastHit2D[] {\n const queryDist = Number.isFinite(ray.maxDistance) && ray.maxDistance > 0\n ? Math.min(ray.maxDistance, 100000)\n : 10000;\n const candidates = this._spatialGrid.queryRay(ray, queryDist);\n const hits: RaycastHit2D[] = [];\n\n for (let i = 0; i < candidates.length; i++) {\n const col = candidates[i];\n if ((col.layer & mask) === 0) continue;\n\n const hit = col.raycast(ray);\n if (hit) {\n hits.push(hit);\n }\n }\n\n return hits.sort((a, b) => a.distance - b.distance);\n }\n\n public overlapCircle(center: Vector2, radius: number, mask: number = 0xFFFFFFFF): Collider2D[] {\n const bounds = new Rect(center.x - radius, center.y - radius, radius * 2, radius * 2);\n const candidates = this._spatialGrid.queryAABB(bounds);\n const results: Collider2D[] = [];\n\n for (let i = 0; i < candidates.length; i++) {\n const col = candidates[i];\n if ((col.layer & mask) === 0) continue;\n if (col.intersectsCircle(center, radius)) {\n results.push(col);\n }\n }\n\n return results;\n }\n\n public overlapBox(\n center: Vector2,\n width: number,\n height: number,\n rotation: number = 0,\n mask: number = 0xFFFFFFFF\n ): Collider2D[] {\n const r = Math.sqrt(width * width + height * height) * 0.5;\n const bounds = new Rect(center.x - r, center.y - r, r * 2, r * 2);\n const candidates = this._spatialGrid.queryAABB(bounds);\n const results: Collider2D[] = [];\n\n for (let i = 0; i < candidates.length; i++) {\n const col = candidates[i];\n if ((col.layer & mask) === 0) continue;\n if (col.intersectsBox(center, width, height, rotation)) {\n results.push(col);\n }\n }\n\n return results;\n }\n\n public overlapPoint(point: Vector2, mask: number = 0xFFFFFFFF): Collider2D[] {\n const candidates = this._spatialGrid.queryPoint(point);\n const results: Collider2D[] = [];\n\n for (let i = 0; i < candidates.length; i++) {\n const col = candidates[i];\n if ((col.layer & mask) === 0) continue;\n if (col.containsPoint(point)) {\n results.push(col);\n }\n }\n\n return results;\n }\n}\n","import type { AudioBusOptions } from './types';\n\n/**\n * AudioBus manages a Web Audio GainNode representing a named channel in the audio hierarchy.\n * Child buses route into their parent bus, inheriting master volume attenuation and mute states.\n */\nexport class AudioBus {\n public readonly name: string;\n public readonly context: AudioContext;\n public readonly gainNode: GainNode;\n\n private _parentBus: AudioBus | null = null;\n private _children: Set<AudioBus> = new Set();\n private _volume: number = 1.0;\n private _muted: boolean = false;\n\n constructor(context: AudioContext, options: AudioBusOptions) {\n this.context = context;\n this.name = options.name;\n this._volume = options.volume !== undefined ? Math.max(0, Math.min(1, options.volume)) : 1.0;\n this._muted = options.muted ?? false;\n\n this.gainNode = context.createGain();\n const initialGain = this._muted ? 0 : this._volume;\n this.gainNode.gain.setValueAtTime(initialGain, context.currentTime);\n\n if (options.parentBus) {\n this.setParentBus(options.parentBus);\n } else {\n this.gainNode.connect(context.destination);\n }\n }\n\n public get parentBus(): AudioBus | null {\n return this._parentBus;\n }\n\n public setParentBus(parent: AudioBus | null): void {\n if (this._parentBus === parent) return;\n\n try {\n this.gainNode.disconnect();\n } catch {\n // Disconnect safely in test mock environments\n }\n\n if (this._parentBus) {\n this._parentBus._children.delete(this);\n }\n\n this._parentBus = parent;\n\n if (this._parentBus) {\n this._parentBus._children.add(this);\n this.gainNode.connect(this._parentBus.gainNode);\n } else {\n this.gainNode.connect(this.context.destination);\n }\n }\n\n public get volume(): number {\n return this._volume;\n }\n\n public setVolume(vol: number, rampDuration: number = 0): this {\n this._volume = Math.max(0, Math.min(1, vol));\n if (!this._muted) {\n this._applyGain(this._volume, rampDuration);\n }\n return this;\n }\n\n public get muted(): boolean {\n return this._muted;\n }\n\n public setMuted(mute: boolean, rampDuration: number = 0): this {\n this._muted = mute;\n const targetGain = this._muted ? 0 : this._volume;\n this._applyGain(targetGain, rampDuration);\n return this;\n }\n\n public toggleMute(rampDuration: number = 0): boolean {\n this.setMuted(!this._muted, rampDuration);\n return this._muted;\n }\n\n public get effectiveVolume(): number {\n const parentVol = this._parentBus ? this._parentBus.effectiveVolume : 1.0;\n return this._muted ? 0 : this._volume * parentVol;\n }\n\n public get isEffectiveMuted(): boolean {\n if (this._muted) return true;\n return this._parentBus ? this._parentBus.isEffectiveMuted : false;\n }\n\n public createChildBus(name: string, volume: number = 1.0): AudioBus {\n return new AudioBus(this.context, {\n name,\n volume,\n parentBus: this\n });\n }\n\n public connectSource(sourceNode: AudioNode): void {\n sourceNode.connect(this.gainNode);\n }\n\n public disconnectSource(sourceNode: AudioNode): void {\n try {\n sourceNode.disconnect(this.gainNode);\n } catch {\n // Ignore disconnect errors\n }\n }\n\n private _applyGain(value: number, rampDuration: number): void {\n const now = this.context.currentTime;\n const gainParam = this.gainNode.gain;\n if (rampDuration > 0) {\n gainParam.setValueAtTime(gainParam.value, now);\n gainParam.linearRampToValueAtTime(value, now + rampDuration);\n } else {\n gainParam.setValueAtTime(value, now);\n }\n }\n\n public destroy(): void {\n try {\n this.gainNode.disconnect();\n } catch {}\n if (this._parentBus) {\n this._parentBus._children.delete(this);\n this._parentBus = null;\n }\n this._children.clear();\n }\n}\n","import type { AudioBus } from './AudioBus';\nimport type { ActiveVoice, SoundPlayOptions, VoicePoolConfig } from './types';\n\n/**\n * VoicePool coordinates polyphonic sound playback with concurrency limits and oldest-voice stealing.\n */\nexport class VoicePool {\n public readonly context: AudioContext;\n public readonly maxVoices: number;\n public readonly maxInstancesPerKey: number;\n public readonly stealFadeDuration: number;\n\n private _activeVoices: Map<number, ActiveVoice> = new Map();\n private _nextVoiceId: number = 1;\n\n constructor(context: AudioContext, config?: VoicePoolConfig) {\n this.context = context;\n this.maxVoices = config?.maxVoices ?? 32;\n this.maxInstancesPerKey = config?.maxInstancesPerKey ?? 8;\n this.stealFadeDuration = config?.stealFadeDuration ?? 0.01;\n }\n\n public play(buffer: AudioBuffer, bus: AudioBus, options?: SoundPlayOptions): number {\n const key = (options as any)?.key ?? options?.bus ?? 'default';\n\n // 1. Enforce per-key concurrency limit\n this._enforceKeyLimit(key);\n\n // 2. Enforce global concurrency limit\n if (this._activeVoices.size >= this.maxVoices) {\n this._stealOldestVoice();\n }\n\n const voiceId = this._nextVoiceId++;\n const now = this.context.currentTime;\n\n // Create per-voice gain for fading and individual volume\n const voiceGain = this.context.createGain();\n const targetVol = Math.max(0, Math.min(1, options?.volume ?? 1.0));\n\n if (options?.fadeInDuration && options.fadeInDuration > 0) {\n voiceGain.gain.setValueAtTime(0, now);\n voiceGain.gain.linearRampToValueAtTime(targetVol, now + options.fadeInDuration);\n } else {\n voiceGain.gain.setValueAtTime(targetVol, now);\n }\n\n voiceGain.connect(bus.gainNode);\n\n // Create buffer source node\n const sourceNode = this.context.createBufferSource();\n sourceNode.buffer = buffer;\n\n // Apply pitch and random pitch jitter\n let playbackRate = options?.pitch ?? 1.0;\n if (options?.pitchRandom && options.pitchRandom > 0) {\n const jitter = (Math.random() * 2 - 1) * options.pitchRandom;\n playbackRate *= (1 + jitter);\n }\n sourceNode.playbackRate.setValueAtTime(Math.max(0.1, playbackRate), now);\n\n // Loop configuration\n sourceNode.loop = !!options?.loop;\n if (options?.loopStart !== undefined) sourceNode.loopStart = options.loopStart;\n if (options?.loopEnd !== undefined) sourceNode.loopEnd = options.loopEnd;\n\n sourceNode.connect(voiceGain);\n\n const voiceDesc: ActiveVoice = {\n id: voiceId,\n key,\n sourceNode,\n gainNode: voiceGain,\n startTime: now,\n duration: options?.duration ?? (buffer.duration / playbackRate),\n loop: sourceNode.loop,\n bus\n };\n\n this._activeVoices.set(voiceId, voiceDesc);\n\n // Auto-cleanup on end\n sourceNode.onended = () => {\n this._cleanupVoice(voiceId);\n };\n\n const offset = options?.offset ?? 0;\n if (options?.duration) {\n sourceNode.start(now, offset, options.duration);\n } else {\n sourceNode.start(now, offset);\n }\n\n return voiceId;\n }\n\n public stop(voiceId: number, fadeDuration?: number): boolean {\n const voice = this._activeVoices.get(voiceId);\n if (!voice) return false;\n\n const fade = fadeDuration !== undefined ? fadeDuration : 0;\n const now = this.context.currentTime;\n\n if (fade > 0) {\n try {\n voice.gainNode.gain.setValueAtTime(voice.gainNode.gain.value, now);\n voice.gainNode.gain.linearRampToValueAtTime(0, now + fade);\n } catch {}\n this._activeVoices.delete(voiceId);\n setTimeout(() => {\n try {\n voice.sourceNode.stop();\n voice.sourceNode.disconnect();\n voice.gainNode.disconnect();\n } catch {}\n }, fade * 1000);\n } else {\n try {\n voice.sourceNode.stop();\n } catch {}\n this._cleanupVoice(voiceId);\n }\n\n return true;\n }\n\n public stopKey(key: string, fadeDuration?: number): number {\n let stoppedCount = 0;\n for (const [id, voice] of Array.from(this._activeVoices.entries())) {\n if (voice.key === key) {\n this.stop(id, fadeDuration);\n stoppedCount++;\n }\n }\n return stoppedCount;\n }\n\n public stopAll(fadeDuration?: number): void {\n const voiceIds = Array.from(this._activeVoices.keys());\n for (const id of voiceIds) {\n this.stop(id, fadeDuration);\n }\n }\n\n public getActiveCount(): number {\n return this._activeVoices.size;\n }\n\n public getActiveCountForKey(key: string): number {\n let count = 0;\n for (const voice of this._activeVoices.values()) {\n if (voice.key === key) count++;\n }\n return count;\n }\n\n public hasVoice(voiceId: number): boolean {\n return this._activeVoices.has(voiceId);\n }\n\n private _enforceKeyLimit(key: string): void {\n const keyVoices: ActiveVoice[] = [];\n for (const voice of this._activeVoices.values()) {\n if (voice.key === key) keyVoices.push(voice);\n }\n\n if (keyVoices.length >= this.maxInstancesPerKey) {\n keyVoices.sort((a, b) => a.startTime - b.startTime);\n const oldest = keyVoices[0];\n this.stop(oldest.id, this.stealFadeDuration);\n }\n }\n\n private _stealOldestVoice(): void {\n let oldest: ActiveVoice | null = null;\n for (const voice of this._activeVoices.values()) {\n if (!oldest || voice.startTime < oldest.startTime) {\n oldest = voice;\n }\n }\n if (oldest) {\n this.stop(oldest.id, this.stealFadeDuration);\n }\n }\n\n private _cleanupVoice(voiceId: number): void {\n const voice = this._activeVoices.get(voiceId);\n if (!voice) return;\n\n voice.sourceNode.onended = null;\n try {\n voice.sourceNode.disconnect();\n } catch {}\n try {\n voice.gainNode.disconnect();\n } catch {}\n\n this._activeVoices.delete(voiceId);\n }\n\n public destroy(): void {\n this.stopAll(0);\n this._activeVoices.clear();\n }\n}\n","import type { SynthParams, WaveformType } from './types';\n\nexport interface ProceduralSoundOptions {\n volume?: number;\n sampleRate?: number;\n}\n\n/**\n * ProceduralAudio generates classic 8-bit retro sound effects using standard Web Audio nodes\n * and direct mathematical buffer synthesis without any external audio asset files.\n */\nexport class ProceduralAudio {\n /**\n * Generates a custom synth tone buffer based on frequency envelope parameters.\n */\n public static createSynthBuffer(context: AudioContext, params: SynthParams): AudioBuffer {\n const sampleRate = context.sampleRate || 44100;\n const duration = Math.max(0.01, params.duration);\n const length = Math.floor(sampleRate * duration);\n const buffer = context.createBuffer(1, length, sampleRate);\n const data = buffer.getChannelData(0);\n\n const startFreq = params.startFreq;\n const endFreq = params.endFreq ?? params.startFreq;\n const volume = Math.max(0, Math.min(1, params.volume ?? 0.8));\n const attack = Math.min(duration, params.attack ?? 0.005);\n const decay = params.decay ?? (duration - attack);\n const waveform = params.waveform ?? 'sine';\n\n let phase = 0;\n for (let i = 0; i < length; i++) {\n const t = i / sampleRate;\n const freqFrac = t / duration;\n const currentFreq = startFreq + (endFreq - startFreq) * freqFrac;\n const deltaPhase = (2 * Math.PI * currentFreq) / sampleRate;\n phase += deltaPhase;\n\n let sample = 0;\n switch (waveform) {\n case 'square':\n sample = Math.sin(phase) >= 0 ? 1 : -1;\n break;\n case 'sawtooth':\n sample = 2 * ((phase / (2 * Math.PI)) % 1) - 1;\n break;\n case 'triangle':\n sample = 2 * Math.abs(2 * ((phase / (2 * Math.PI)) % 1) - 1) - 1;\n break;\n case 'sine':\n default:\n sample = Math.sin(phase);\n break;\n }\n\n let env = 1.0;\n if (t < attack) {\n env = t / attack;\n } else {\n const decayTime = t - attack;\n env = Math.max(0, 1.0 - (decayTime / Math.max(0.001, decay)));\n }\n\n data[i] = Math.max(-1.0, Math.min(1.0, sample * env * volume));\n }\n\n return buffer;\n }\n\n /**\n * Laser Sound: Frequency sweep downwards (880Hz -> 220Hz over 0.15s, square wave).\n */\n public static createLaserBuffer(context: AudioContext, options?: ProceduralSoundOptions): AudioBuffer {\n const sampleRate = context.sampleRate || 44100;\n const duration = 0.15;\n const length = Math.floor(sampleRate * duration);\n const buffer = context.createBuffer(1, length, sampleRate);\n const data = buffer.getChannelData(0);\n const volume = options?.volume ?? 0.7;\n\n let phase = 0;\n for (let i = 0; i < length; i++) {\n const t = i / sampleRate;\n const freq = 880 * Math.pow(220 / 880, t / duration);\n phase += (2 * Math.PI * freq) / sampleRate;\n const square = Math.sin(phase) >= 0 ? 0.8 : -0.8;\n const env = Math.pow(1 - t / duration, 1.2);\n data[i] = Math.max(-1.0, Math.min(1.0, square * env * volume));\n }\n return buffer;\n }\n\n /**\n * Explosion Sound: Low-frequency noise buffer with exponential gain decay (0.45s).\n */\n public static createExplosionBuffer(context: AudioContext, options?: ProceduralSoundOptions): AudioBuffer {\n const sampleRate = context.sampleRate || 44100;\n const duration = 0.45;\n const length = Math.floor(sampleRate * duration);\n const buffer = context.createBuffer(1, length, sampleRate);\n const data = buffer.getChannelData(0);\n const volume = options?.volume ?? 0.85;\n\n let lastSample = 0;\n for (let i = 0; i < length; i++) {\n const t = i / sampleRate;\n const whiteNoise = Math.random() * 2 - 1;\n\n // 1-pole lowpass filter with cutoff sweeping down from 800Hz to 60Hz\n const cutoff = 800 * Math.pow(60 / 800, t / duration);\n const alpha = (2 * Math.PI * cutoff / sampleRate) / (1 + (2 * Math.PI * cutoff / sampleRate));\n lastSample = lastSample + alpha * (whiteNoise - lastSample);\n\n // Attack (5ms) followed by exponential decay\n const attackEnv = Math.min(1.0, t / 0.005);\n const decayEnv = Math.exp(-6.0 * (t / duration));\n data[i] = Math.max(-1.0, Math.min(1.0, lastSample * attackEnv * decayEnv * volume));\n }\n return buffer;\n }\n\n /**\n * Jump Sound: Upward frequency sweep (150Hz -> 600Hz over 0.18s, square wave).\n */\n public static createJumpBuffer(context: AudioContext, options?: ProceduralSoundOptions): AudioBuffer {\n const sampleRate = context.sampleRate || 44100;\n const duration = 0.18;\n const length = Math.floor(sampleRate * duration);\n const buffer = context.createBuffer(1, length, sampleRate);\n const data = buffer.getChannelData(0);\n const volume = options?.volume ?? 0.7;\n\n let phase = 0;\n for (let i = 0; i < length; i++) {\n const t = i / sampleRate;\n const freq = 150 + (600 - 150) * (t / duration);\n phase += (2 * Math.PI * freq) / sampleRate;\n const wave = Math.sin(phase) >= 0 ? 0.75 : -0.75;\n const env = t < 0.14 ? 1.0 : Math.max(0, 1.0 - (t - 0.14) / 0.04);\n data[i] = Math.max(-1.0, Math.min(1.0, wave * env * volume));\n }\n return buffer;\n }\n\n /**\n * Coin Sound: Two-tone chime (987.77Hz [B5] for 0.08s -> 1318.51Hz [E6] for 0.22s).\n */\n public static createCoinBuffer(context: AudioContext, options?: ProceduralSoundOptions): AudioBuffer {\n const sampleRate = context.sampleRate || 44100;\n const duration = 0.30;\n const length = Math.floor(sampleRate * duration);\n const buffer = context.createBuffer(1, length, sampleRate);\n const data = buffer.getChannelData(0);\n const volume = options?.volume ?? 0.75;\n\n let phase = 0;\n for (let i = 0; i < length; i++) {\n const t = i / sampleRate;\n const isSecondTone = t >= 0.08;\n const freq = isSecondTone ? 1318.51 : 987.77;\n phase += (2 * Math.PI * freq) / sampleRate;\n\n const sine = Math.sin(phase);\n const tone = 0.8 * sine + 0.2 * (sine >= 0 ? 1 : -1);\n\n let env = 1.0;\n if (isSecondTone) {\n const decayTime = t - 0.08;\n env = Math.pow(Math.max(0, 1 - decayTime / 0.22), 1.5);\n }\n data[i] = Math.max(-1.0, Math.min(1.0, tone * env * volume));\n }\n return buffer;\n }\n\n /**\n * Hit Sound: Sudden pitch drop with high damping (300Hz -> 60Hz, 0.12s).\n */\n public static createHitBuffer(context: AudioContext, options?: ProceduralSoundOptions): AudioBuffer {\n const sampleRate = context.sampleRate || 44100;\n const duration = 0.12;\n const length = Math.floor(sampleRate * duration);\n const buffer = context.createBuffer(1, length, sampleRate);\n const data = buffer.getChannelData(0);\n const volume = options?.volume ?? 0.85;\n\n let phase = 0;\n for (let i = 0; i < length; i++) {\n const t = i / sampleRate;\n const freq = 300 * Math.pow(60 / 300, t / duration);\n phase += (2 * Math.PI * freq) / sampleRate;\n const saw = 2 * ((phase / (2 * Math.PI)) % 1) - 1;\n const noise = (Math.random() * 2 - 1) * 0.2;\n const env = Math.exp(-12 * (t / duration));\n data[i] = Math.max(-1.0, Math.min(1.0, (saw + noise) * env * volume));\n }\n return buffer;\n }\n\n /**\n * Powerup Sound: 4-note ascending arpeggio (C5: 523Hz, E5: 659Hz, G5: 784Hz, C6: 1046Hz).\n */\n public static createPowerupBuffer(context: AudioContext, options?: ProceduralSoundOptions): AudioBuffer {\n const sampleRate = context.sampleRate || 44100;\n const duration = 0.36;\n const length = Math.floor(sampleRate * duration);\n const buffer = context.createBuffer(1, length, sampleRate);\n const data = buffer.getChannelData(0);\n const volume = options?.volume ?? 0.75;\n\n const notes = [523.25, 659.25, 783.99, 1046.50];\n const noteDuration = 0.08;\n\n let phase = 0;\n for (let i = 0; i < length; i++) {\n const t = i / sampleRate;\n const noteIndex = Math.min(notes.length - 1, Math.floor(t / noteDuration));\n const freq = notes[noteIndex];\n phase += (2 * Math.PI * freq) / sampleRate;\n\n const tri = 2 * Math.abs(2 * ((phase / (2 * Math.PI)) % 1) - 1) - 1;\n\n let env = 1.0;\n if (noteIndex === notes.length - 1) {\n const lastNoteTime = t - (notes.length - 1) * noteDuration;\n env = Math.max(0, 1.0 - lastNoteTime / (duration - (notes.length - 1) * noteDuration));\n }\n data[i] = Math.max(-1.0, Math.min(1.0, tri * env * volume));\n }\n return buffer;\n }\n\n /**\n * Real-time oscillator player for Laser.\n */\n public static playLaser(context: AudioContext, destination: AudioNode, options?: ProceduralSoundOptions): AudioNode {\n const now = context.currentTime;\n const osc = context.createOscillator();\n const gain = context.createGain();\n const volume = options?.volume ?? 0.7;\n\n osc.type = 'square';\n osc.frequency.setValueAtTime(880, now);\n osc.frequency.exponentialRampToValueAtTime(220, now + 0.15);\n\n gain.gain.setValueAtTime(volume, now);\n gain.gain.linearRampToValueAtTime(0, now + 0.15);\n\n osc.connect(gain);\n gain.connect(destination);\n\n osc.start(now);\n osc.stop(now + 0.15);\n return gain;\n }\n\n /**\n * Real-time oscillator player for Jump.\n */\n public static playJump(context: AudioContext, destination: AudioNode, options?: ProceduralSoundOptions): AudioNode {\n const now = context.currentTime;\n const osc = context.createOscillator();\n const gain = context.createGain();\n const volume = options?.volume ?? 0.7;\n\n osc.type = 'square';\n osc.frequency.setValueAtTime(150, now);\n osc.frequency.exponentialRampToValueAtTime(600, now + 0.18);\n\n gain.gain.setValueAtTime(volume, now);\n gain.gain.setValueAtTime(volume, now + 0.14);\n gain.gain.linearRampToValueAtTime(0, now + 0.18);\n\n osc.connect(gain);\n gain.connect(destination);\n\n osc.start(now);\n osc.stop(now + 0.18);\n return gain;\n }\n}\n","import { EventEmitter } from '../core/EventEmitter';\nimport { AudioBus } from './AudioBus';\nimport { VoicePool } from './VoicePool';\nimport { ProceduralAudio } from './ProceduralAudio';\nimport type {\n MusicPlayOptions,\n SoundManagerEvents,\n SoundPlayOptions,\n SynthParams,\n VoicePoolConfig\n} from './types';\n\n/**\n * SoundManager coordinates the framework's Web Audio subsystem.\n */\nexport class SoundManager extends EventEmitter<SoundManagerEvents> {\n private _context: AudioContext | null = null;\n private _isUnlocked: boolean = false;\n private _unlockListenersAttached: boolean = false;\n private _boundUnlockHandler: (() => void) | null = null;\n\n // Buses\n private _masterBus: AudioBus | null = null;\n private _musicBus: AudioBus | null = null;\n private _sfxBus: AudioBus | null = null;\n private _buses: Map<string, AudioBus> = new Map();\n\n // Voice Pool\n private _voicePool: VoicePool | null = null;\n\n // Sound Buffer Cache\n private _buffers: Map<string, AudioBuffer> = new Map();\n\n // Active Background Music State\n private _currentMusicVoiceId: number | null = null;\n private _currentMusicKey: string | null = null;\n private _currentMusicGain: GainNode | null = null;\n private _currentMusicSource: AudioBufferSourceNode | null = null;\n private _isMusicPlaying: boolean = false;\n\n constructor() {\n super();\n this.init();\n }\n\n /**\n * Initializes the AudioContext and setup default buses.\n */\n public init(): void {\n if (this._context) return;\n\n const AudioContextClass = (globalThis as any).AudioContext ||\n (globalThis as any).webkitAudioContext;\n\n if (AudioContextClass) {\n try {\n this._context = new AudioContextClass();\n } catch (err) {\n console.warn('SoundManager: Failed to construct AudioContext', err);\n }\n }\n\n if (this._context) {\n this._masterBus = new AudioBus(this._context, { name: 'master', volume: 1.0 });\n this._musicBus = this._masterBus.createChildBus('music', 1.0);\n this._sfxBus = this._masterBus.createChildBus('sfx', 1.0);\n\n this._buses.set('master', this._masterBus);\n this._buses.set('music', this._musicBus);\n this._buses.set('sfx', this._sfxBus);\n\n this._voicePool = new VoicePool(this._context);\n\n // Pre-bake procedural sounds into buffer cache for immediate zero-asset playback\n this._prebakeProceduralSounds();\n\n // Check unlock status\n if (this._context.state === 'running') {\n this._isUnlocked = true;\n } else {\n this._attachAutoplayUnlockListeners();\n }\n }\n }\n\n public get context(): AudioContext | null {\n return this._context;\n }\n\n public get state(): string {\n return this._context?.state ?? 'closed';\n }\n\n public get isUnlocked(): boolean {\n return this._isUnlocked;\n }\n\n /**\n * Explicitly triggers an unlock attempt via resume().\n */\n public async unlock(): Promise<boolean> {\n if (!this._context) return false;\n if (this._context.state === 'suspended') {\n try {\n await this._context.resume();\n } catch {}\n }\n if (this._context.state === 'running') {\n this._handleUnlocked();\n return true;\n }\n return false;\n }\n\n private _attachAutoplayUnlockListeners(): void {\n if (this._unlockListenersAttached || typeof window === 'undefined') return;\n\n const events = ['click', 'touchstart', 'touchend', 'keydown', 'pointerdown'];\n this._boundUnlockHandler = () => {\n if (!this._context) return;\n if (this._context.state === 'suspended') {\n this._context.resume().then(() => {\n if (this._context?.state === 'running') {\n this._handleUnlocked();\n }\n }).catch(() => {});\n } else if (this._context.state === 'running') {\n this._handleUnlocked();\n }\n };\n\n for (const evt of events) {\n window.addEventListener(evt, this._boundUnlockHandler, { passive: true, once: false });\n }\n this._unlockListenersAttached = true;\n }\n\n private _handleUnlocked(): void {\n this._isUnlocked = true;\n this._detachAutoplayUnlockListeners();\n this.emit('unlock');\n this.emit('statechange', 'running');\n }\n\n private _detachAutoplayUnlockListeners(): void {\n if (!this._unlockListenersAttached || !this._boundUnlockHandler || typeof window === 'undefined') return;\n\n const events = ['click', 'touchstart', 'touchend', 'keydown', 'pointerdown'];\n for (const evt of events) {\n window.removeEventListener(evt, this._boundUnlockHandler);\n }\n this._unlockListenersAttached = false;\n this._boundUnlockHandler = null;\n }\n\n // --- Volume & Bus Controls ---\n\n public get masterVolume(): number {\n return this._masterBus?.volume ?? 1.0;\n }\n\n public setMasterVolume(vol: number, rampDuration: number = 0): void {\n this._masterBus?.setVolume(vol, rampDuration);\n this.emit('volumechange', { bus: 'master', volume: this.masterVolume });\n }\n\n public get musicVolume(): number {\n return this._musicBus?.volume ?? 1.0;\n }\n\n public setMusicVolume(vol: number, rampDuration: number = 0): void {\n this._musicBus?.setVolume(vol, rampDuration);\n this.emit('volumechange', { bus: 'music', volume: this.musicVolume });\n }\n\n public get sfxVolume(): number {\n return this._sfxBus?.volume ?? 1.0;\n }\n\n public setSfxVolume(vol: number, rampDuration: number = 0): void {\n this._sfxBus?.setVolume(vol, rampDuration);\n this.emit('volumechange', { bus: 'sfx', volume: this.sfxVolume });\n }\n\n public get isMuted(): boolean {\n return this._masterBus?.muted ?? false;\n }\n\n public mute(rampDuration: number = 0): void {\n this._masterBus?.setMuted(true, rampDuration);\n this.emit('mutechange', true);\n }\n\n public unmute(rampDuration: number = 0): void {\n this._masterBus?.setMuted(false, rampDuration);\n this.emit('mutechange', false);\n }\n\n public toggleMute(rampDuration: number = 0): boolean {\n const muted = this._masterBus?.toggleMute(rampDuration) ?? false;\n this.emit('mutechange', muted);\n return muted;\n }\n\n public getBus(name: string): AudioBus | undefined {\n return this._buses.get(name);\n }\n\n public createBus(name: string, parentName: string = 'master'): AudioBus {\n if (!this._context) throw new Error('SoundManager: AudioContext uninitialized');\n const parent = this.getBus(parentName) ?? this._masterBus!;\n const bus = parent.createChildBus(name);\n this._buses.set(name, bus);\n return bus;\n }\n\n // --- Sound Asset Registration & Caching ---\n\n public registerSound(key: string, buffer: AudioBuffer): void {\n this._buffers.set(key, buffer);\n }\n\n public hasSound(key: string): boolean {\n return this._buffers.has(key);\n }\n\n public getSound(key: string): AudioBuffer | undefined {\n return this._buffers.get(key);\n }\n\n public async loadSound(key: string, url: string): Promise<AudioBuffer> {\n if (!this._context) throw new Error('SoundManager: AudioContext uninitialized');\n if (this._buffers.has(key)) return this._buffers.get(key)!;\n\n const response = await fetch(url);\n if (!response.ok) {\n throw new Error(`SoundManager: Failed to fetch sound from ${url} (status: ${response.status})`);\n }\n const arrayBuffer = await response.arrayBuffer();\n const audioBuffer = await (this._context as any).decodeAudioData(arrayBuffer);\n this.registerSound(key, audioBuffer);\n return audioBuffer;\n }\n\n // --- Playback Operations ---\n\n public playSound(key: string, options?: SoundPlayOptions): number {\n if (!this._context || !this._voicePool) return -1;\n\n const buffer = this._buffers.get(key);\n if (!buffer) {\n console.warn(`SoundManager: Sound \"${key}\" not found in cache.`);\n return -1;\n }\n\n const targetBus = (options?.bus ? this.getBus(options.bus) : null) ?? this._sfxBus!;\n return this._voicePool.play(buffer, targetBus, {\n ...options,\n key\n } as any);\n }\n\n public stopSound(voiceId: number, fadeDuration?: number): boolean {\n return this._voicePool?.stop(voiceId, fadeDuration) ?? false;\n }\n\n public stopAllSfx(fadeDuration?: number): void {\n this._voicePool?.stopAll(fadeDuration);\n }\n\n // --- Background Music (BGM) Operations ---\n\n public playMusic(key: string, options?: MusicPlayOptions): void {\n if (!this._context || !this._musicBus) return;\n\n const buffer = this._buffers.get(key);\n if (!buffer) {\n console.warn(`SoundManager: Music \"${key}\" not found in cache.`);\n return;\n }\n\n const crossFade = options?.crossFadeDuration ?? 0.5;\n const now = this._context.currentTime;\n\n // Cross-fade out existing music if playing\n if (this._currentMusicGain && this._currentMusicSource && this._isMusicPlaying) {\n const oldGain = this._currentMusicGain;\n const oldSource = this._currentMusicSource;\n try {\n oldGain.gain.setValueAtTime(oldGain.gain.value, now);\n oldGain.gain.linearRampToValueAtTime(0, now + crossFade);\n setTimeout(() => {\n try { oldSource.stop(); oldSource.disconnect(); oldGain.disconnect(); } catch {}\n }, crossFade * 1000);\n } catch {}\n }\n\n // Create new music track source and track-level gain node\n const trackGain = this._context.createGain();\n const targetVol = Math.max(0, Math.min(1, options?.volume ?? 1.0));\n\n if (crossFade > 0 || (options?.fadeInDuration && options.fadeInDuration > 0)) {\n const fadeTime = options?.fadeInDuration ?? crossFade;\n trackGain.gain.setValueAtTime(0, now);\n trackGain.gain.linearRampToValueAtTime(targetVol, now + fadeTime);\n } else {\n trackGain.gain.setValueAtTime(targetVol, now);\n }\n\n trackGain.connect(this._musicBus.gainNode);\n\n const source = this._context.createBufferSource();\n source.buffer = buffer;\n source.loop = options?.loop !== false;\n source.connect(trackGain);\n\n source.start(now);\n\n this._currentMusicGain = trackGain;\n this._currentMusicSource = source;\n this._currentMusicKey = key;\n this._isMusicPlaying = true;\n }\n\n public pauseMusic(): void {\n if (!this._context || !this._isMusicPlaying) return;\n this.stopMusic(0.1);\n }\n\n public resumeMusic(): void {\n if (this._currentMusicKey) {\n this.playMusic(this._currentMusicKey);\n }\n }\n\n public stopMusic(fadeDuration: number = 0.2): void {\n if (!this._currentMusicGain || !this._currentMusicSource) return;\n const now = this._context?.currentTime ?? 0;\n const gain = this._currentMusicGain;\n const source = this._currentMusicSource;\n\n if (fadeDuration > 0) {\n try {\n gain.gain.setValueAtTime(gain.gain.value, now);\n gain.gain.linearRampToValueAtTime(0, now + fadeDuration);\n setTimeout(() => {\n try { source.stop(); source.disconnect(); gain.disconnect(); } catch {}\n }, fadeDuration * 1000);\n } catch {}\n } else {\n try { source.stop(); source.disconnect(); gain.disconnect(); } catch {}\n }\n\n this._isMusicPlaying = false;\n }\n\n public isMusicPlaying(): boolean {\n return this._isMusicPlaying;\n }\n\n // --- Procedural 8-Bit Audio Shortcuts ---\n\n public playLaser(options?: SoundPlayOptions): number {\n return this.playSound('laser', options);\n }\n\n public playExplosion(options?: SoundPlayOptions): number {\n return this.playSound('explosion', options);\n }\n\n public playJump(options?: SoundPlayOptions): number {\n return this.playSound('jump', options);\n }\n\n public playCoin(options?: SoundPlayOptions): number {\n return this.playSound('coin', options);\n }\n\n public playHit(options?: SoundPlayOptions): number {\n return this.playSound('hit', options);\n }\n\n public playPowerup(options?: SoundPlayOptions): number {\n return this.playSound('powerup', options);\n }\n\n public playSynth(params: SynthParams, options?: SoundPlayOptions): number {\n if (!this._context || !this._voicePool) return -1;\n const buffer = ProceduralAudio.createSynthBuffer(this._context, params);\n const bus = (options?.bus ? this.getBus(options.bus) : null) ?? this._sfxBus!;\n return this._voicePool.play(buffer, bus, options);\n }\n\n // --- Lifecycle & Cleanup ---\n\n private _prebakeProceduralSounds(): void {\n if (!this._context) return;\n this.registerSound('laser', ProceduralAudio.createLaserBuffer(this._context));\n this.registerSound('explosion', ProceduralAudio.createExplosionBuffer(this._context));\n this.registerSound('jump', ProceduralAudio.createJumpBuffer(this._context));\n this.registerSound('coin', ProceduralAudio.createCoinBuffer(this._context));\n this.registerSound('hit', ProceduralAudio.createHitBuffer(this._context));\n this.registerSound('powerup', ProceduralAudio.createPowerupBuffer(this._context));\n }\n\n public stopAll(): void {\n this.stopAllSfx();\n this.stopMusic(0);\n }\n\n public destroy(): void {\n this.stopAll();\n this._detachAutoplayUnlockListeners();\n this._voicePool?.destroy();\n this._masterBus?.destroy();\n this._buses.clear();\n this._buffers.clear();\n\n if (this._context && this._context.state !== 'closed') {\n try {\n this._context.close();\n } catch {}\n }\n this._context = null;\n this._isUnlocked = false;\n this.clear();\n }\n}\n","import { EventEmitter } from '../core/EventEmitter';\n\n/**\n * Internal event map for Blackboard subscriptions.\n */\ninterface BlackboardEventMap {\n change: { key: string; value: any; oldValue: any };\n clear: void;\n [key: `change:${string}`]: { value: any; oldValue: any };\n}\n\n/**\n * Persistent cross-scene observable data store.\n * Supports typed gets/sets, atomic increments, boolean toggles, change observers,\n * and JSON / LocalStorage serialization.\n */\nexport class Blackboard {\n private _data: Map<string, any> = new Map();\n private _emitter: EventEmitter<BlackboardEventMap> = new EventEmitter();\n\n /**\n * Set a key-value pair and notify registered listeners.\n */\n public set<T = any>(key: string, value: T): this {\n const oldValue = this._data.get(key);\n if (oldValue === value && this._data.has(key)) {\n return this;\n }\n\n this._data.set(key, value);\n\n // Emit specific key event and generic change event\n const payload = { value, oldValue };\n this._emitter.emit(`change:${key}` as any, payload as any);\n this._emitter.emit('change', { key, value, oldValue });\n\n return this;\n }\n\n /**\n * Get a stored value with optional fallback default.\n */\n public get<T = any>(key: string, defaultValue?: T): T {\n if (this._data.has(key)) {\n return this._data.get(key) as T;\n }\n return defaultValue as T;\n }\n\n /**\n * Check if key exists in the store.\n */\n public has(key: string): boolean {\n return this._data.has(key);\n }\n\n /**\n * Remove a key and notify listeners with value undefined.\n */\n public delete(key: string): boolean {\n if (!this._data.has(key)) return false;\n\n const oldValue = this._data.get(key);\n this._data.delete(key);\n\n const payload = { value: undefined, oldValue };\n this._emitter.emit(`change:${key}` as any, payload as any);\n this._emitter.emit('change', { key, value: undefined, oldValue });\n\n return true;\n }\n\n /**\n * Clear all entries.\n */\n public clear(): void {\n if (this._data.size === 0) return;\n this._data.clear();\n this._emitter.emit('clear');\n }\n\n /**\n * Atomic numeric increment.\n * If key does not exist, defaults to 0 and adds delta.\n * @returns Updated numeric value.\n */\n public increment(key: string, delta: number = 1): number {\n const current = typeof this.get(key) === 'number' ? (this.get(key) as number) : 0;\n const updated = current + delta;\n this.set(key, updated);\n return updated;\n }\n\n /**\n * Atomic numeric decrement.\n * @returns Updated numeric value.\n */\n public decrement(key: string, delta: number = 1): number {\n return this.increment(key, -delta);\n }\n\n /**\n * Atomic boolean toggle.\n * If key does not exist, treats current as false and sets to true.\n * @returns Updated boolean value.\n */\n public toggle(key: string): boolean {\n const current = Boolean(this.get(key, false));\n const updated = !current;\n this.set(key, updated);\n return updated;\n }\n\n /**\n * Subscribe to value changes for a specific key.\n * @returns Disposer function that unsubscribes the listener when called.\n */\n public onChange<T = any>(\n key: string,\n callback: (value: T, oldValue: T | undefined) => void\n ): () => void {\n const listener = (payload: { value: T; oldValue: T }) => {\n callback(payload.value, payload.oldValue);\n };\n return this._emitter.subscribe(`change:${key}` as any, listener);\n }\n\n /**\n * Subscribe to all value changes across the entire store.\n * @returns Disposer function that unsubscribes the listener when called.\n */\n public onAnyChange(\n callback: (key: string, value: any, oldValue: any) => void\n ): () => void {\n const listener = (payload: { key: string; value: any; oldValue: any }) => {\n callback(payload.key, payload.value, payload.oldValue);\n };\n return this._emitter.subscribe('change', listener);\n }\n\n /**\n * Export all data as a plain JavaScript record.\n */\n public toObject(): Record<string, any> {\n const obj: Record<string, any> = {};\n for (const [key, val] of this._data.entries()) {\n obj[key] = val;\n }\n return obj;\n }\n\n /**\n * Bulk load key-values from a record.\n */\n public fromObject(data: Record<string, any>): this {\n if (!data || typeof data !== 'object') return this;\n for (const [key, val] of Object.entries(data)) {\n this.set(key, val);\n }\n return this;\n }\n\n /**\n * Serialize state to JSON string.\n */\n public serialize(): string {\n return JSON.stringify(this.toObject());\n }\n\n /**\n * Deserialize state from JSON string.\n */\n public deserialize(json: string): this {\n try {\n const parsed = JSON.parse(json);\n this.fromObject(parsed);\n } catch (err) {\n console.error('Blackboard.deserialize failed:', err);\n }\n return this;\n }\n\n /**\n * Save store to browser localStorage.\n */\n public saveToLocalStorage(storageKey: string): boolean {\n if (typeof localStorage === 'undefined') return false;\n try {\n localStorage.setItem(storageKey, this.serialize());\n return true;\n } catch {\n return false;\n }\n }\n\n /**\n * Load store from browser localStorage.\n */\n public loadFromLocalStorage(storageKey: string): boolean {\n if (typeof localStorage === 'undefined') return false;\n try {\n const item = localStorage.getItem(storageKey);\n if (item !== null) {\n this.deserialize(item);\n return true;\n }\n } catch {\n return false;\n }\n return false;\n }\n}\n","import type { Camera2D } from '../rendering/Camera2D';\nimport type { Blackboard } from './Blackboard';\nimport type { SceneManager } from './SceneManager';\n\n/**\n * Lifecycle states of a scene.\n */\nexport enum SceneState {\n UNINITIALIZED = 'UNINITIALIZED',\n INACTIVE = 'INACTIVE',\n ENTERING = 'ENTERING',\n ACTIVE = 'ACTIVE',\n PAUSED = 'PAUSED',\n EXITING = 'EXITING',\n DESTROYED = 'DESTROYED'\n}\n\n/**\n * Public interface contract for all framework scenes.\n */\nexport interface IScene<TGame = any> {\n /** Unique registered name of the scene */\n name: string;\n\n /** Reference to the game orchestrator / context */\n game: TGame;\n\n /** Reference to the SceneManager managing this scene */\n sceneManager: SceneManager<TGame>;\n\n /** Reference to the shared cross-scene Blackboard */\n blackboard: Blackboard;\n\n /** Current lifecycle state */\n state: SceneState;\n\n /** Whether the scene has completed init() */\n initialized: boolean;\n\n /** Whether the scene is currently the top active scene */\n active: boolean;\n\n /** Whether the scene is currently paused beneath a modal overlay */\n paused: boolean;\n\n /**\n * If true, underlying scenes on the modal stack will be rendered\n * beneath this scene (e.g. for pause menus or semi-transparent overlays).\n * Default: false.\n */\n renderUnderlying: boolean;\n\n /** Optional active Camera2D reference for scene rendering */\n camera: Camera2D | null;\n\n /**\n * One-time initialization. Called when scene is added or first loaded.\n * Use for preloading assets, initializing pools, and configuring entities.\n */\n init(game: TGame): void | Promise<void>;\n\n /**\n * Called whenever the scene becomes active on the stack.\n * @param data Optional payload passed via switchTo() or push().\n */\n enter(data?: any): void | Promise<void>;\n\n /**\n * Variable logic update called every frame.\n * @param dt Scaled delta time in seconds.\n */\n update(dt: number): void;\n\n /**\n * Deterministic fixed timestep update called at constant rate (e.g. 60Hz).\n * @param dt Fixed timestep in seconds.\n */\n fixedUpdate?(dt: number): void;\n\n /**\n * Render pass called once per display frame.\n * @param ctx CanvasRenderingContext2D or framework CanvasContext / Renderer.\n */\n render(ctx: CanvasRenderingContext2D | any): void;\n\n /**\n * Called when another scene is pushed on top of this scene in the modal stack.\n */\n pause?(): void;\n\n /**\n * Called when a modal scene on top is popped and this scene resumes being active.\n * @param data Optional result data passed from pop().\n */\n resume?(data?: any): void;\n\n /**\n * Called when switching away from this scene or popping it off the stack.\n */\n exit(): void | Promise<void>;\n\n /**\n * Final teardown. Releases GPU textures, unbinds global listeners, clears state.\n */\n destroy(): void;\n}\n\n/**\n * Abstract base class providing default lifecycle implementations,\n * scene-local key-value state, and convenient engine hooks.\n */\nexport abstract class Scene<TGame = any> implements IScene<TGame> {\n public name: string = '';\n public game!: TGame;\n public sceneManager!: SceneManager<TGame>;\n public blackboard!: Blackboard;\n public state: SceneState = SceneState.UNINITIALIZED;\n public renderUnderlying: boolean = false;\n public camera: Camera2D | null = null;\n\n protected _localState: Map<string, any> = new Map();\n\n public get initialized(): boolean {\n return this.state !== SceneState.UNINITIALIZED && this.state !== SceneState.DESTROYED;\n }\n\n public get active(): boolean {\n return this.state === SceneState.ACTIVE;\n }\n\n public get paused(): boolean {\n return this.state === SceneState.PAUSED;\n }\n\n /**\n * One-time initialization.\n */\n public init(game: TGame): void | Promise<void> {\n this.game = game;\n this.state = SceneState.INACTIVE;\n }\n\n /**\n * Called on entering the scene.\n */\n public enter(data?: any): void | Promise<void> {\n this.state = SceneState.ACTIVE;\n }\n\n /**\n * Variable frame logic update.\n */\n public update(dt: number): void {}\n\n /**\n * Deterministic fixed timestep physics/simulation update.\n */\n public fixedUpdate(dt: number): void {}\n\n /**\n * Render loop pass.\n */\n public render(ctx: CanvasRenderingContext2D | any): void {}\n\n /**\n * Modal pause hook.\n */\n public pause(): void {\n this.state = SceneState.PAUSED;\n }\n\n /**\n * Modal resume hook.\n */\n public resume(data?: any): void {\n this.state = SceneState.ACTIVE;\n }\n\n /**\n * Exit hook called when leaving the scene.\n */\n public exit(): void | Promise<void> {\n this.state = SceneState.INACTIVE;\n }\n\n /**\n * Teardown and resource cleanup.\n */\n public destroy(): void {\n this.state = SceneState.DESTROYED;\n this._localState.clear();\n this.camera = null;\n }\n\n // ==========================================\n // Scene-Local State Storage Helpers\n // ==========================================\n\n /**\n * Set a scene-local state value.\n */\n public setLocal<T = any>(key: string, value: T): void {\n this._localState.set(key, value);\n }\n\n /**\n * Get a scene-local state value with optional fallback default.\n */\n public getLocal<T = any>(key: string, defaultValue?: T): T {\n if (this._localState.has(key)) {\n return this._localState.get(key) as T;\n }\n return defaultValue as T;\n }\n\n /**\n * Check if a scene-local state key exists.\n */\n public hasLocal(key: string): boolean {\n return this._localState.has(key);\n }\n\n /**\n * Remove a scene-local state key.\n */\n public deleteLocal(key: string): boolean {\n return this._localState.delete(key);\n }\n\n /**\n * Clear all scene-local state.\n */\n public clearLocal(): void {\n this._localState.clear();\n }\n}\n","import { EventEmitter } from '../core/EventEmitter';\nimport { Blackboard } from './Blackboard';\nimport { IScene, SceneState } from './Scene';\nimport { SceneTransition, InstantTransition } from './SceneTransition';\n\nexport type SceneConstructor<TGame = any> = new () => IScene<TGame>;\nexport type SceneEntry<TGame = any> = IScene<TGame> | SceneConstructor<TGame>;\n\n/**\n * Events emitted by SceneManager.\n */\nexport interface SceneManagerEvents {\n 'scene:added': { name: string; scene: IScene };\n 'scene:removed': { name: string };\n 'scene:change': { from: string | null; to: string; data?: any };\n 'scene:pushed': { name: string; depth: number; data?: any };\n 'scene:popped': { name: string; depth: number; result?: any };\n 'transition:start': { type: string; from: string | null; to: string; duration: number };\n 'transition:complete': { type: string; from: string | null; to: string };\n}\n\n/**\n * Production-grade Scene Lifecycle & Modal Stack Manager.\n */\nexport class SceneManager<TGame = any> {\n public readonly game: TGame;\n public readonly blackboard: Blackboard;\n public readonly events: EventEmitter<SceneManagerEvents> = new EventEmitter();\n\n private _registry: Map<string, SceneEntry<TGame>> = new Map();\n private _instances: Map<string, IScene<TGame>> = new Map();\n private _stack: IScene<TGame>[] = [];\n\n private _previousScene: IScene<TGame> | null = null;\n private _activeTransition: SceneTransition | null = null;\n private _transitionFromScene: IScene<TGame> | null = null;\n private _transitionToScene: IScene<TGame> | null = null;\n private _pendingSwitchData: any = undefined;\n\n constructor(game?: TGame) {\n this.game = game as TGame;\n this.blackboard = new Blackboard();\n }\n\n // ==========================================\n // Scene Registration\n // ==========================================\n\n /**\n * Register a scene by name. Supports both instantiated instances and class constructors.\n */\n public add(name: string, scene: SceneEntry<TGame>): this {\n if (!name || typeof name !== 'string') {\n throw new TypeError(`SceneManager.add: name must be a non-empty string, received ${name}`);\n }\n\n this._registry.set(name, scene);\n\n if (typeof scene !== 'function') {\n this._instances.set(name, scene);\n this._bindSceneMetadata(name, scene);\n this.events.emit('scene:added', { name, scene });\n }\n\n return this;\n }\n\n /**\n * Check if a scene is registered.\n */\n public has(name: string): boolean {\n return this._registry.has(name);\n }\n\n /**\n * Remove a registered scene. If scene is active or on stack, it is exited and destroyed.\n */\n public remove(name: string): boolean {\n if (!this._registry.has(name)) return false;\n\n // If scene is currently in stack, remove it cleanly\n const instance = this._instances.get(name);\n if (instance) {\n const idx = this._stack.indexOf(instance);\n if (idx !== -1) {\n instance.exit();\n instance.destroy();\n this._stack.splice(idx, 1);\n }\n this._instances.delete(name);\n }\n\n this._registry.delete(name);\n this.events.emit('scene:removed', { name });\n return true;\n }\n\n /**\n * Get an instantiated scene by name, instantiating lazily if needed.\n */\n public get(name: string): IScene<TGame> | undefined {\n let instance = this._instances.get(name);\n if (!instance) {\n const entry = this._registry.get(name);\n if (!entry) return undefined;\n\n if (typeof entry === 'function') {\n instance = new entry();\n this._instances.set(name, instance);\n this._bindSceneMetadata(name, instance);\n this.events.emit('scene:added', { name, scene: instance });\n } else {\n instance = entry;\n }\n }\n return instance;\n }\n\n /**\n * Return a list of all registered scene names.\n */\n public getSceneNames(): string[] {\n return Array.from(this._registry.keys());\n }\n\n // ==========================================\n // Stack & State Accessors\n // ==========================================\n\n /**\n * Currently active scene (top of stack).\n */\n public get currentScene(): IScene<TGame> | null {\n return this._stack.length > 0 ? this._stack[this._stack.length - 1] : null;\n }\n\n /**\n * Scene that was active prior to the latest switch.\n */\n public get previousScene(): IScene<TGame> | null {\n return this._previousScene;\n }\n\n /**\n * Number of scenes currently in the modal stack.\n */\n public get stackDepth(): number {\n return this._stack.length;\n }\n\n /**\n * Read-only view of the current scene stack (bottom to top).\n */\n public getStack(): readonly IScene<TGame>[] {\n return this._stack;\n }\n\n /**\n * Whether a visual scene transition is actively animating.\n */\n public get isTransitioning(): boolean {\n return this._activeTransition !== null && !this._activeTransition.isComplete;\n }\n\n /**\n * Currently executing scene transition, if any.\n */\n public get activeTransition(): SceneTransition | null {\n return this._activeTransition;\n }\n\n // ==========================================\n // Scene Switching & Modal Stack\n // ==========================================\n\n /**\n * Switch directly to a scene, clearing the existing modal stack.\n * Supports smooth visual transitions.\n */\n public switchTo(name: string, transition?: SceneTransition, data?: any): boolean {\n const toScene = this.get(name);\n if (!toScene) {\n throw new Error(`SceneManager.switchTo: Scene \"${name}\" not found in registry`);\n }\n\n // If currently transitioning, finish active transition immediately\n if (this._activeTransition && !this._activeTransition.isComplete) {\n this._finishTransition();\n }\n\n const fromScene = this.currentScene;\n this._ensureSceneInitialized(toScene);\n\n // If no transition or instant transition, perform direct synchronous switch\n if (!transition || transition.duration === 0) {\n this._executeDirectSwitch(fromScene, toScene, data);\n return true;\n }\n\n // Begin visual transition\n this._activeTransition = transition;\n this._transitionFromScene = fromScene;\n this._transitionToScene = toScene;\n this._pendingSwitchData = data;\n\n transition.start(fromScene, toScene);\n\n // If transition does not have midpoint (e.g. Slide, CrossFade), enter toScene immediately\n // so its visual state is ready to render during the animation\n if (!transition.hasMidpoint) {\n toScene.enter(data);\n if (toScene.state !== SceneState.ACTIVE) {\n toScene.state = SceneState.ACTIVE;\n }\n }\n\n this.events.emit('transition:start', {\n type: transition.constructor.name,\n from: fromScene ? fromScene.name : null,\n to: toScene.name,\n duration: transition.duration\n });\n\n return true;\n }\n\n /**\n * Push a modal scene onto the stack (e.g. Pause Menu, Inventory overlay).\n * Pauses the underlying scene.\n */\n public push(name: string, transition?: SceneTransition, data?: any): boolean {\n const toScene = this.get(name);\n if (!toScene) {\n throw new Error(`SceneManager.push: Scene \"${name}\" not found in registry`);\n }\n\n const current = this.currentScene;\n if (current && typeof current.pause === 'function') {\n current.pause();\n }\n\n this._ensureSceneInitialized(toScene);\n this._stack.push(toScene);\n toScene.enter(data);\n if (toScene.state !== SceneState.ACTIVE) {\n toScene.state = SceneState.ACTIVE;\n }\n\n if (transition && transition.duration > 0) {\n this._activeTransition = transition;\n this._transitionFromScene = current;\n this._transitionToScene = toScene;\n transition.start(current, toScene);\n }\n\n this.events.emit('scene:pushed', {\n name: toScene.name,\n depth: this._stack.length,\n data\n });\n\n return true;\n }\n\n /**\n * Pop the top modal scene off the stack and resume the underlying scene.\n * @param transition Optional transition out.\n * @param popResult Optional result data passed to underlying scene's resume(data).\n */\n public pop(transition?: SceneTransition, popResult?: any): IScene<TGame> | null {\n if (this._stack.length <= 1) {\n // Cannot pop root scene; game must always have at least one scene\n return null;\n }\n\n const poppedScene = this._stack.pop()!;\n poppedScene.exit();\n\n const underlyingScene = this.currentScene;\n if (underlyingScene && typeof underlyingScene.resume === 'function') {\n underlyingScene.resume(popResult);\n }\n\n if (transition && transition.duration > 0) {\n this._activeTransition = transition;\n this._transitionFromScene = poppedScene;\n this._transitionToScene = underlyingScene;\n transition.start(poppedScene, underlyingScene);\n }\n\n this.events.emit('scene:popped', {\n name: poppedScene.name,\n depth: this._stack.length,\n result: popResult\n });\n\n return poppedScene;\n }\n\n // ==========================================\n // Frame Loop Execution (GameLoop Delegation)\n // ==========================================\n\n /**\n * Execute variable logic update for active scenes.\n */\n public update(dt: number): void {\n // 1. Advance active transition\n if (this._activeTransition && !this._activeTransition.isComplete) {\n this._activeTransition.update(dt);\n\n // Handle midpoint swap for two-phase transitions (e.g. Fade to black)\n if (\n this._activeTransition.hasMidpoint &&\n !this._activeTransition.midpointTriggered &&\n this._activeTransition.progress >= 0.5\n ) {\n this._activeTransition.midpointTriggered = true;\n this._executeDirectSwitch(\n this._transitionFromScene,\n this._transitionToScene!,\n this._pendingSwitchData\n );\n }\n\n if (this._activeTransition.isComplete) {\n this._finishTransition();\n }\n }\n\n // 2. Update active top scene\n const current = this.currentScene;\n if (current && current.state === SceneState.ACTIVE) {\n current.update(dt);\n }\n }\n\n /**\n * Execute deterministic fixed timestep update for active scenes.\n */\n public fixedUpdate(dt: number): void {\n const current = this.currentScene;\n if (current && current.state === SceneState.ACTIVE && typeof current.fixedUpdate === 'function') {\n current.fixedUpdate(dt);\n }\n }\n\n /**\n * Render active scenes with modal stack composition and transition blending.\n */\n public render(ctx: CanvasRenderingContext2D | any): void {\n // If a transition is actively animating, delegate rendering to the transition\n if (this._activeTransition && !this._activeTransition.isComplete) {\n this._activeTransition.render(ctx, this._transitionFromScene, this._transitionToScene);\n return;\n }\n\n if (this._stack.length === 0) return;\n\n // Determine lowest scene index to render based on renderUnderlying flags\n let startIndex = this._stack.length - 1;\n while (startIndex > 0 && this._stack[startIndex].renderUnderlying) {\n startIndex--;\n }\n\n // Render stack bottom-to-top\n for (let i = startIndex; i < this._stack.length; i++) {\n this._stack[i].render(ctx);\n }\n }\n\n /**\n * Teardown all scenes and reset manager.\n */\n public destroy(): void {\n if (this._activeTransition) {\n this._activeTransition = null;\n }\n\n while (this._stack.length > 0) {\n const scene = this._stack.pop()!;\n scene.exit();\n scene.destroy();\n }\n\n for (const instance of this._instances.values()) {\n if (instance.state !== SceneState.DESTROYED) {\n instance.destroy();\n }\n }\n\n this._instances.clear();\n this._registry.clear();\n this.blackboard.clear();\n this.events.clear();\n }\n\n // ==========================================\n // Internal Helpers\n // ==========================================\n\n private _bindSceneMetadata(name: string, scene: IScene<TGame>): void {\n scene.name = name;\n scene.sceneManager = this;\n scene.blackboard = this.blackboard;\n if (this.game) {\n scene.game = this.game;\n }\n }\n\n private _ensureSceneInitialized(scene: IScene<TGame>): void {\n if (!scene.initialized) {\n this._bindSceneMetadata(scene.name, scene);\n scene.init(this.game);\n }\n }\n\n private _executeDirectSwitch(\n fromScene: IScene<TGame> | null,\n toScene: IScene<TGame>,\n data?: any\n ): void {\n // Exit and clear all current stack scenes\n while (this._stack.length > 0) {\n const s = this._stack.pop()!;\n s.exit();\n }\n\n this._previousScene = fromScene;\n this._stack.push(toScene);\n toScene.enter(data);\n if (toScene.state !== SceneState.ACTIVE) {\n toScene.state = SceneState.ACTIVE;\n }\n\n this.events.emit('scene:change', {\n from: fromScene ? fromScene.name : null,\n to: toScene.name,\n data\n });\n }\n\n private _finishTransition(): void {\n if (!this._activeTransition) return;\n\n const transition = this._activeTransition;\n const fromScene = this._transitionFromScene;\n const toScene = this._transitionToScene!;\n\n // For transitions without midpoint (Slide, CrossFade), finalize switch at completion\n if (!transition.hasMidpoint) {\n if (this.currentScene !== toScene) {\n while (this._stack.length > 0) {\n const s = this._stack.pop()!;\n if (s !== toScene) {\n s.exit();\n }\n }\n this._previousScene = fromScene;\n this._stack.push(toScene);\n\n this.events.emit('scene:change', {\n from: fromScene ? fromScene.name : null,\n to: toScene.name,\n data: this._pendingSwitchData\n });\n }\n }\n\n this._activeTransition = null;\n this._transitionFromScene = null;\n this._transitionToScene = null;\n this._pendingSwitchData = undefined;\n\n this.events.emit('transition:complete', {\n type: transition.constructor.name,\n from: fromScene ? fromScene.name : null,\n to: toScene.name\n });\n }\n}\n","import { Vector2 } from '../math/Vector2';\nimport { Rect } from '../math/Rect';\nimport { CanvasContext } from '../rendering/CanvasContext';\nimport { ICanvasRenderingContext2D } from '../rendering/CanvasMock';\n\nexport type UIContextLike = CanvasRenderingContext2D | ICanvasRenderingContext2D | CanvasContext | any;\n\nexport interface UIPointerEvent {\n target: UIElement;\n canvasPosition: Vector2;\n button: number;\n pointerType: 'mouse' | 'touch' | 'pen';\n consumed: boolean;\n stopPropagation: () => void;\n}\n\nexport interface UIElementOptions {\n name?: string;\n position?: Vector2 | { x: number; y: number };\n size?: Vector2 | { x: number; y: number };\n anchor?: Vector2 | { x: number; y: number };\n pivot?: Vector2 | { x: number; y: number };\n scale?: Vector2 | { x: number; y: number };\n rotation?: number;\n visible?: boolean;\n interactive?: boolean;\n enabled?: boolean;\n zIndex?: number;\n alpha?: number;\n cursor?: string;\n onClick?: (event: UIPointerEvent) => void;\n onPointerDown?: (event: UIPointerEvent) => void;\n onPointerUp?: (event: UIPointerEvent) => void;\n onPointerMove?: (event: UIPointerEvent) => void;\n onPointerEnter?: (event: UIPointerEvent) => void;\n onPointerLeave?: (event: UIPointerEvent) => void;\n}\n\nlet _nextElementId = 1;\n\n/**\n * Abstract Base Class for all Retained-Mode UI Elements.\n * Provides hierarchical 9-point anchor/pivot layout, bounds tracking,\n * z-index ordering, and pointer event dispatch.\n */\nexport class UIElement {\n public readonly id: string;\n public name: string;\n\n // Local Transform & Layout Properties\n public readonly position: Vector2;\n public readonly size: Vector2;\n public readonly anchor: Vector2;\n public readonly pivot: Vector2;\n public readonly scale: Vector2;\n public rotation: number = 0;\n\n // Visibility, Interactivity & Styling State\n public visible: boolean = true;\n public interactive: boolean = true;\n public enabled: boolean = true;\n public zIndex: number = 0;\n public alpha: number = 1.0;\n public cursor: string = 'default';\n\n // Hierarchy Tree\n public parent: UIElement | null = null;\n public readonly children: UIElement[] = [];\n\n // Cached World Transform Properties\n protected readonly _worldPosition: Vector2 = new Vector2();\n protected readonly _pivotWorldPosition: Vector2 = new Vector2();\n protected readonly _worldBounds: Rect = new Rect();\n protected readonly _worldScale: Vector2 = new Vector2(1, 1);\n protected _worldAlpha: number = 1.0;\n protected _isDirty: boolean = true;\n\n // Event Callbacks\n public onClick?: (event: UIPointerEvent) => void;\n public onPointerDown?: (event: UIPointerEvent) => void;\n public onPointerUp?: (event: UIPointerEvent) => void;\n public onPointerMove?: (event: UIPointerEvent) => void;\n public onPointerEnter?: (event: UIPointerEvent) => void;\n public onPointerLeave?: (event: UIPointerEvent) => void;\n\n constructor(options: UIElementOptions = {}) {\n this.id = `ui_${_nextElementId++}`;\n this.name = options.name ?? this.id;\n\n this.position = options.position instanceof Vector2 ? options.position.clone() : new Vector2(options.position?.x ?? 0, options.position?.y ?? 0);\n this.size = options.size instanceof Vector2 ? options.size.clone() : new Vector2(options.size?.x ?? 0, options.size?.y ?? 0);\n this.anchor = options.anchor instanceof Vector2 ? options.anchor.clone() : new Vector2(options.anchor?.x ?? 0, options.anchor?.y ?? 0);\n this.pivot = options.pivot instanceof Vector2 ? options.pivot.clone() : new Vector2(options.pivot?.x ?? 0, options.pivot?.y ?? 0);\n this.scale = options.scale instanceof Vector2 ? options.scale.clone() : new Vector2(options.scale?.x ?? 1, options.scale?.y ?? 1);\n this.rotation = options.rotation ?? 0;\n\n this.visible = options.visible ?? true;\n this.interactive = options.interactive ?? true;\n this.enabled = options.enabled ?? true;\n this.zIndex = options.zIndex ?? 0;\n this.alpha = options.alpha ?? 1.0;\n this._worldAlpha = this.alpha;\n this.cursor = options.cursor ?? 'default';\n\n this.onClick = options.onClick;\n this.onPointerDown = options.onPointerDown;\n this.onPointerUp = options.onPointerUp;\n this.onPointerMove = options.onPointerMove;\n this.onPointerEnter = options.onPointerEnter;\n this.onPointerLeave = options.onPointerLeave;\n }\n\n // ==========================================\n // Layout & Transform Calculations\n // ==========================================\n\n public markDirty(): void {\n this._isDirty = true;\n for (let i = 0; i < this.children.length; i++) {\n this.children[i].markDirty();\n }\n }\n\n public setAnchorAndPivot(anchor: Vector2, pivot: Vector2 = anchor): this {\n this.anchor.copy(anchor);\n this.pivot.copy(pivot);\n this.markDirty();\n return this;\n }\n\n public updateTransform(parentBounds?: Rect): void {\n let pLeft = 0;\n let pTop = 0;\n let pWidth = this.size.x;\n let pHeight = this.size.y;\n let pScaleX = 1;\n let pScaleY = 1;\n let pAlpha = 1;\n\n if (this.parent) {\n if (this.parent._isDirty) {\n this.parent.updateTransform();\n }\n pLeft = this.parent._worldBounds.x;\n pTop = this.parent._worldBounds.y;\n pWidth = this.parent._worldBounds.width;\n pHeight = this.parent._worldBounds.height;\n pScaleX = this.parent._worldScale.x;\n pScaleY = this.parent._worldScale.y;\n pAlpha = this.parent._worldAlpha;\n } else if (parentBounds) {\n pLeft = parentBounds.x;\n pTop = parentBounds.y;\n pWidth = parentBounds.width;\n pHeight = parentBounds.height;\n }\n\n // 1. Calculate anchor point on parent\n const anchorX = pLeft + this.anchor.x * pWidth;\n const anchorY = pTop + this.anchor.y * pHeight;\n\n // 2. Calculate pivot world position (origin of rotation/scaling)\n const pivotX = anchorX + this.position.x;\n const pivotY = anchorY + this.position.y;\n this._pivotWorldPosition.set(pivotX, pivotY);\n\n // 3. Compounded world scale\n this._worldScale.set(this.scale.x * pScaleX, this.scale.y * pScaleY);\n\n // 4. Compounded world alpha\n this._worldAlpha = Math.max(0, Math.min(1, this.alpha * pAlpha));\n\n // 5. Scaled width and height\n const w = this.size.x * this._worldScale.x;\n const h = this.size.y * this._worldScale.y;\n\n // 6. Top-left corner of bounding box\n const left = pivotX - this.pivot.x * w;\n const top = pivotY - this.pivot.y * h;\n\n this._worldPosition.set(left, top);\n this._worldBounds.set(left, top, w, h);\n this._isDirty = false;\n\n // 7. Update children\n for (let i = 0; i < this.children.length; i++) {\n this.children[i].updateTransform(this._worldBounds);\n }\n }\n\n public get worldPosition(): Vector2 {\n if (this._isDirty) this.updateTransform();\n return this._worldPosition;\n }\n\n public get pivotWorldPosition(): Vector2 {\n if (this._isDirty) this.updateTransform();\n return this._pivotWorldPosition;\n }\n\n public get worldBounds(): Rect {\n if (this._isDirty) this.updateTransform();\n return this._worldBounds;\n }\n\n public get worldScale(): Vector2 {\n if (this._isDirty) this.updateTransform();\n return this._worldScale;\n }\n\n public get worldAlpha(): number {\n if (this._isDirty) this.updateTransform();\n return this._worldAlpha;\n }\n\n // ==========================================\n // Hierarchy Management\n // ==========================================\n\n public addChild(child: UIElement): this {\n if (child.parent === this) return this;\n if (child.parent) {\n child.parent.removeChild(child);\n }\n child.parent = this;\n this.children.push(child);\n child.markDirty();\n return this;\n }\n\n public removeChild(child: UIElement): boolean {\n const idx = this.children.indexOf(child);\n if (idx !== -1) {\n this.children.splice(idx, 1);\n child.parent = null;\n child.markDirty();\n return true;\n }\n return false;\n }\n\n public removeFromParent(): boolean {\n if (this.parent) {\n return this.parent.removeChild(this);\n }\n return false;\n }\n\n public removeAllChildren(): this {\n for (let i = 0; i < this.children.length; i++) {\n this.children[i].parent = null;\n this.children[i].markDirty();\n }\n this.children.length = 0;\n return this;\n }\n\n public getChildByName(name: string): UIElement | null {\n for (let i = 0; i < this.children.length; i++) {\n if (this.children[i].name === name) return this.children[i];\n const found = this.children[i].getChildByName(name);\n if (found) return found;\n }\n return null;\n }\n\n public getRoot(): UIElement {\n let curr: UIElement = this;\n while (curr.parent) {\n curr = curr.parent;\n }\n return curr;\n }\n\n // ==========================================\n // Hit-Testing & Collision\n // ==========================================\n\n public containsPoint(point: Vector2): boolean {\n if (this._isDirty) this.updateTransform();\n\n if (this.rotation === 0) {\n return this._worldBounds.contains(point.x, point.y);\n }\n\n // Unrotate point relative to pivotWorldPosition\n const dx = point.x - this._pivotWorldPosition.x;\n const dy = point.y - this._pivotWorldPosition.y;\n const cos = Math.cos(-this.rotation);\n const sin = Math.sin(-this.rotation);\n\n const lx = (dx * cos - dy * sin) / (this._worldScale.x || 1);\n const ly = (dx * sin + dy * cos) / (this._worldScale.y || 1);\n\n const minX = -this.pivot.x * this.size.x;\n const maxX = (1 - this.pivot.x) * this.size.x;\n const minY = -this.pivot.y * this.size.y;\n const maxY = (1 - this.pivot.y) * this.size.y;\n\n return lx >= minX && lx <= maxX && ly >= minY && ly <= maxY;\n }\n\n /**\n * Recursive hit test against hierarchy in reverse z-index order.\n */\n public hitTest(point: Vector2): UIElement | null {\n if (!this.visible || !this.interactive || this.worldAlpha <= 0) {\n return null;\n }\n\n // Copy children and sort by zIndex descending, then reverse original index\n const sorted = this.children.slice().sort((a, b) => {\n if (b.zIndex !== a.zIndex) return b.zIndex - a.zIndex;\n return this.children.indexOf(b) - this.children.indexOf(a);\n });\n\n for (let i = 0; i < sorted.length; i++) {\n const hit = sorted[i].hitTest(point);\n if (hit) return hit;\n }\n\n if (this.containsPoint(point)) {\n return this;\n }\n\n return null;\n }\n\n // ==========================================\n // Lifecycle & Rendering\n // ==========================================\n\n public update(dt: number): void {\n if (this._isDirty) {\n this.updateTransform();\n }\n for (let i = 0; i < this.children.length; i++) {\n this.children[i].update(dt);\n }\n }\n\n public render(ctx: UIContextLike): void {\n if (!this.visible || this.worldAlpha <= 0) return;\n if (this._isDirty) this.updateTransform();\n\n const raw = ctx instanceof CanvasContext ? ctx.rawContext : ctx;\n raw.save();\n\n raw.globalAlpha = this.worldAlpha;\n raw.translate(this._pivotWorldPosition.x, this._pivotWorldPosition.y);\n if (this.rotation !== 0) raw.rotate(this.rotation);\n if (this.scale.x !== 1 || this.scale.y !== 1) raw.scale(this.scale.x, this.scale.y);\n\n const localBounds = new Rect(\n -this.pivot.x * this.size.x,\n -this.pivot.y * this.size.y,\n this.size.x,\n this.size.y\n );\n\n // Render self\n this.draw(raw, localBounds);\n\n raw.restore();\n\n // Render children sorted by zIndex ascending\n const sortedChildren = this.children.slice().sort((a, b) => {\n if (a.zIndex !== b.zIndex) return a.zIndex - b.zIndex;\n return this.children.indexOf(a) - this.children.indexOf(b);\n });\n\n for (let i = 0; i < sortedChildren.length; i++) {\n sortedChildren[i].render(ctx);\n }\n }\n\n protected draw(_raw: any, _localBounds: Rect): void {\n // Override in concrete UI elements\n }\n}\n","import { UIElement, UIElementOptions, UIContextLike } from './UIElement';\nimport { Rect } from '../math/Rect';\nimport { Color } from '../math/Color';\nimport { CanvasContext } from '../rendering/CanvasContext';\n\nexport interface UILabelOptions extends UIElementOptions {\n text?: string;\n fontFamily?: string;\n fontSize?: number;\n fontWeight?: string | number;\n fontStyle?: string;\n color?: string | Color;\n align?: 'left' | 'center' | 'right';\n baseline?: 'top' | 'middle' | 'bottom' | 'alphabetic';\n maxWidth?: number;\n wordWrap?: boolean;\n lineHeight?: number;\n truncate?: boolean;\n shadowColor?: string | Color;\n shadowBlur?: number;\n shadowOffsetX?: number;\n shadowOffsetY?: number;\n autoSize?: boolean;\n}\n\n/**\n * Text component with measurement, alignment, word wrapping, truncation, and drop shadows.\n */\nexport class UILabel extends UIElement {\n public text: string;\n public fontFamily: string;\n public fontSize: number;\n public fontWeight: string | number;\n public fontStyle: string;\n public color: string | Color;\n public align: 'left' | 'center' | 'right';\n public baseline: 'top' | 'middle' | 'bottom' | 'alphabetic';\n public maxWidth?: number;\n public wordWrap: boolean;\n public lineHeight: number;\n public truncate: boolean;\n public shadowColor?: string | Color;\n public shadowBlur?: number;\n public shadowOffsetX?: number;\n public shadowOffsetY?: number;\n public autoSize: boolean;\n\n constructor(options: UILabelOptions = {}) {\n super(options);\n this.text = options.text ?? '';\n this.fontFamily = options.fontFamily ?? 'sans-serif';\n this.fontSize = options.fontSize ?? 16;\n this.fontWeight = options.fontWeight ?? 'normal';\n this.fontStyle = options.fontStyle ?? 'normal';\n this.color = options.color ?? '#ffffff';\n this.align = options.align ?? 'left';\n this.baseline = options.baseline ?? 'top';\n this.maxWidth = options.maxWidth;\n this.wordWrap = options.wordWrap ?? false;\n this.lineHeight = options.lineHeight ?? Math.round(this.fontSize * 1.25);\n this.truncate = options.truncate ?? false;\n this.shadowColor = options.shadowColor;\n this.shadowBlur = options.shadowBlur;\n this.shadowOffsetX = options.shadowOffsetX;\n this.shadowOffsetY = options.shadowOffsetY;\n this.autoSize = options.autoSize ?? (this.size.x === 0 && this.size.y === 0);\n }\n\n public getFontString(): string {\n return `${this.fontStyle} ${this.fontWeight} ${this.fontSize}px ${this.fontFamily}`.trim();\n }\n\n public measure(ctx?: UIContextLike): { width: number; height: number } {\n const raw = ctx instanceof CanvasContext ? ctx.rawContext : ctx;\n const lines = this.splitLines(ctx);\n let maxW = 0;\n\n if (raw && typeof raw.measureText === 'function') {\n raw.font = this.getFontString();\n for (let i = 0; i < lines.length; i++) {\n const metrics = raw.measureText(lines[i]);\n if (metrics.width > maxW) maxW = metrics.width;\n }\n } else {\n // Robust headless fallback: 0.55em approx width per character\n for (let i = 0; i < lines.length; i++) {\n const approx = lines[i].length * (this.fontSize * 0.55);\n if (approx > maxW) maxW = approx;\n }\n }\n\n const totalH = Math.max(this.fontSize, lines.length * this.lineHeight);\n if (this.autoSize) {\n this.size.set(maxW, totalH);\n this.markDirty();\n }\n return { width: maxW, height: totalH };\n }\n\n public splitLines(ctx?: UIContextLike): string[] {\n if (!this.text) return [''];\n if (!this.wordWrap || !this.maxWidth) {\n if (this.truncate && this.maxWidth) {\n return [this._truncateLine(this.text, this.maxWidth, ctx)];\n }\n return this.text.split('\\n');\n }\n\n const raw = ctx instanceof CanvasContext ? ctx.rawContext : ctx;\n const paragraphs = this.text.split('\\n');\n const result: string[] = [];\n\n for (let p = 0; p < paragraphs.length; p++) {\n const words = paragraphs[p].split(' ');\n let currentLine = '';\n\n for (let w = 0; w < words.length; w++) {\n const testLine = currentLine ? `${currentLine} ${words[w]}` : words[w];\n let width = 0;\n if (raw && typeof raw.measureText === 'function') {\n raw.font = this.getFontString();\n width = raw.measureText(testLine).width;\n } else {\n width = testLine.length * (this.fontSize * 0.55);\n }\n\n if (width > this.maxWidth && currentLine) {\n result.push(currentLine);\n currentLine = words[w];\n } else {\n currentLine = testLine;\n }\n }\n if (currentLine) result.push(currentLine);\n }\n\n return result.length > 0 ? result : [''];\n }\n\n private _truncateLine(line: string, maxW: number, ctx: any): string {\n const raw = ctx instanceof CanvasContext ? ctx.rawContext : ctx;\n let w = 0;\n if (raw && typeof raw.measureText === 'function') {\n raw.font = this.getFontString();\n w = raw.measureText(line).width;\n } else {\n w = line.length * (this.fontSize * 0.55);\n }\n if (w <= maxW) return line;\n\n let sub = line;\n while (sub.length > 0) {\n sub = sub.slice(0, -1);\n const test = `${sub}...`;\n const curW = raw && typeof raw.measureText === 'function' ? raw.measureText(test).width : test.length * (this.fontSize * 0.55);\n if (curW <= maxW) return test;\n }\n return '...';\n }\n\n protected override draw(raw: any, localBounds: Rect): void {\n if (!this.text) return;\n\n raw.font = this.getFontString();\n raw.textAlign = this.align;\n raw.textBaseline = this.baseline;\n raw.fillStyle = this.color instanceof Color ? this.color.toRgbaString() : this.color;\n\n if (this.shadowColor) {\n raw.shadowColor = this.shadowColor instanceof Color ? this.shadowColor.toRgbaString() : this.shadowColor;\n raw.shadowBlur = this.shadowBlur ?? 0;\n raw.shadowOffsetX = this.shadowOffsetX ?? 0;\n raw.shadowOffsetY = this.shadowOffsetY ?? 0;\n }\n\n const lines = this.splitLines(raw);\n\n // Compute line start X\n let lineX = localBounds.x;\n if (this.align === 'center') {\n lineX = localBounds.x + localBounds.width * 0.5;\n } else if (this.align === 'right') {\n lineX = localBounds.x + localBounds.width;\n }\n\n let startY = localBounds.y;\n if (this.baseline === 'middle') {\n const totalH = lines.length * this.lineHeight;\n startY = localBounds.y + (localBounds.height - totalH) * 0.5 + this.lineHeight * 0.5;\n }\n\n for (let i = 0; i < lines.length; i++) {\n const lineY = startY + i * this.lineHeight;\n raw.fillText(lines[i], lineX, lineY);\n }\n\n if (this.shadowColor) {\n raw.shadowColor = 'transparent';\n raw.shadowBlur = 0;\n raw.shadowOffsetX = 0;\n raw.shadowOffsetY = 0;\n }\n }\n}\n","import { UIElement, UIElementOptions, UIContextLike } from './UIElement';\nimport { Vector2 } from '../math/Vector2';\nimport { Rect } from '../math/Rect';\nimport { Color } from '../math/Color';\nimport { CanvasContext } from '../rendering/CanvasContext';\n\nexport interface UIPadding {\n top: number;\n right: number;\n bottom: number;\n left: number;\n}\n\nexport interface UIPanelOptions extends UIElementOptions {\n backgroundColor?: string | Color | null;\n borderColor?: string | Color | null;\n borderWidth?: number;\n borderRadius?: number;\n padding?: UIPadding | number;\n clipChildren?: boolean;\n}\n\nexport function drawRoundedRectPath(raw: any, x: number, y: number, w: number, h: number, radius: number): void {\n const r = Math.max(0, Math.min(radius, w / 2, h / 2));\n if (r <= 0) {\n raw.rect(x, y, w, h);\n return;\n }\n if (typeof raw.roundRect === 'function') {\n raw.roundRect(x, y, w, h, r);\n } else {\n raw.moveTo(x + r, y);\n raw.lineTo(x + w - r, y);\n raw.arcTo(x + w, y, x + w, y + r, r);\n raw.lineTo(x + w, y + h - r);\n raw.arcTo(x + w, y + h, x + w - r, y + h, r);\n raw.lineTo(x + r, y + h);\n raw.arcTo(x, y + h, x, y + h - r, r);\n raw.lineTo(x, y + r);\n raw.arcTo(x, y, x + r, y, r);\n raw.closePath();\n }\n}\n\n/**\n * Container panel with background fill, border, corner radius, padding, and child clipping.\n */\nexport class UIPanel extends UIElement {\n public backgroundColor: string | Color | null;\n public borderColor: string | Color | null;\n public borderWidth: number;\n public borderRadius: number;\n public padding: UIPadding;\n public clipChildren: boolean;\n\n constructor(options: UIPanelOptions = {}) {\n super(options);\n this.backgroundColor = options.backgroundColor ?? '#1e1e2e';\n this.borderColor = options.borderColor ?? null;\n this.borderWidth = options.borderWidth ?? 0;\n this.borderRadius = options.borderRadius ?? 0;\n this.clipChildren = options.clipChildren ?? false;\n\n if (typeof options.padding === 'number') {\n this.padding = { top: options.padding, right: options.padding, bottom: options.padding, left: options.padding };\n } else if (options.padding) {\n this.padding = { ...options.padding };\n } else {\n this.padding = { top: 0, right: 0, bottom: 0, left: 0 };\n }\n }\n\n public getInnerBounds(): Rect {\n const wb = this.worldBounds;\n return new Rect(\n wb.x + this.padding.left,\n wb.y + this.padding.top,\n Math.max(0, wb.width - this.padding.left - this.padding.right),\n Math.max(0, wb.height - this.padding.top - this.padding.bottom)\n );\n }\n\n public override hitTest(point: Vector2): UIElement | null {\n if (this.clipChildren && !this.containsPoint(point)) {\n return null;\n }\n return super.hitTest(point);\n }\n\n protected override draw(raw: any, localBounds: Rect): void {\n const { x, y, width, height } = localBounds;\n if (width <= 0 || height <= 0) return;\n\n raw.beginPath();\n drawRoundedRectPath(raw, x, y, width, height, this.borderRadius);\n\n if (this.backgroundColor) {\n raw.fillStyle = this.backgroundColor instanceof Color ? this.backgroundColor.toRgbaString() : this.backgroundColor;\n raw.fill();\n }\n\n if (this.borderColor && this.borderWidth > 0) {\n raw.strokeStyle = this.borderColor instanceof Color ? this.borderColor.toRgbaString() : this.borderColor;\n raw.lineWidth = this.borderWidth;\n raw.stroke();\n }\n }\n\n public override render(ctx: UIContextLike): void {\n if (!this.visible || this.worldAlpha <= 0) return;\n if (this._isDirty) this.updateTransform();\n\n const raw = ctx instanceof CanvasContext ? ctx.rawContext : ctx;\n\n if (this.clipChildren) {\n raw.save();\n // Clip children to this panel's world bounds\n raw.beginPath();\n drawRoundedRectPath(raw, this._worldBounds.x, this._worldBounds.y, this._worldBounds.width, this._worldBounds.height, this.borderRadius);\n raw.clip();\n super.render(ctx);\n raw.restore();\n } else {\n super.render(ctx);\n }\n }\n}\n","import { Vector2 } from '../math/Vector2';\n\n/**\n * Standard 9-point normalized anchor presets for responsive canvas UI layout.\n * Values range from 0.0 to 1.0.\n */\nexport const UIAnchor = {\n TopLeft: Object.freeze(new Vector2(0.0, 0.0)),\n TopCenter: Object.freeze(new Vector2(0.5, 0.0)),\n TopRight: Object.freeze(new Vector2(1.0, 0.0)),\n CenterLeft: Object.freeze(new Vector2(0.0, 0.5)),\n Center: Object.freeze(new Vector2(0.5, 0.5)),\n CenterRight: Object.freeze(new Vector2(1.0, 0.5)),\n BottomLeft: Object.freeze(new Vector2(0.0, 1.0)),\n BottomCenter: Object.freeze(new Vector2(0.5, 1.0)),\n BottomRight: Object.freeze(new Vector2(1.0, 1.0))\n} as const;\n\n/**\n * Standard 9-point normalized pivot presets for local element alignment.\n */\nexport const UIPivot = {\n TopLeft: Object.freeze(new Vector2(0.0, 0.0)),\n TopCenter: Object.freeze(new Vector2(0.5, 0.0)),\n TopRight: Object.freeze(new Vector2(1.0, 0.0)),\n CenterLeft: Object.freeze(new Vector2(0.0, 0.5)),\n Center: Object.freeze(new Vector2(0.5, 0.5)),\n CenterRight: Object.freeze(new Vector2(1.0, 0.5)),\n BottomLeft: Object.freeze(new Vector2(0.0, 1.0)),\n BottomCenter: Object.freeze(new Vector2(0.5, 1.0)),\n BottomRight: Object.freeze(new Vector2(1.0, 1.0))\n} as const;\n","import { UIElement, UIElementOptions, UIPointerEvent } from './UIElement';\nimport { Rect } from '../math/Rect';\nimport { Color } from '../math/Color';\nimport { UILabel } from './UILabel';\nimport { drawRoundedRectPath } from './UIPanel';\nimport { UIAnchor, UIPivot } from './UIAnchor';\n\nexport enum UIButtonState {\n Normal = 'normal',\n Hover = 'hover',\n Pressed = 'pressed',\n Disabled = 'disabled'\n}\n\nexport interface UIButtonStyle {\n backgroundColor?: string | Color;\n borderColor?: string | Color;\n borderWidth?: number;\n textColor?: string | Color;\n}\n\nexport interface UIButtonOptions extends UIElementOptions {\n text?: string;\n fontSize?: number;\n fontFamily?: string;\n textColor?: string | Color;\n borderRadius?: number;\n stateStyles?: Partial<Record<UIButtonState, UIButtonStyle>>;\n onHover?: (button: UIButton, isHovered: boolean) => void;\n}\n\n/**\n * Production-grade Interactive Button with 4-state visual machine,\n * hover/pressed feedback, pointer absorption, and optional embedded label.\n */\nexport class UIButton extends UIElement {\n public state: UIButtonState = UIButtonState.Normal;\n public borderRadius: number;\n public label: UILabel | null = null;\n public stateStyles: Record<UIButtonState, UIButtonStyle>;\n\n public onHover?: (button: UIButton, isHovered: boolean) => void;\n\n private _isHovered: boolean = false;\n private _isPressed: boolean = false;\n\n constructor(options: UIButtonOptions = {}) {\n super({\n size: options.size ?? { x: 140, y: 44 },\n cursor: 'pointer',\n ...options\n });\n\n this.borderRadius = options.borderRadius ?? 6;\n this.onHover = options.onHover;\n\n this.stateStyles = {\n [UIButtonState.Normal]: {\n backgroundColor: '#3b82f6',\n borderColor: '#2563eb',\n borderWidth: 1,\n textColor: '#ffffff',\n ...options.stateStyles?.[UIButtonState.Normal]\n },\n [UIButtonState.Hover]: {\n backgroundColor: '#60a5fa',\n borderColor: '#3b82f6',\n borderWidth: 1,\n textColor: '#ffffff',\n ...options.stateStyles?.[UIButtonState.Hover]\n },\n [UIButtonState.Pressed]: {\n backgroundColor: '#1d4ed8',\n borderColor: '#1e40af',\n borderWidth: 2,\n textColor: '#e2e8f0',\n ...options.stateStyles?.[UIButtonState.Pressed]\n },\n [UIButtonState.Disabled]: {\n backgroundColor: '#475569',\n borderColor: '#334155',\n borderWidth: 1,\n textColor: '#94a3b8',\n ...options.stateStyles?.[UIButtonState.Disabled]\n }\n };\n\n if (options.text !== undefined) {\n this.label = new UILabel({\n text: options.text,\n fontSize: options.fontSize ?? 16,\n fontFamily: options.fontFamily ?? 'sans-serif',\n color: options.textColor ?? this.stateStyles[UIButtonState.Normal].textColor ?? '#ffffff',\n align: 'center',\n baseline: 'middle',\n anchor: UIAnchor.Center,\n pivot: UIPivot.Center,\n interactive: false\n });\n this.addChild(this.label);\n }\n\n if (!this.enabled) {\n this.state = UIButtonState.Disabled;\n }\n }\n\n public set disabled(value: boolean) {\n this.enabled = !value;\n if (value) {\n this.state = UIButtonState.Disabled;\n this._isHovered = false;\n this._isPressed = false;\n } else {\n this.state = this._isHovered ? UIButtonState.Hover : UIButtonState.Normal;\n }\n this._syncLabelColor();\n }\n\n public get disabled(): boolean {\n return !this.enabled || this.state === UIButtonState.Disabled;\n }\n\n public handlePointerEnter(event: UIPointerEvent): void {\n if (this.disabled) return;\n this._isHovered = true;\n if (!this._isPressed) {\n this.state = UIButtonState.Hover;\n this._syncLabelColor();\n }\n this.onHover?.(this, true);\n this.onPointerEnter?.(event);\n }\n\n public handlePointerLeave(event: UIPointerEvent): void {\n if (this.disabled) return;\n this._isHovered = false;\n this._isPressed = false;\n this.state = UIButtonState.Normal;\n this._syncLabelColor();\n this.onHover?.(this, false);\n this.onPointerLeave?.(event);\n }\n\n public handlePointerDown(event: UIPointerEvent): void {\n if (this.disabled) return;\n this._isPressed = true;\n this.state = UIButtonState.Pressed;\n this._syncLabelColor();\n this.onPointerDown?.(event);\n }\n\n public handlePointerUp(event: UIPointerEvent): void {\n if (this.disabled) return;\n const wasPressed = this._isPressed;\n this._isPressed = false;\n\n if (this._isHovered) {\n this.state = UIButtonState.Hover;\n this._syncLabelColor();\n this.onPointerUp?.(event);\n if (wasPressed) {\n this.onClick?.(event);\n }\n } else {\n this.state = UIButtonState.Normal;\n this._syncLabelColor();\n this.onPointerUp?.(event);\n }\n }\n\n private _syncLabelColor(): void {\n if (!this.label) return;\n const style = this.stateStyles[this.state];\n if (style?.textColor) {\n this.label.color = style.textColor;\n }\n }\n\n protected override draw(raw: any, localBounds: Rect): void {\n const { x, y, width, height } = localBounds;\n const style = this.stateStyles[this.state] || this.stateStyles[UIButtonState.Normal];\n\n raw.beginPath();\n drawRoundedRectPath(raw, x, y, width, height, this.borderRadius);\n\n if (style.backgroundColor) {\n raw.fillStyle = style.backgroundColor instanceof Color ? style.backgroundColor.toRgbaString() : style.backgroundColor;\n raw.fill();\n }\n\n if (style.borderColor && (style.borderWidth ?? 0) > 0) {\n raw.strokeStyle = style.borderColor instanceof Color ? style.borderColor.toRgbaString() : style.borderColor;\n raw.lineWidth = style.borderWidth ?? 1;\n raw.stroke();\n }\n }\n}\n","import { UIElement, UIPointerEvent, UIContextLike } from './UIElement';\nimport { Vector2 } from '../math/Vector2';\nimport { Rect } from '../math/Rect';\nimport { InputManager } from '../input/InputManager';\nimport { MouseButton } from '../input/Pointer';\nimport { UIButton } from './UIButton';\n\nexport interface UIManagerConfig {\n width?: number;\n height?: number;\n absorbInput?: boolean;\n}\n\n/**\n * Top-Level UI Manager coordinating retained UI hierarchy,\n * reverse z-index hit testing, hover states, and click event absorption.\n */\nexport class UIManager {\n public readonly root: UIElement;\n public viewportWidth: number;\n public viewportHeight: number;\n public absorbInput: boolean;\n\n public hoveredElement: UIElement | null = null;\n public pressedElement: UIElement | null = null;\n public focusedElement: UIElement | null = null;\n\n constructor(config: UIManagerConfig | number = 800, height: number = 600) {\n if (typeof config === 'number') {\n this.viewportWidth = config;\n this.viewportHeight = height;\n this.absorbInput = true;\n } else {\n this.viewportWidth = config.width ?? 800;\n this.viewportHeight = config.height ?? 600;\n this.absorbInput = config.absorbInput ?? true;\n }\n\n this.root = new UIElement({\n name: 'root',\n size: { x: this.viewportWidth, y: this.viewportHeight },\n interactive: true\n });\n this.root.updateTransform(new Rect(0, 0, this.viewportWidth, this.viewportHeight));\n }\n\n public resize(width: number, height: number): void {\n this.viewportWidth = width;\n this.viewportHeight = height;\n this.root.size.set(width, height);\n this.root.markDirty();\n this.root.updateTransform(new Rect(0, 0, width, height));\n }\n\n public add(child: UIElement): this {\n this.root.addChild(child);\n return this;\n }\n\n public remove(child: UIElement): boolean {\n return this.root.removeChild(child);\n }\n\n public clear(): void {\n this.root.removeAllChildren();\n this.hoveredElement = null;\n this.pressedElement = null;\n this.focusedElement = null;\n }\n\n public findElement(name: string): UIElement | null {\n return this.root.getChildByName(name);\n }\n\n /**\n * Hit test against UI children in reverse z-index order.\n * Empty canvas areas outside interactive UI widgets return null.\n */\n public hitTest(canvasPos: Vector2): UIElement | null {\n if (!this.root.visible || this.root.worldAlpha <= 0) return null;\n\n const sorted = this.root.children.slice().sort((a, b) => {\n if (b.zIndex !== a.zIndex) return b.zIndex - a.zIndex;\n return this.root.children.indexOf(b) - this.root.children.indexOf(a);\n });\n\n for (let i = 0; i < sorted.length; i++) {\n const hit = sorted[i].hitTest(canvasPos);\n if (hit) return hit;\n }\n\n return null;\n }\n\n /**\n * Evaluates pointer interaction against UI hierarchy.\n * If a hit occurs on an interactive widget, marks pointer.consumed = true and absorbs input from game entities.\n */\n public processInput(input: InputManager): boolean {\n const pointer = input.pointer;\n const pos = pointer.canvasPosition;\n const hit = this.hitTest(pos);\n\n let consumedThisFrame = false;\n\n // 1. Hover State Handling\n if (hit !== this.hoveredElement) {\n if (this.hoveredElement) {\n const leaveEvt = this._createPointerEvent(this.hoveredElement, pos, 0, pointer.pointerType);\n if (this.hoveredElement instanceof UIButton) {\n this.hoveredElement.handlePointerLeave(leaveEvt);\n } else {\n this.hoveredElement.onPointerLeave?.(leaveEvt);\n }\n }\n\n this.hoveredElement = hit;\n\n if (this.hoveredElement) {\n const enterEvt = this._createPointerEvent(this.hoveredElement, pos, 0, pointer.pointerType);\n if (this.hoveredElement instanceof UIButton) {\n this.hoveredElement.handlePointerEnter(enterEvt);\n } else {\n this.hoveredElement.onPointerEnter?.(enterEvt);\n }\n }\n } else if (this.hoveredElement) {\n const moveEvt = this._createPointerEvent(this.hoveredElement, pos, 0, pointer.pointerType);\n this.hoveredElement.onPointerMove?.(moveEvt);\n }\n\n // 2. Pointer Down Handling\n if (pointer.isJustPressed(MouseButton.Primary)) {\n if (hit) {\n this.pressedElement = hit;\n this.focusedElement = hit;\n const downEvt = this._createPointerEvent(hit, pos, MouseButton.Primary, pointer.pointerType);\n if (hit instanceof UIButton) {\n hit.handlePointerDown(downEvt);\n } else {\n hit.onPointerDown?.(downEvt);\n }\n\n if (this.absorbInput) {\n pointer.consume();\n consumedThisFrame = true;\n }\n }\n }\n\n // 3. Pointer Up Handling\n if (pointer.isJustReleased(MouseButton.Primary)) {\n if (this.pressedElement) {\n const upEvt = this._createPointerEvent(this.pressedElement, pos, MouseButton.Primary, pointer.pointerType);\n if (this.pressedElement instanceof UIButton) {\n this.pressedElement.handlePointerUp(upEvt);\n } else {\n this.pressedElement.onPointerUp?.(upEvt);\n if (this.pressedElement === hit) {\n this.pressedElement.onClick?.(upEvt);\n }\n }\n this.pressedElement = null;\n\n if (this.absorbInput) {\n pointer.consume();\n consumedThisFrame = true;\n }\n }\n }\n\n // 4. Continued Drag / Hold\n if (pointer.isDown(MouseButton.Primary) && this.pressedElement) {\n if (this.absorbInput) {\n pointer.consume();\n consumedThisFrame = true;\n }\n }\n\n return consumedThisFrame || (hit !== null && this.absorbInput && (pointer.isDown(MouseButton.Primary) || pointer.isJustPressed(MouseButton.Primary) || pointer.isJustReleased(MouseButton.Primary)));\n }\n\n private _createPointerEvent(target: UIElement, pos: Vector2, button: number, pointerType: 'mouse' | 'touch' | 'pen'): UIPointerEvent {\n let stopped = false;\n return {\n target,\n canvasPosition: pos.clone(),\n button,\n pointerType,\n get consumed() {\n return stopped;\n },\n set consumed(val: boolean) {\n stopped = val;\n },\n stopPropagation: () => {\n stopped = true;\n }\n };\n }\n\n public update(dt: number): void {\n this.root.update(dt);\n }\n\n public render(ctx: UIContextLike): void {\n this.root.render(ctx);\n }\n}\n","import { EventEmitter } from '../core/EventEmitter';\nimport { Transform2D } from '../math/Transform2D';\nimport { RenderLayer, type Renderer } from '../rendering/Renderer';\nimport type { Component, ComponentType } from './Component';\nimport type { EntityManager } from './EntityManager';\nimport type { Collider2D } from '../physics/Collider2D';\nimport type { ContactManifold } from '../physics/ContactSolver';\n\nlet _nextEntityId = 1;\n\nexport interface EntityEvents {\n 'destroy': { entity: Entity };\n 'component:add': { entity: Entity; component: Component };\n 'component:remove': { entity: Entity; component: Component };\n}\n\n/**\n * Primary Game Object container in the 2D Scene Graph.\n */\nexport class Entity extends EventEmitter<EntityEvents> {\n public readonly id: number;\n public name: string;\n public active: boolean = true;\n public tag: string = 'default';\n public layer: number = RenderLayer.ENTITIES;\n public zIndex: number = 0;\n\n public readonly transform: Transform2D;\n\n public parent: Entity | null = null;\n public readonly children: Entity[] = [];\n\n public entityManager: EntityManager | null = null;\n\n protected _components: Component[] = [];\n public _hasStarted: boolean = false;\n public _isDestroyed: boolean = false;\n\n constructor(name?: string) {\n super();\n this.id = _nextEntityId++;\n this.name = name ?? `Entity_${this.id}`;\n this.transform = new Transform2D();\n }\n\n public get isDestroyed(): boolean {\n return this._isDestroyed;\n }\n\n public get activeInHierarchy(): boolean {\n let curr: Entity | null = this;\n while (curr !== null) {\n if (!curr.active) return false;\n curr = curr.parent;\n }\n return true;\n }\n\n // ==========================================\n // Hierarchy Management\n // ==========================================\n\n public addChild(child: Entity): this {\n if (child === this || child.parent === this) return this;\n\n // Prevent cyclic hierarchy: cannot add an ancestor as a child\n let ancestor: Entity | null = this.parent;\n while (ancestor !== null) {\n if (ancestor === child) return this;\n ancestor = ancestor.parent;\n }\n\n if (child.parent !== null) {\n child.parent.removeChild(child);\n }\n\n child.parent = this;\n this.children.push(child);\n this.transform.addChild(child.transform);\n\n if (this.entityManager && !child.entityManager) {\n this.entityManager.add(child);\n }\n\n return this;\n }\n\n public removeChild(child: Entity): this {\n const idx = this.children.indexOf(child);\n if (idx !== -1) {\n this.children.splice(idx, 1);\n child.parent = null;\n this.transform.removeChild(child.transform);\n }\n return this;\n }\n\n public setParent(parent: Entity | null): this {\n if (parent === this || this.parent === parent) return this;\n\n if (parent === null) {\n if (this.parent !== null) {\n this.parent.removeChild(this);\n }\n return this;\n }\n\n parent.addChild(this);\n return this;\n }\n\n // ==========================================\n // Component Management\n // ==========================================\n\n public addComponent<T extends Component>(component: T): T {\n if (component.entity && component.entity !== this) {\n throw new Error(`Component is already attached to another Entity (${component.entity.name})`);\n }\n\n component.entity = this;\n this._components.push(component);\n component.onAttach();\n\n if (this._hasStarted && !component._hasStarted) {\n component._hasStarted = true;\n component.onStart();\n }\n\n if (this.entityManager) {\n this.entityManager._onComponentAdded(this, component);\n }\n\n this.emit('component:add', { entity: this, component });\n return component;\n }\n\n public getComponent<T extends Component>(type: ComponentType<T>): T | null {\n for (let i = 0; i < this._components.length; i++) {\n if (this._components[i] instanceof (type as any)) {\n return this._components[i] as T;\n }\n }\n return null;\n }\n\n public getComponents<T extends Component>(type: ComponentType<T>): T[] {\n const results: T[] = [];\n for (let i = 0; i < this._components.length; i++) {\n if (this._components[i] instanceof (type as any)) {\n results.push(this._components[i] as T);\n }\n }\n return results;\n }\n\n public hasComponent<T extends Component>(type: ComponentType<T>): boolean {\n return this.getComponent(type) !== null;\n }\n\n public removeComponent<T extends Component>(componentOrType: T | ComponentType<T>): boolean {\n let targetComponent: Component | null = null;\n let targetIdx = -1;\n\n if (typeof componentOrType === 'function') {\n for (let i = 0; i < this._components.length; i++) {\n if (this._components[i] instanceof (componentOrType as any)) {\n targetComponent = this._components[i];\n targetIdx = i;\n break;\n }\n }\n } else {\n targetIdx = this._components.indexOf(componentOrType);\n if (targetIdx !== -1) {\n targetComponent = componentOrType;\n }\n }\n\n if (!targetComponent || targetIdx === -1) return false;\n\n this._components.splice(targetIdx, 1);\n targetComponent._isDestroyed = true;\n targetComponent.onDetach();\n targetComponent.onDestroy();\n\n if (this.entityManager) {\n this.entityManager._onComponentRemoved(this, targetComponent);\n }\n\n this.emit('component:remove', { entity: this, component: targetComponent });\n return true;\n }\n\n // ==========================================\n // Physics & Collision Callbacks\n // ==========================================\n\n public onCollisionEnter(other: Collider2D, manifold: ContactManifold): void {\n for (let i = 0; i < this._components.length; i++) {\n const c = this._components[i];\n if (c.enabled && typeof (c as any).onCollisionEnter === 'function') {\n (c as any).onCollisionEnter(other, manifold);\n }\n }\n }\n\n public onCollisionStay(other: Collider2D, manifold: ContactManifold): void {\n for (let i = 0; i < this._components.length; i++) {\n const c = this._components[i];\n if (c.enabled && typeof (c as any).onCollisionStay === 'function') {\n (c as any).onCollisionStay(other, manifold);\n }\n }\n }\n\n public onCollisionExit(other: Collider2D): void {\n for (let i = 0; i < this._components.length; i++) {\n const c = this._components[i];\n if (c.enabled && typeof (c as any).onCollisionExit === 'function') {\n (c as any).onCollisionExit(other);\n }\n }\n }\n\n public onTriggerEnter(other: Collider2D): void {\n for (let i = 0; i < this._components.length; i++) {\n const c = this._components[i];\n if (c.enabled && typeof (c as any).onTriggerEnter === 'function') {\n (c as any).onTriggerEnter(other);\n }\n }\n }\n\n public onTriggerStay(other: Collider2D): void {\n for (let i = 0; i < this._components.length; i++) {\n const c = this._components[i];\n if (c.enabled && typeof (c as any).onTriggerStay === 'function') {\n (c as any).onTriggerStay(other);\n }\n }\n }\n\n public onTriggerExit(other: Collider2D): void {\n for (let i = 0; i < this._components.length; i++) {\n const c = this._components[i];\n if (c.enabled && typeof (c as any).onTriggerExit === 'function') {\n (c as any).onTriggerExit(other);\n }\n }\n }\n\n // ==========================================\n // Lifecycle Dispatch\n // ==========================================\n\n public start(): void {\n if (this._hasStarted) return;\n this._hasStarted = true;\n\n const comps = this._components.slice();\n for (let i = 0; i < comps.length; i++) {\n const c = comps[i];\n if (c.enabled && !c._hasStarted && !c._isDestroyed) {\n c._hasStarted = true;\n c.onStart();\n }\n }\n\n const children = this.children.slice();\n for (let i = 0; i < children.length; i++) {\n const child = children[i];\n if (child.active && !child._isDestroyed) {\n child.start();\n }\n }\n }\n\n public update(dt: number): void {\n if (!this.activeInHierarchy || this._isDestroyed) return;\n\n if (!this._hasStarted) {\n this.start();\n }\n\n const comps = this._components.slice();\n for (let i = 0; i < comps.length; i++) {\n const c = comps[i];\n if (c.enabled && !c._isDestroyed) {\n c.onUpdate(dt);\n }\n }\n\n const children = this.children.slice();\n for (let i = 0; i < children.length; i++) {\n const child = children[i];\n if (child.active && !child._isDestroyed) {\n child.update(dt);\n }\n }\n }\n\n public fixedUpdate(dt: number): void {\n if (!this.activeInHierarchy || this._isDestroyed) return;\n\n const comps = this._components.slice();\n for (let i = 0; i < comps.length; i++) {\n const c = comps[i];\n if (c.enabled && !c._isDestroyed) {\n c.onFixedUpdate(dt);\n }\n }\n\n const children = this.children.slice();\n for (let i = 0; i < children.length; i++) {\n const child = children[i];\n if (child.active && !child._isDestroyed) {\n child.fixedUpdate(dt);\n }\n }\n }\n\n public render(renderer: Renderer): void {\n if (!this.activeInHierarchy || this._isDestroyed) return;\n\n const comps = this._components.slice();\n for (let i = 0; i < comps.length; i++) {\n const c = comps[i];\n if (c.enabled && !c._isDestroyed) {\n c.onRender(renderer);\n }\n }\n\n const children = this.children.slice();\n for (let i = 0; i < children.length; i++) {\n const child = children[i];\n if (child.active && !child._isDestroyed) {\n child.render(renderer);\n }\n }\n }\n\n public destroy(): void {\n if (this._isDestroyed) return;\n this._isDestroyed = true;\n\n // Recursively destroy children first\n for (let i = this.children.length - 1; i >= 0; i--) {\n this.children[i].destroy();\n }\n\n // Detach and destroy all components\n for (let i = this._components.length - 1; i >= 0; i--) {\n const c = this._components[i];\n c._isDestroyed = true;\n c.onDetach();\n c.onDestroy();\n }\n this._components.length = 0;\n\n // Unparent from parent if attached\n if (this.parent !== null) {\n this.parent.removeChild(this);\n }\n\n if (this.entityManager !== null) {\n this.entityManager.markForDestruction(this);\n }\n\n this.emit('destroy', { entity: this });\n this.clear();\n }\n}\n","import type { Entity } from './Entity';\nimport type { Transform2D } from '../math/Transform2D';\nimport type { Renderer } from '../rendering/Renderer';\n\nexport type Constructor<T = any> = new (...args: any[]) => T;\nexport type AbstractConstructor<T = any> = abstract new (...args: any[]) => T;\nexport type ComponentType<T extends Component = Component> = Constructor<T> | AbstractConstructor<T>;\n\n/**\n * Abstract Base Class for all modular Entity components.\n */\nexport abstract class Component {\n public entity!: Entity;\n public enabled: boolean = true;\n public _hasStarted: boolean = false;\n public _isDestroyed: boolean = false;\n\n // ==========================================\n // Convenience Shortcuts\n // ==========================================\n\n public get transform(): Transform2D {\n return this.entity.transform;\n }\n\n public get name(): string {\n return this.entity.name;\n }\n\n public get tag(): string {\n return this.entity.tag;\n }\n\n public get layer(): number {\n return this.entity.layer;\n }\n\n public getComponent<T extends Component>(type: ComponentType<T>): T | null {\n return this.entity.getComponent(type);\n }\n\n public getComponents<T extends Component>(type: ComponentType<T>): T[] {\n return this.entity.getComponents(type);\n }\n\n public hasComponent<T extends Component>(type: ComponentType<T>): boolean {\n return this.entity.hasComponent(type);\n }\n\n public destroy(): void {\n if (this.entity && !this._isDestroyed) {\n this.entity.removeComponent(this);\n }\n }\n\n // ==========================================\n // Lifecycle Hooks\n // ==========================================\n\n public onAttach(): void {}\n public onDetach(): void {}\n public onStart(): void {}\n public onUpdate(dt: number): void {}\n public onFixedUpdate(dt: number): void {}\n public onRender(renderer: Renderer): void {}\n public onDestroy(): void {}\n}\n","import { Component } from '../Component';\nimport { Collider2D, type ColliderConfig } from '../../physics/Collider2D';\nimport { CircleCollider2D } from '../../physics/CircleCollider2D';\nimport { BoxCollider2D } from '../../physics/BoxCollider2D';\nimport type { Vector2 } from '../../math/Vector2';\nimport { RigidBodyComponent } from './RigidBodyComponent';\n\n/**\n * Base Component wrapping a 2D physics geometry Collider or Sensor/Trigger.\n */\nexport class ColliderComponent<T extends Collider2D = Collider2D> extends Component {\n public readonly collider: T;\n\n constructor(collider: T) {\n super();\n this.collider = collider;\n }\n\n public get isTrigger(): boolean {\n return this.collider.isTrigger;\n }\n\n public set isTrigger(val: boolean) {\n this.collider.isTrigger = val;\n }\n\n public get offset(): Vector2 {\n return this.collider.offset;\n }\n\n public set offset(val: Vector2) {\n this.collider.offset.copy(val);\n this.collider.updateWorldBounds();\n }\n\n public get layer(): number {\n return this.collider.layer;\n }\n\n public set layer(val: number) {\n this.collider.layer = val;\n }\n\n public get mask(): number {\n return this.collider.mask;\n }\n\n public set mask(val: number) {\n this.collider.mask = val;\n }\n\n public get friction(): number {\n return this.collider.friction;\n }\n\n public set friction(val: number) {\n this.collider.friction = val;\n }\n\n public get restitution(): number {\n return this.collider.restitution;\n }\n\n public set restitution(val: number) {\n this.collider.restitution = val;\n }\n\n // ==========================================\n // Lifecycle Hooks\n // ==========================================\n\n public override onAttach(): void {\n this.collider.userData = this.entity;\n\n // Associate with existing RigidBodyComponent if present on entity\n const rb = this.entity.getComponent(RigidBodyComponent);\n if (rb) {\n this.collider.body = rb.body;\n } else {\n // For static triggers/colliders without RigidBody, anchor initial position\n this.collider.offset.copy(this.entity.transform.position);\n this.collider.updateWorldBounds();\n }\n\n // Route collider callbacks directly to Entity collision methods\n this.collider.onCollisionEnter = (other, manifold) => this.entity.onCollisionEnter(other, manifold);\n this.collider.onCollisionStay = (other, manifold) => this.entity.onCollisionStay(other, manifold);\n this.collider.onCollisionExit = (other) => this.entity.onCollisionExit(other);\n this.collider.onTriggerEnter = (other) => this.entity.onTriggerEnter(other);\n this.collider.onTriggerStay = (other) => this.entity.onTriggerStay(other);\n this.collider.onTriggerExit = (other) => this.entity.onTriggerExit(other);\n\n // Auto-register with PhysicsWorld2D if present\n if (this.entity.entityManager?.physicsWorld) {\n this.entity.entityManager.physicsWorld.addCollider(this.collider);\n }\n }\n\n public override onFixedUpdate(_dt: number): void {\n // If static without RigidBody, sync entity transform into collider offset\n if (!this.collider.body) {\n this.collider.offset.copy(this.entity.transform.position);\n this.collider.updateWorldBounds();\n }\n }\n\n public override onDetach(): void {\n if (this.entity.entityManager?.physicsWorld) {\n this.entity.entityManager.physicsWorld.removeCollider(this.collider);\n }\n this.collider.body = null;\n this.collider.userData = null;\n }\n\n public override onDestroy(): void {\n this.onDetach();\n }\n}\n\n/**\n * Concrete Circular 2D Collider Component.\n */\nexport class CircleColliderComponent extends ColliderComponent<CircleCollider2D> {\n constructor(radius: number, config?: ColliderConfig) {\n super(new CircleCollider2D({ radius, ...config }));\n }\n\n public get radius(): number {\n return this.collider.radius;\n }\n\n public set radius(val: number) {\n this.collider.radius = val;\n this.collider.updateWorldBounds();\n }\n}\n\n/**\n * Concrete Oriented Bounding Box (OBB) / AABB 2D Collider Component.\n */\nexport class BoxColliderComponent extends ColliderComponent<BoxCollider2D> {\n constructor(width: number, height: number, config?: ColliderConfig) {\n super(new BoxCollider2D({ width, height, ...config }));\n }\n\n public get width(): number {\n return this.collider.size.x;\n }\n\n public set width(val: number) {\n this.collider.size.x = val;\n this.collider.halfExtents.x = val / 2;\n this.collider.updateWorldBounds();\n }\n\n public get height(): number {\n return this.collider.size.y;\n }\n\n public set height(val: number) {\n this.collider.size.y = val;\n this.collider.halfExtents.y = val / 2;\n this.collider.updateWorldBounds();\n }\n}\n","import { Component } from '../Component';\nimport { RigidBody2D, type RigidBodyConfig, type BodyType } from '../../physics/RigidBody2D';\nimport type { Vector2 } from '../../math/Vector2';\nimport { ColliderComponent } from './ColliderComponent';\n\n/**\n * Component that binds an Entity's Transform2D to a 2D RigidBody physics simulation.\n */\nexport class RigidBodyComponent extends Component {\n public readonly body: RigidBody2D;\n\n constructor(bodyOrConfig?: RigidBody2D | RigidBodyConfig) {\n super();\n if (bodyOrConfig instanceof RigidBody2D) {\n this.body = bodyOrConfig;\n } else {\n this.body = new RigidBody2D(bodyOrConfig);\n }\n }\n\n // ==========================================\n // Direct Physics Property Accessors\n // ==========================================\n\n public get bodyType(): BodyType {\n return this.body.bodyType;\n }\n\n public set bodyType(val: BodyType) {\n this.body.bodyType = val;\n }\n\n public get velocity(): Vector2 {\n return this.body.velocity;\n }\n\n public get angularVelocity(): number {\n return this.body.angularVelocity;\n }\n\n public set angularVelocity(val: number) {\n this.body.angularVelocity = val;\n }\n\n public get mass(): number {\n return this.body.mass;\n }\n\n public set mass(val: number) {\n this.body.setMass(val);\n }\n\n public get gravityScale(): number {\n return this.body.gravityScale;\n }\n\n public set gravityScale(val: number) {\n this.body.gravityScale = val;\n }\n\n public get restitution(): number {\n return this.body.restitution;\n }\n\n public set restitution(val: number) {\n this.body.restitution = val;\n }\n\n public get friction(): number {\n return this.body.friction;\n }\n\n public set friction(val: number) {\n this.body.friction = val;\n }\n\n public get fixedRotation(): boolean {\n return this.body.fixedRotation;\n }\n\n public set fixedRotation(val: boolean) {\n this.body.fixedRotation = val;\n }\n\n public get isSleeping(): boolean {\n return this.body.isSleeping;\n }\n\n // ==========================================\n // Force & Impulse APIs\n // ==========================================\n\n public applyForce(force: Vector2, point?: Vector2): void {\n this.body.applyForce(force, point);\n }\n\n public applyImpulse(impulse: Vector2, point?: Vector2): void {\n this.body.applyImpulse(impulse, point);\n }\n\n public applyTorque(torque: number): void {\n this.body.applyTorque(torque);\n }\n\n public applyAngularImpulse(impulse: number): void {\n this.body.applyAngularImpulse(impulse);\n }\n\n public setVelocity(vx: number, vy: number): void {\n this.body.velocity.set(vx, vy);\n this.body.wakeUp();\n }\n\n public wakeUp(): void {\n this.body.wakeUp();\n }\n\n public sleep(): void {\n this.body.sleep();\n }\n\n // ==========================================\n // Lifecycle Synchronization\n // ==========================================\n\n public override onAttach(): void {\n this.body.transform = this.entity.transform;\n this.body.userData = this.entity;\n\n // Initial position sync from scene graph into physics body\n this.body.position.copy(this.entity.transform.position);\n this.body.rotation = this.entity.transform.rotation;\n\n // Connect to any already attached ColliderComponents\n const colliders = this.entity.getComponents(ColliderComponent);\n for (let i = 0; i < colliders.length; i++) {\n colliders[i].collider.body = this.body;\n }\n\n // Auto-register with EntityManager's PhysicsWorld2D if present\n if (this.entity.entityManager?.physicsWorld) {\n this.entity.entityManager.physicsWorld.addBody(this.body);\n }\n }\n\n public override onDetach(): void {\n if (this.entity.entityManager?.physicsWorld) {\n this.entity.entityManager.physicsWorld.removeBody(this.body);\n }\n this.body.transform = null;\n this.body.userData = null;\n }\n\n public override onFixedUpdate(_dt: number): void {\n const transform = this.entity.transform;\n const body = this.body;\n const posChanged = body.position.x !== transform.position.x || body.position.y !== transform.position.y;\n const rotChanged = body.rotation !== transform.rotation;\n if (transform.isDirty || posChanged || rotChanged) {\n body.syncFromTransform();\n }\n }\n\n public override onDestroy(): void {\n this.onDetach();\n }\n}\n","import { Entity } from './Entity';\nimport { Component, type ComponentType } from './Component';\nimport { RigidBodyComponent } from './components/RigidBodyComponent';\nimport { ColliderComponent } from './components/ColliderComponent';\nimport type { PhysicsWorld2D } from '../../src/physics/PhysicsWorld2D';\nimport type { Renderer } from '../../src/rendering/Renderer';\nimport type { Camera2D } from '../../src/rendering/Camera2D';\n\n/**\n * Master Entity Manager handling collection lifecycle, fast queries,\n * deferred garbage collection, and physics integration.\n */\nexport class EntityManager {\n public physicsWorld: PhysicsWorld2D | null = null;\n public camera: Camera2D | null = null;\n\n private _entities: Entity[] = [];\n private _entitiesById: Map<number, Entity> = new Map();\n private _entitiesByName: Map<string, Entity> = new Map();\n private _entitiesByTag: Map<string, Set<Entity>> = new Map();\n private _entitiesByLayer: Map<number, Set<Entity>> = new Map();\n\n private _pendingAdd: Entity[] = [];\n private _pendingDestroy: Set<Entity> = new Set();\n private _isIterating: boolean = false;\n\n constructor(physicsWorld: PhysicsWorld2D | null = null) {\n this.physicsWorld = physicsWorld;\n }\n\n public get count(): number {\n return this._entities.length;\n }\n\n // ==========================================\n // Entity Registration & Factories\n // ==========================================\n\n public createEntity(name?: string): Entity {\n const entity = new Entity(name);\n return this.add(entity);\n }\n\n public add(entity: Entity): Entity {\n if (this._entitiesById.has(entity.id)) return entity;\n\n entity.entityManager = this;\n\n if (this._isIterating) {\n this._pendingAdd.push(entity);\n } else {\n this._registerEntity(entity);\n }\n\n return entity;\n }\n\n private _registerEntity(entity: Entity): void {\n if (this._entitiesById.has(entity.id)) return;\n\n this._entities.push(entity);\n this._entitiesById.set(entity.id, entity);\n this._entitiesByName.set(entity.name, entity);\n\n // Index by Tag\n let tagSet = this._entitiesByTag.get(entity.tag);\n if (!tagSet) {\n tagSet = new Set();\n this._entitiesByTag.set(entity.tag, tagSet);\n }\n tagSet.add(entity);\n\n // Index by Layer\n let layerSet = this._entitiesByLayer.get(entity.layer);\n if (!layerSet) {\n layerSet = new Set();\n this._entitiesByLayer.set(entity.layer, layerSet);\n }\n layerSet.add(entity);\n\n // Register with PhysicsWorld if physics components are present\n if (this.physicsWorld) {\n const rb = entity.getComponent(RigidBodyComponent);\n if (rb) {\n this.physicsWorld.addBody(rb.body);\n }\n const colliders = entity.getComponents(ColliderComponent);\n for (let i = 0; i < colliders.length; i++) {\n this.physicsWorld.addCollider(colliders[i].collider);\n }\n }\n\n // Register all children recursively\n for (let i = 0; i < entity.children.length; i++) {\n this.add(entity.children[i]);\n }\n }\n\n public remove(entity: Entity): boolean {\n if (this._isIterating) {\n const pendingIdx = this._pendingAdd.indexOf(entity);\n if (pendingIdx !== -1) {\n this._pendingAdd.splice(pendingIdx, 1);\n entity.entityManager = null;\n return true;\n }\n if (this._entitiesById.has(entity.id)) {\n this.markForDestruction(entity);\n return true;\n }\n return false;\n }\n\n const pendingIdx = this._pendingAdd.indexOf(entity);\n if (pendingIdx !== -1) {\n this._pendingAdd.splice(pendingIdx, 1);\n entity.entityManager = null;\n return true;\n }\n\n if (!this._entitiesById.has(entity.id)) return false;\n this._unregisterEntity(entity);\n return true;\n }\n\n private _unregisterEntity(entity: Entity): void {\n const idx = this._entities.indexOf(entity);\n if (idx !== -1) {\n this._entities.splice(idx, 1);\n }\n\n this._entitiesById.delete(entity.id);\n this._entitiesByName.delete(entity.name);\n\n const tagSet = this._entitiesByTag.get(entity.tag);\n if (tagSet) {\n tagSet.delete(entity);\n if (tagSet.size === 0) this._entitiesByTag.delete(entity.tag);\n }\n\n const layerSet = this._entitiesByLayer.get(entity.layer);\n if (layerSet) {\n layerSet.delete(entity);\n if (layerSet.size === 0) this._entitiesByLayer.delete(entity.layer);\n }\n\n // Unregister physics components\n if (this.physicsWorld) {\n const rb = entity.getComponent(RigidBodyComponent);\n if (rb) {\n this.physicsWorld.removeBody(rb.body);\n }\n const colliders = entity.getComponents(ColliderComponent);\n for (let i = 0; i < colliders.length; i++) {\n this.physicsWorld.removeCollider(colliders[i].collider);\n }\n }\n\n entity.entityManager = null;\n }\n\n public clear(): void {\n for (let i = this._entities.length - 1; i >= 0; i--) {\n this._entities[i].destroy();\n }\n this._entities.length = 0;\n this._entitiesById.clear();\n this._entitiesByName.clear();\n this._entitiesByTag.clear();\n this._entitiesByLayer.clear();\n this._pendingAdd.length = 0;\n this._pendingDestroy.clear();\n }\n\n // ==========================================\n // Queries\n // ==========================================\n\n public getById(id: number): Entity | undefined {\n return this._entitiesById.get(id);\n }\n\n public getByName(name: string): Entity | undefined {\n return this._entitiesByName.get(name);\n }\n\n public getByTag(tag: string): Entity[] {\n const results: Entity[] = [];\n for (let i = 0; i < this._entities.length; i++) {\n if (this._entities[i].tag === tag) {\n results.push(this._entities[i]);\n }\n }\n return results;\n }\n\n public getByLayer(layer: number): Entity[] {\n const results: Entity[] = [];\n for (let i = 0; i < this._entities.length; i++) {\n if (this._entities[i].layer === layer) {\n results.push(this._entities[i]);\n }\n }\n return results;\n }\n\n public queryByComponent<T extends Component>(type: ComponentType<T>): Entity[] {\n const results: Entity[] = [];\n for (let i = 0; i < this._entities.length; i++) {\n const entity = this._entities[i];\n if (entity.active && entity.hasComponent(type)) {\n results.push(entity);\n }\n }\n return results;\n }\n\n public queryByComponents(types: ComponentType[]): Entity[] {\n const results: Entity[] = [];\n for (let i = 0; i < this._entities.length; i++) {\n const entity = this._entities[i];\n if (!entity.active) continue;\n\n let hasAll = true;\n for (let j = 0; j < types.length; j++) {\n if (!entity.hasComponent(types[j])) {\n hasAll = false;\n break;\n }\n }\n if (hasAll) {\n results.push(entity);\n }\n }\n return results;\n }\n\n public get rootEntities(): Entity[] {\n return this._entities.filter((e) => e.parent === null || !this._entitiesById.has(e.parent.id));\n }\n\n // ==========================================\n // Internal Notification Hooks\n // ==========================================\n\n public _onComponentAdded(entity: Entity, component: Component): void {\n if (!this.physicsWorld) return;\n\n if (component instanceof RigidBodyComponent) {\n this.physicsWorld.addBody(component.body);\n } else if (component instanceof ColliderComponent) {\n this.physicsWorld.addCollider(component.collider);\n }\n }\n\n public _onComponentRemoved(entity: Entity, component: Component): void {\n if (!this.physicsWorld) return;\n\n if (component instanceof RigidBodyComponent) {\n this.physicsWorld.removeBody(component.body);\n } else if (component instanceof ColliderComponent) {\n this.physicsWorld.removeCollider(component.collider);\n }\n }\n\n public markForDestruction(entity: Entity): void {\n this._pendingDestroy.add(entity);\n }\n\n // ==========================================\n // Lifecycle Coordination & Deferred GC\n // ==========================================\n\n private _flushPendingAdd(): void {\n if (this._pendingAdd.length === 0) return;\n const toAdd = this._pendingAdd.slice();\n this._pendingAdd.length = 0;\n for (let i = 0; i < toAdd.length; i++) {\n this._registerEntity(toAdd[i]);\n }\n }\n\n private _flushPendingDestroy(): void {\n if (this._pendingDestroy.size === 0) return;\n for (const entity of this._pendingDestroy) {\n this._unregisterEntity(entity);\n }\n this._pendingDestroy.clear();\n }\n\n public start(): void {\n this._flushPendingAdd();\n const roots = this.rootEntities;\n for (let i = 0; i < roots.length; i++) {\n if (roots[i].active) {\n roots[i].start();\n }\n }\n }\n\n public update(dt: number): void {\n this._flushPendingAdd();\n\n this._isIterating = true;\n try {\n const roots = this.rootEntities;\n for (let i = 0; i < roots.length; i++) {\n const entity = roots[i];\n if (entity.active && !entity.isDestroyed) {\n entity.update(dt);\n }\n }\n } finally {\n this._isIterating = false;\n }\n\n this._flushPendingAdd();\n this._flushPendingDestroy();\n }\n\n public fixedUpdate(dt: number): void {\n this._flushPendingAdd();\n\n this._isIterating = true;\n try {\n const roots = this.rootEntities;\n for (let i = 0; i < roots.length; i++) {\n const entity = roots[i];\n if (entity.active && !entity.isDestroyed) {\n entity.fixedUpdate(dt);\n }\n }\n } finally {\n this._isIterating = false;\n }\n\n this._flushPendingAdd();\n this._flushPendingDestroy();\n }\n\n public render(renderer: Renderer): void {\n const roots = this.rootEntities;\n for (let i = 0; i < roots.length; i++) {\n const entity = roots[i];\n if (entity.active && !entity.isDestroyed) {\n entity.render(renderer);\n }\n }\n }\n}\n","import { EventEmitter } from './EventEmitter';\nimport { Time } from './Time';\nimport { GameLoop, type GameLoopCallbacks } from './GameLoop';\nimport { Renderer, type ScaleMode } from '../rendering/Renderer';\nimport { CanvasContext } from '../rendering/CanvasContext';\nimport { Camera2D, type Camera2DConfig } from '../rendering/Camera2D';\nimport { InputManager, type InputConfig } from '../input/InputManager';\nimport { PhysicsWorld2D, type PhysicsWorldConfig } from '../physics/PhysicsWorld2D';\nimport { SoundManager } from '../audio/SoundManager';\nimport { SceneManager, type SceneEntry } from '../scene/SceneManager';\nimport { UIManager, type UIManagerConfig } from '../ui/UIManager';\nimport { Vector2 } from '../math/Vector2';\nimport { EntityManager } from '../entity/EntityManager';\nimport type { IScene } from '../scene/Scene';\nimport type { SceneTransition } from '../scene/SceneTransition';\nimport type { Blackboard } from '../scene/Blackboard';\nimport type { MockCanvasElement } from '../rendering/CanvasMock';\n\nexport interface GameCallbacks {\n /** Quick prototype: custom one-time setup */\n init?: (game: Game) => void | Promise<void>;\n /** Quick prototype: variable logic update called each frame */\n update?: (dt: number, game: Game) => void;\n /** Quick prototype: fixed physics update called at constant rate */\n fixedUpdate?: (fixedDt: number, game: Game) => void;\n /** Quick prototype: render pass called each frame */\n render?: (ctx: CanvasContext, game: Game) => void;\n}\n\nexport interface GameAudioConfig {\n /** Whether to automatically attempt AudioContext unlock on first user gesture (default: true) */\n autoUnlock?: boolean;\n}\n\nexport interface GameConfig extends GameCallbacks {\n /** Canvas element, DOM element ID string, or MockCanvasElement. If omitted, auto-creates canvas or mock */\n canvas?: HTMLCanvasElement | MockCanvasElement | string;\n\n /** Virtual logical game width in pixels (default: 800) */\n width?: number;\n\n /** Virtual logical game height in pixels (default: 600) */\n height?: number;\n\n /** Canvas scaling mode ('letterbox' | 'fit' | 'stretch' | 'fill' | 'none', default: 'letterbox') */\n scaleMode?: ScaleMode;\n\n /** Whether to disable image smoothing for crisp pixel-art aesthetics (default: false) */\n pixelArt?: boolean;\n\n /** Canvas frame clear background color CSS/hex (default: '#11111b') */\n backgroundColor?: string;\n\n /** Whether to scale buffer to devicePixelRatio on Retina/HiDPI displays (default: true) */\n highDPI?: boolean;\n\n /** Maximum allowed devicePixelRatio clamp to prevent GPU fill-rate throttling (default: 2) */\n maxPixelRatio?: number;\n\n /** Explicit devicePixelRatio override for deterministic testing */\n dpr?: number;\n\n /** Target frames per second for loop timing (default: 60) */\n targetFps?: number;\n\n /** Alias for fixedDeltaTime */\n fixedTimestep?: number;\n\n /** Deterministic physics simulation timestep in seconds (default: 1 / 60 = ~0.0166667s) */\n fixedDeltaTime?: number;\n\n /** Maximum allowed frame delta to prevent spiral of death during heavy lags (default: 0.25s) */\n maxFrameDelta?: number;\n\n /** Maximum fixed update substeps allowed in a single frame tick (default: 15) */\n maxSubSteps?: number;\n\n /** Automatically pause simulation when browser tab is hidden (default: true) */\n autoPauseOnHide?: boolean;\n\n /** Whether to invoke render pass while game is paused (default: false) */\n renderWhenPaused?: boolean;\n\n /** Automatically start the game loop on creation when using createGame (default: false) */\n autoStart?: boolean;\n\n /** Whether to apply camera view matrix transform to world/scene rendering (default: true) */\n applyCamera?: boolean;\n\n /** Global gravity vector shortcut for physics simulation */\n gravity?: Vector2;\n\n /** Debug visual flags */\n debug?: boolean;\n\n /** Camera2D initial configuration */\n camera?: Partial<Camera2DConfig>;\n\n /** PhysicsWorld2D configuration (gravity, iterations, spatialCellSize) */\n physics?: PhysicsWorldConfig;\n\n /** InputManager configuration (preventDefaultKeys, preventContextMenu) */\n input?: InputConfig;\n\n /** SoundManager configuration */\n audio?: GameAudioConfig;\n\n /** UIManager configuration (absorbInput, etc.) */\n ui?: Partial<UIManagerConfig>;\n\n /** Initial scenes to register on startup */\n scenes?: Array<{ name: string; scene: SceneEntry<Game> }> | Record<string, SceneEntry<Game>>;\n\n /** Name of the scene to activate immediately on start() */\n initialScene?: string;\n\n /** Alias for initialScene */\n startScene?: string;\n}\n\n/**\n * Events emitted by the Game orchestrator.\n */\nexport interface GameEvents {\n 'init': { game: Game };\n 'start': { game: Game };\n 'pause': { game: Game };\n 'resume': { game: Game };\n 'stop': { game: Game };\n 'update': { deltaTime: number; game: Game };\n 'fixedUpdate': { fixedDeltaTime: number; game: Game };\n 'render': { alpha: number; ctx: CanvasContext; game: Game };\n 'resize': { width: number; height: number; game: Game };\n 'destroy': { game: Game };\n}\n\n/**\n * Top-Level Game Engine Orchestrator coordinating all subsystems:\n * Renderer, Camera2D, InputManager, PhysicsWorld2D, SoundManager, SceneManager, UIManager, GameLoop, and EntityManager.\n */\nexport class Game extends EventEmitter<GameEvents> {\n public readonly config: Readonly<GameConfig>;\n\n // Subsystems\n public readonly renderer: Renderer;\n public readonly canvas: HTMLCanvasElement | MockCanvasElement | any;\n public readonly ctx: CanvasContext;\n public readonly camera: Camera2D;\n public readonly input: InputManager;\n public readonly physics: PhysicsWorld2D;\n public readonly audio: SoundManager;\n public readonly scenes: SceneManager<Game>;\n public readonly ui: UIManager;\n public readonly loop: GameLoop;\n public readonly entities: EntityManager;\n\n /** Convenience alias for sound manager */\n public get sound(): SoundManager {\n return this.audio;\n }\n\n /** Convenience alias for cross-scene shared Blackboard */\n public get blackboard(): Blackboard {\n return this.scenes.blackboard;\n }\n\n // Viewport & Settings\n public readonly width: number;\n public readonly height: number;\n public applyCamera: boolean;\n\n // Lifecycle state\n private _isInitialized: boolean = false;\n private _initialSceneName: string | null = null;\n private _boundResizeListener: (() => void) | null = null;\n\n // Scratchpad for zero-allocation calculations\n private readonly _scratchPointerWorld: Vector2 = new Vector2();\n\n constructor(config: GameConfig = {}) {\n super();\n\n this.config = Object.freeze({ ...config });\n this.width = config.width ?? 800;\n this.height = config.height ?? 600;\n this.applyCamera = config.applyCamera ?? true;\n this._initialSceneName = config.initialScene ?? config.startScene ?? null;\n\n // 1. Initialize 2D Renderer & Canvas\n this.renderer = new Renderer({\n canvas: config.canvas,\n width: this.width,\n height: this.height,\n scaleMode: config.scaleMode ?? 'letterbox',\n pixelArt: config.pixelArt ?? false,\n backgroundColor: config.backgroundColor ?? '#11111b',\n highDPI: config.highDPI ?? true,\n maxPixelRatio: config.maxPixelRatio ?? 2,\n dpr: config.dpr\n });\n this.canvas = this.renderer.canvas;\n this.ctx = this.renderer.ctx;\n\n // 2. Initialize Camera2D (default centered origin for game world)\n this.camera = new Camera2D({\n viewportWidth: this.renderer.virtualWidth,\n viewportHeight: this.renderer.virtualHeight,\n originX: config.camera?.originX ?? 0.5,\n originY: config.camera?.originY ?? 0.5,\n ...config.camera\n });\n\n // 3. Initialize Input Subsystem attached to Canvas\n this.input = new InputManager({\n target: this.canvas,\n ...config.input\n });\n\n // 4. Initialize Deterministic GameLoop\n const loopCallbacks: GameLoopCallbacks = {\n update: (dt: number) => this._onUpdate(dt),\n fixedUpdate: (fixedDt: number) => this._onFixedUpdate(fixedDt),\n render: (alpha: number) => this._onRender(alpha)\n };\n\n const fixedDt =\n config.fixedDeltaTime ??\n config.fixedTimestep ??\n (config.targetFps ? 1 / config.targetFps : 1 / 60);\n\n this.loop = new GameLoop(loopCallbacks, {\n fixedDeltaTime: fixedDt,\n maxFrameDelta: config.maxFrameDelta ?? 0.25,\n maxSubSteps: config.maxSubSteps ?? 15,\n autoPauseOnHide: config.autoPauseOnHide ?? true,\n renderWhenPaused: config.renderWhenPaused ?? false\n });\n\n // 5. Initialize 2D Physics Engine Subsystem\n const physicsConfig: PhysicsWorldConfig = {\n fixedDeltaTime: this.loop.fixedDeltaTime,\n ...config.physics\n };\n if (config.gravity && !physicsConfig.gravity) {\n physicsConfig.gravity = config.gravity;\n }\n\n this.physics = new PhysicsWorld2D(physicsConfig);\n\n // 6. Initialize Web Audio Subsystem\n this.audio = new SoundManager();\n\n // 7. Initialize Scene Management Subsystem\n this.scenes = new SceneManager<Game>(this);\n if (config.scenes) {\n if (Array.isArray(config.scenes)) {\n for (const entry of config.scenes) {\n this.scenes.add(entry.name, entry.scene);\n }\n } else {\n for (const [name, entry] of Object.entries(config.scenes)) {\n this.scenes.add(name, entry);\n }\n }\n }\n\n // 8. Initialize Retained UI Subsystem\n this.ui = new UIManager({\n width: this.renderer.virtualWidth,\n height: this.renderer.virtualHeight,\n absorbInput: config.ui?.absorbInput ?? true\n });\n\n // 9. Initialize Entity-Component System Manager\n this.entities = new EntityManager(this.physics);\n this.entities.camera = this.camera;\n\n // 10. Window Resize Listener for Responsive Displays\n this._initResizeListener();\n }\n\n // ==========================================\n // Engine State Accessors\n // ==========================================\n\n public isRunning(): boolean {\n return this.loop.isRunning();\n }\n\n public isPaused(): boolean {\n return this.loop.isPaused();\n }\n\n public get isInitialized(): boolean {\n return this._isInitialized;\n }\n\n public get currentScene(): IScene<Game> | null {\n return this.scenes.currentScene;\n }\n\n public get deltaTime(): number {\n return Time.deltaTime;\n }\n\n public get rawDeltaTime(): number {\n return Time.rawDeltaTime;\n }\n\n public get fixedDeltaTime(): number {\n return this.loop.fixedDeltaTime;\n }\n\n public get time(): number {\n return Time.time;\n }\n\n public get fps(): number {\n return Time.fps;\n }\n\n public get exactFps(): number {\n return Time.exactFps;\n }\n\n public get frameCount(): number {\n return Time.frameCount;\n }\n\n public get timeScale(): number {\n return Time.timeScale;\n }\n\n public set timeScale(scale: number) {\n Time.setTimeScale(scale);\n }\n\n // ==========================================\n // Lifecycle Management\n // ==========================================\n\n /**\n * Initializes the game, executing custom init callback and activating the initial scene.\n */\n public async init(): Promise<this> {\n if (this._isInitialized) return this;\n\n if (this.config.init) {\n await this.config.init(this);\n }\n\n if (this._initialSceneName && !this.scenes.currentScene) {\n await this.scenes.switchTo(this._initialSceneName);\n }\n\n this._isInitialized = true;\n this.emit('init', { game: this });\n return this;\n }\n\n /**\n * Starts the game loop. Automatically invokes init() if not already initialized.\n */\n public start(): this {\n if (this.isRunning()) return this;\n\n if (!this._isInitialized) {\n if (this.config.init) {\n this.config.init(this);\n }\n // Synchronous initial scene switch fallback if init() wasn't awaited\n if (this._initialSceneName && !this.scenes.currentScene) {\n this.scenes.switchTo(this._initialSceneName);\n }\n this._isInitialized = true;\n this.emit('init', { game: this });\n }\n\n this.loop.start();\n this.emit('start', { game: this });\n return this;\n }\n\n /**\n * Pauses the game loop (logic updates and physics simulation halted).\n */\n public pause(): this {\n if (!this.isRunning() || this.isPaused()) return this;\n this.loop.pause();\n this.emit('pause', { game: this });\n return this;\n }\n\n /**\n * Resumes the game loop.\n */\n public resume(): this {\n if (!this.isRunning() || !this.isPaused()) return this;\n this.loop.resume();\n this.emit('resume', { game: this });\n return this;\n }\n\n /**\n * Stops the game loop.\n */\n public stop(): this {\n if (!this.isRunning()) return this;\n this.loop.stop();\n this.emit('stop', { game: this });\n return this;\n }\n\n /**\n * Manually steps the simulation by dt seconds.\n * Essential for deterministic unit testing and frame-by-frame debuggers.\n */\n public step(dt?: number): void {\n if (!this._isInitialized) {\n if (this._initialSceneName && !this.scenes.currentScene) {\n this.scenes.switchTo(this._initialSceneName);\n }\n this._isInitialized = true;\n this.emit('init', { game: this });\n }\n this.loop.step(dt);\n }\n\n /**\n * Teardown all subsystems, unregister DOM listeners, clear audio and scene graphs.\n */\n public destroy(): void {\n this.stop();\n this.loop.destroy();\n this.scenes.destroy();\n this.input.detach();\n this.audio.destroy();\n this.ui.clear();\n this.physics.clear();\n this.entities.clear();\n\n if (this._boundResizeListener && typeof window !== 'undefined') {\n window.removeEventListener('resize', this._boundResizeListener);\n this._boundResizeListener = null;\n }\n\n this.emit('destroy', { game: this });\n this.clear(); // Clear all event listeners\n }\n\n // ==========================================\n // Frame Update & Render Pipeline\n // ==========================================\n\n /**\n * 1. Variable Logic Update Step\n */\n private _onUpdate(dt: number): void {\n // Phase 1: Flush asynchronous DOM input events into active frame buffers\n this.input.update();\n\n // Phase 2: Retained UI hit-testing & click absorption\n // Consumes pointer clicks before game scenes or entities process them\n this.ui.processInput(this.input);\n\n // Phase 3: Active Camera target follow & trauma decay\n const activeCamera = this.scenes.currentScene?.camera ?? this.camera;\n if (activeCamera) {\n activeCamera.update(dt);\n }\n\n // Phase 4: Active Scene variable update\n this.scenes.update(dt);\n\n // Phase 5: Entities variable update\n this.entities.update(dt);\n\n // Phase 6: Retained UI hierarchy animations & layout updates\n this.ui.update(dt);\n\n // Phase 7: Custom prototype callback\n if (this.config.update) {\n this.config.update(dt, this);\n }\n\n this.emit('update', { deltaTime: dt, game: this });\n }\n\n /**\n * 2. Deterministic Fixed Timestep Physics Simulation\n */\n private _onFixedUpdate(fixedDt: number): void {\n // Phase 1: Master 2D Physics Step\n this.physics.step(fixedDt);\n\n // Phase 2: Active Scene fixed update\n this.scenes.fixedUpdate(fixedDt);\n\n // Phase 3: Entities fixed update\n this.entities.fixedUpdate(fixedDt);\n\n // Phase 4: Custom prototype fixed update\n if (this.config.fixedUpdate) {\n this.config.fixedUpdate(fixedDt, this);\n }\n\n this.emit('fixedUpdate', { fixedDeltaTime: fixedDt, game: this });\n }\n\n /**\n * 3. Render Pass\n */\n private _onRender(alpha: number): void {\n // Step 1: Clear canvas & prepare HiDPI buffer transform\n this.renderer.beginFrame();\n\n // Step 2: Determine active camera\n const activeCamera = this.scenes.currentScene?.camera ?? this.camera;\n this.entities.camera = activeCamera;\n\n // Step 3: Apply Camera View Matrix for direct World Space Rendering\n if (this.applyCamera && activeCamera) {\n this.ctx.save();\n activeCamera.applyToContext(this.ctx);\n }\n\n // Step 4: Render World Scenes\n this.scenes.render(this.ctx);\n\n // Step 5: Restore Context Transform back to Virtual Resolution Space\n if (this.applyCamera && activeCamera) {\n this.ctx.restore();\n }\n\n // Step 6: Render World Entities (submits commands to renderer queue)\n this.entities.render(this.renderer);\n this.renderer.flushQueue();\n\n // Step 7: Custom prototype render callback (screen / UI overlay space)\n if (this.config.render) {\n this.config.render(this.ctx, this);\n }\n\n // Step 8: Retained UI Render Pass (Screen space, responsive to virtual dimensions)\n this.ui.render(this.ctx);\n\n // Step 9: Flush queued render commands & safety guard check\n this.renderer.endFrame();\n\n // Step 10: Late Update input buffer cleanup (clears justPressed, justReleased, consumed)\n this.input.lateUpdate();\n\n this.emit('render', { alpha, ctx: this.ctx, game: this });\n }\n\n // ==========================================\n // Coordinate Unprojection & Queries\n // ==========================================\n\n /**\n * Unprojects current pointer position through active camera into 2D world coordinates.\n */\n public getPointerWorld(out?: Vector2): Vector2 {\n const dest = out ?? this._scratchPointerWorld;\n const activeCamera = this.scenes.currentScene?.camera ?? this.camera;\n return activeCamera.screenToWorld(this.input.pointer.canvasPosition, dest);\n }\n\n /**\n * Transforms screen / viewport coordinates into 2D world coordinates.\n */\n public screenToWorld(screenPos: Vector2, out?: Vector2): Vector2 {\n const activeCamera = this.scenes.currentScene?.camera ?? this.camera;\n return activeCamera.screenToWorld(screenPos, out);\n }\n\n /**\n * Transforms 2D world coordinates into screen / viewport coordinates.\n */\n public worldToScreen(worldPos: Vector2, out?: Vector2): Vector2 {\n const activeCamera = this.scenes.currentScene?.camera ?? this.camera;\n return activeCamera.worldToScreen(worldPos, out);\n }\n\n // ==========================================\n // Scene Helpers\n // ==========================================\n\n /**\n * Registers a scene into the SceneManager.\n */\n public addScene(name: string, scene: SceneEntry<Game>): this {\n this.scenes.add(name, scene);\n return this;\n }\n\n /**\n * Switches active scene with optional transition and payload.\n */\n public switchToScene(name: string, transition?: SceneTransition, data?: any): void {\n this.scenes.switchTo(name, transition, data);\n }\n\n // ==========================================\n // Resize Coordination\n // ==========================================\n\n /**\n * Resizes renderer, camera, and UI when window or container dimensions change.\n */\n public resize(containerWidth?: number, containerHeight?: number): void {\n this.renderer.resize(containerWidth, containerHeight);\n this.camera.viewportWidth = this.renderer.virtualWidth;\n this.camera.viewportHeight = this.renderer.virtualHeight;\n this.ui.resize(this.renderer.virtualWidth, this.renderer.virtualHeight);\n\n this.emit('resize', {\n width: containerWidth ?? this.renderer.virtualWidth,\n height: containerHeight ?? this.renderer.virtualHeight,\n game: this\n });\n }\n\n private _initResizeListener(): void {\n if (typeof window === 'undefined') return;\n\n this._boundResizeListener = () => {\n this.resize(window.innerWidth, window.innerHeight);\n };\n\n window.addEventListener('resize', this._boundResizeListener);\n }\n}\n\n/**\n * Factory function to instantiate, configure, and optionally start a new Game.\n * @param config Comprehensive game configuration options.\n * @returns Fully initialized Game orchestrator instance.\n */\nexport function createGame(config: GameConfig = {}): Game {\n const game = new Game(config);\n if (config.autoStart) {\n game.start();\n }\n return game;\n}\n","import { Vector2 } from '../math/Vector2';\nimport { Rect } from '../math/Rect';\nimport { Color } from '../math/Color';\nimport { Transform2D } from '../math/Transform2D';\nimport { CanvasContext } from './CanvasContext';\nimport { ICanvasRenderingContext2D } from './CanvasMock';\n\nexport interface SpriteConfig {\n /** CanvasImageSource: HTMLImageElement, HTMLCanvasElement, ImageBitmap, OffscreenCanvas, or MockCanvasElement */\n texture: CanvasImageSource | any;\n /** Source rectangle in the texture (for sprite sheets / atlases). Default: full texture */\n sourceRect?: Rect | { x: number; y: number; width: number; height: number };\n /** Destination rendering width. Default: sourceRect.width or texture.width */\n width?: number;\n /** Destination rendering height. Default: sourceRect.height or texture.height */\n height?: number;\n /** Normalized pivot/anchor [0, 1]. Default: (0.5, 0.5) for center */\n anchor?: Vector2 | { x: number; y: number };\n /** Tint color applied to sprite. Default: null (no tint) */\n tint?: Color | string | null;\n /** Horizontal flip */\n flipX?: boolean;\n /** Vertical flip */\n flipY?: boolean;\n /** Opacity [0.0, 1.0]. Default: 1.0 */\n opacity?: number;\n}\n\n/**\n * Cache for tinted offscreen canvases to eliminate per-frame canvas allocations.\n */\nexport class TextureTintCache {\n private static _cache: Map<string, any> = new Map();\n\n public static getTintedTexture(\n source: any,\n sourceRect: Rect,\n tint: Color\n ): any | null {\n if (typeof document === 'undefined') return null; // Headless fallback\n\n const key = `${source.src ?? 'canvas'}_${sourceRect.x}_${sourceRect.y}_${sourceRect.width}_${sourceRect.height}_${tint.toHexString(true)}`;\n const cached = this._cache.get(key);\n if (cached) return cached;\n\n const canvas = document.createElement('canvas');\n canvas.width = sourceRect.width;\n canvas.height = sourceRect.height;\n const ctx = canvas.getContext('2d');\n if (!ctx) return null;\n\n // Draw source sub-image\n ctx.drawImage(\n source,\n sourceRect.x, sourceRect.y, sourceRect.width, sourceRect.height,\n 0, 0, sourceRect.width, sourceRect.height\n );\n\n // Composite tint over source\n ctx.globalCompositeOperation = 'source-atop';\n ctx.fillStyle = tint.toRgbaString();\n ctx.fillRect(0, 0, sourceRect.width, sourceRect.height);\n\n this._cache.set(key, canvas);\n return canvas;\n }\n\n public static clear(): void {\n this._cache.clear();\n }\n}\n\nexport class Sprite {\n public texture: any;\n public sourceRect: Rect;\n public width: number;\n public height: number;\n public anchor: Vector2;\n public tint: Color | null = null;\n public flipX: boolean = false;\n public flipY: boolean = false;\n public opacity: number = 1.0;\n\n // Cached scratch rect for bounds calculation without allocation\n private _cachedBounds: Rect = new Rect();\n\n constructor(config: SpriteConfig) {\n this.texture = config.texture;\n\n const texW = (config.texture?.width as number) || 32;\n const texH = (config.texture?.height as number) || 32;\n\n if (config.sourceRect) {\n this.sourceRect = config.sourceRect instanceof Rect\n ? config.sourceRect.clone()\n : new Rect(config.sourceRect.x, config.sourceRect.y, config.sourceRect.width, config.sourceRect.height);\n } else {\n this.sourceRect = new Rect(0, 0, texW, texH);\n }\n\n this.width = config.width ?? this.sourceRect.width;\n this.height = config.height ?? this.sourceRect.height;\n this.anchor = config.anchor instanceof Vector2\n ? config.anchor.clone()\n : new Vector2(config.anchor?.x ?? 0.5, config.anchor?.y ?? 0.5);\n\n if (config.tint) {\n this.tint = config.tint instanceof Color ? config.tint.clone() : Color.parse(config.tint);\n }\n\n this.flipX = config.flipX ?? false;\n this.flipY = config.flipY ?? false;\n this.opacity = Math.max(0, Math.min(1, config.opacity ?? 1.0));\n }\n\n public setSourceRect(x: number, y: number, width: number, height: number): this {\n this.sourceRect.set(x, y, width, height);\n return this;\n }\n\n public setAnchor(x: number, y: number): this {\n this.anchor.set(x, y);\n return this;\n }\n\n public setDimensions(width: number, height: number): this {\n this.width = width;\n this.height = height;\n return this;\n }\n\n public setFlip(flipX: boolean, flipY: boolean): this {\n this.flipX = flipX;\n this.flipY = flipY;\n return this;\n }\n\n public setTint(tint: Color | string | null): this {\n if (!tint) {\n this.tint = null;\n } else if (tint instanceof Color) {\n this.tint = tint.clone();\n } else {\n this.tint = Color.parse(tint);\n }\n return this;\n }\n\n /**\n * Returns the local bounding box relative to the anchor point.\n */\n public getBounds(out?: Rect): Rect {\n const dest = out ?? this._cachedBounds;\n dest.set(\n -this.width * this.anchor.x,\n -this.height * this.anchor.y,\n this.width,\n this.height\n );\n return dest;\n }\n\n private _getRawContext(ctx: CanvasRenderingContext2D | ICanvasRenderingContext2D | CanvasContext | any): any {\n return ctx instanceof CanvasContext ? ctx.rawContext : ctx;\n }\n\n /**\n * Draws the sprite at an explicit world position, rotation, and scale.\n */\n public draw(\n context: CanvasRenderingContext2D | ICanvasRenderingContext2D | CanvasContext | any,\n x: number,\n y: number,\n rotation: number = 0,\n scaleX: number = 1,\n scaleY: number = 1\n ): void {\n const ctx = this._getRawContext(context);\n ctx.save();\n ctx.translate(x, y);\n\n if (rotation !== 0) {\n ctx.rotate(rotation);\n }\n\n const sx = scaleX * (this.flipX ? -1 : 1);\n const sy = scaleY * (this.flipY ? -1 : 1);\n if (sx !== 1 || sy !== 1) {\n ctx.scale(sx, sy);\n }\n\n if (this.opacity < 1.0) {\n ctx.globalAlpha *= this.opacity;\n }\n\n const drawX = -this.width * this.anchor.x;\n const drawY = -this.height * this.anchor.y;\n\n if (this.tint) {\n const tinted = TextureTintCache.getTintedTexture(this.texture, this.sourceRect, this.tint);\n if (tinted) {\n ctx.drawImage(tinted, 0, 0, this.sourceRect.width, this.sourceRect.height, drawX, drawY, this.width, this.height);\n ctx.restore();\n return;\n }\n }\n\n ctx.drawImage(\n this.texture,\n this.sourceRect.x,\n this.sourceRect.y,\n this.sourceRect.width,\n this.sourceRect.height,\n drawX,\n drawY,\n this.width,\n this.height\n );\n\n ctx.restore();\n }\n\n /**\n * Draws the sprite using a Transform2D hierarchy component.\n */\n public drawTransform(\n context: CanvasRenderingContext2D | ICanvasRenderingContext2D | CanvasContext | any,\n transform: Transform2D\n ): void {\n const ctx = this._getRawContext(context);\n ctx.save();\n transform.updateWorldMatrix().transformContext(ctx);\n\n if (this.flipX || this.flipY) {\n ctx.scale(this.flipX ? -1 : 1, this.flipY ? -1 : 1);\n }\n\n if (this.opacity < 1.0) {\n ctx.globalAlpha *= this.opacity;\n }\n\n const drawX = -this.width * this.anchor.x;\n const drawY = -this.height * this.anchor.y;\n\n if (this.tint) {\n const tinted = TextureTintCache.getTintedTexture(this.texture, this.sourceRect, this.tint);\n if (tinted) {\n ctx.drawImage(tinted, 0, 0, this.sourceRect.width, this.sourceRect.height, drawX, drawY, this.width, this.height);\n ctx.restore();\n return;\n }\n }\n\n ctx.drawImage(\n this.texture,\n this.sourceRect.x,\n this.sourceRect.y,\n this.sourceRect.width,\n this.sourceRect.height,\n drawX,\n drawY,\n this.width,\n this.height\n );\n\n ctx.restore();\n }\n}\n","import { Rect } from '../math/Rect';\nimport { Vector2 } from '../math/Vector2';\nimport { Time } from '../core/Time';\nimport { Sprite } from './Sprite';\n\nexport interface AnimationFrame {\n /** Index in the clip */\n index: number;\n /** Sub-rectangle coordinates on texture atlas */\n sourceRect: Rect;\n /** Frame duration in seconds (default: 1 / clip.fps) */\n duration: number;\n /** Optional frame-specific anchor override */\n anchor?: Vector2;\n}\n\nexport type PlaybackMode = 'loop' | 'once' | 'ping-pong' | 'reverse';\n\nexport interface AnimationClipConfig {\n name: string;\n frames: AnimationFrame[];\n fps?: number; // default: 12\n wrapMode?: PlaybackMode; // default: 'loop'\n}\n\nexport class AnimationClip {\n public readonly name: string;\n public readonly frames: AnimationFrame[];\n public readonly fps: number;\n public readonly wrapMode: PlaybackMode;\n public readonly totalDuration: number;\n\n constructor(config: AnimationClipConfig) {\n this.name = config.name;\n this.fps = config.fps ?? 12;\n this.wrapMode = config.wrapMode ?? 'loop';\n this.frames = config.frames;\n\n let sum = 0;\n for (let i = 0; i < this.frames.length; i++) {\n sum += this.frames[i].duration;\n }\n this.totalDuration = sum > 0 ? sum : (this.frames.length / this.fps);\n }\n}\n\n/**\n * Animation controller for driving sprite animation playback.\n */\nexport class Animation {\n private _clips: Map<string, AnimationClip> = new Map();\n public currentClip: AnimationClip | null = null;\n public currentFrameIndex: number = 0;\n public currentTime: number = 0;\n public playbackSpeed: number = 1.0;\n public isPlaying: boolean = false;\n public isPaused: boolean = false;\n public isFinished: boolean = false;\n\n private _direction: 1 | -1 = 1;\n public targetSprite: Sprite | null = null;\n\n // Event callbacks\n public onFrame?: (frameIndex: number, frame: AnimationFrame) => void;\n public onComplete?: () => void;\n public onLoop?: () => void;\n\n constructor(targetSprite?: Sprite) {\n if (targetSprite) {\n this.targetSprite = targetSprite;\n }\n }\n\n public addClip(clip: AnimationClip): this {\n this._clips.set(clip.name, clip);\n return this;\n }\n\n public getClip(name: string): AnimationClip | undefined {\n return this._clips.get(name);\n }\n\n public hasClip(name: string): boolean {\n return this._clips.has(name);\n }\n\n public play(clipName: string, restart: boolean = false): this {\n const clip = this._clips.get(clipName);\n if (!clip) {\n console.warn(`[Animation] Clip \"${clipName}\" not found`);\n return this;\n }\n\n if (this.currentClip === clip && this.isPlaying && !restart) {\n return this;\n }\n\n const isNewClip = this.currentClip !== clip;\n this.currentClip = clip;\n this.isPlaying = true;\n this.isPaused = false;\n this.isFinished = false;\n this._direction = clip.wrapMode === 'reverse' ? -1 : 1;\n\n if (restart || isNewClip) {\n this.currentTime = 0;\n this.currentFrameIndex = this._direction === 1 ? 0 : clip.frames.length - 1;\n this._applyFrame();\n }\n\n return this;\n }\n\n public pause(): this {\n this.isPaused = true;\n return this;\n }\n\n public resume(): this {\n if (this.currentClip && !this.isFinished) {\n this.isPaused = false;\n this.isPlaying = true;\n }\n return this;\n }\n\n public stop(): this {\n this.isPlaying = false;\n this.isPaused = false;\n this.currentTime = 0;\n this.currentFrameIndex = 0;\n return this;\n }\n\n public gotoAndStop(frameIndex: number): this {\n if (!this.currentClip) return this;\n this.currentFrameIndex = Math.max(0, Math.min(this.currentClip.frames.length - 1, frameIndex));\n this.isPlaying = false;\n this._applyFrame();\n return this;\n }\n\n public gotoAndPlay(frameIndex: number): this {\n this.gotoAndStop(frameIndex);\n this.isPlaying = true;\n return this;\n }\n\n /**\n * Advances the animation timeline. Zero per-frame memory allocation.\n */\n public update(dt?: number): void {\n if (!this.isPlaying || this.isPaused || !this.currentClip || this.isFinished) {\n return;\n }\n\n const delta = (dt !== undefined ? dt : Time.deltaTime) * this.playbackSpeed;\n if (delta <= 0) return;\n\n this.currentTime += delta;\n const clip = this.currentClip;\n const frames = clip.frames;\n if (frames.length === 0) return;\n\n let currentFrame = frames[this.currentFrameIndex];\n let iterations = 0;\n const maxIterations = frames.length * 2;\n\n while (\n this.currentTime >= Math.max(0.0001, currentFrame.duration) &&\n this.isPlaying &&\n !this.isFinished &&\n iterations++ < maxIterations\n ) {\n const frameDuration = Math.max(0.0001, currentFrame.duration);\n this.currentTime -= frameDuration;\n\n if (clip.wrapMode === 'once') {\n if (this.currentFrameIndex + 1 >= frames.length) {\n this.currentFrameIndex = frames.length - 1;\n this.isPlaying = false;\n this.isFinished = true;\n this._applyFrame();\n this.onComplete?.();\n return;\n }\n this.currentFrameIndex++;\n } else if (clip.wrapMode === 'loop') {\n this.currentFrameIndex = (this.currentFrameIndex + 1) % frames.length;\n if (this.currentFrameIndex === 0) {\n this.onLoop?.();\n }\n } else if (clip.wrapMode === 'ping-pong') {\n const next = this.currentFrameIndex + this._direction;\n if (next >= frames.length) {\n this._direction = -1;\n this.currentFrameIndex = Math.max(0, frames.length - 2);\n } else if (next < 0) {\n this._direction = 1;\n this.currentFrameIndex = Math.min(frames.length - 1, 1);\n this.onLoop?.();\n } else {\n this.currentFrameIndex = next;\n }\n } else if (clip.wrapMode === 'reverse') {\n if (this.currentFrameIndex - 1 < 0) {\n this.currentFrameIndex = 0;\n this.isPlaying = false;\n this.isFinished = true;\n this._applyFrame();\n this.onComplete?.();\n return;\n }\n this.currentFrameIndex--;\n }\n\n currentFrame = frames[this.currentFrameIndex];\n this._applyFrame();\n }\n\n if (iterations >= maxIterations) {\n this.currentTime = 0;\n }\n }\n\n private _applyFrame(): void {\n if (!this.currentClip || this.currentClip.frames.length === 0) return;\n const frame = this.currentClip.frames[this.currentFrameIndex];\n if (this.targetSprite) {\n this.targetSprite.sourceRect.copy(frame.sourceRect);\n if (frame.anchor) {\n this.targetSprite.anchor.copy(frame.anchor);\n }\n }\n this.onFrame?.(this.currentFrameIndex, frame);\n }\n}\n","import { Rect } from '../math/Rect';\nimport { AnimationClip, AnimationFrame, PlaybackMode } from './Animation';\n\nexport interface SpriteSheetGridOptions {\n frameWidth: number;\n frameHeight: number;\n columns?: number;\n rows?: number;\n spacing?: number;\n margin?: number;\n totalFrames?: number;\n}\n\n/**\n * Utility for slicing texture atlases and grid sprite sheets.\n */\nexport class SpriteSheet {\n public readonly texture: any;\n public readonly frames: Rect[] = [];\n\n constructor(texture: any, options: SpriteSheetGridOptions) {\n this.texture = texture;\n const texW = (texture?.width as number) || 0;\n const texH = (texture?.height as number) || 0;\n\n const fw = options.frameWidth;\n const fh = options.frameHeight;\n const spacing = options.spacing ?? 0;\n const margin = options.margin ?? 0;\n\n const cols = options.columns ?? (fw > 0 ? Math.floor((texW - margin * 2 + spacing) / (fw + spacing)) : 1);\n const rows = options.rows ?? (fh > 0 ? Math.floor((texH - margin * 2 + spacing) / (fh + spacing)) : 1);\n const maxFrames = options.totalFrames ?? (cols * rows);\n\n let count = 0;\n for (let r = 0; r < rows && count < maxFrames; r++) {\n for (let c = 0; c < cols && count < maxFrames; c++) {\n const x = margin + c * (fw + spacing);\n const y = margin + r * (fh + spacing);\n this.frames.push(new Rect(x, y, fw, fh));\n count++;\n }\n }\n }\n\n public getFrame(index: number): Rect {\n if (index < 0 || index >= this.frames.length) {\n throw new Error(`[SpriteSheet] Frame index ${index} out of bounds (0..${this.frames.length - 1})`);\n }\n return this.frames[index];\n }\n\n public createClip(\n name: string,\n frameIndices: number[],\n fps: number = 12,\n wrapMode: PlaybackMode = 'loop'\n ): AnimationClip {\n const frameDuration = fps > 0 ? 1 / fps : 0.1;\n const frames: AnimationFrame[] = frameIndices.map((idx, i) => ({\n index: i,\n sourceRect: this.getFrame(idx),\n duration: frameDuration\n }));\n\n return new AnimationClip({ name, frames, fps, wrapMode });\n }\n}\n","import { Vector2 } from '../math/Vector2';\nimport { Color } from '../math/Color';\nimport { MathUtils } from '../math/MathUtils';\nimport { Sprite } from './Sprite';\nimport { CanvasContext } from './CanvasContext';\nimport { ICanvasRenderingContext2D } from './CanvasMock';\n\nexport interface Particle {\n active: boolean;\n x: number;\n y: number;\n vx: number;\n vy: number;\n life: number;\n maxLife: number;\n startSize: number;\n endSize: number;\n currentSize: number;\n rotation: number;\n angularVelocity: number;\n // Unpacked scalar start/end colors (eliminates per-frame Color allocations)\n startR: number; startG: number; startB: number; startA: number;\n endR: number; endG: number; endB: number; endA: number;\n // Interpolated scalar color\n r: number; g: number; b: number; a: number;\n}\n\nexport type RangeValue = number | [number, number];\n\nexport interface ParticleEmitterConfig {\n /** Maximum particles in the pre-allocated pool (default: 500) */\n maxParticles?: number;\n /** Continuous emission rate in particles per second (default: 50) */\n rate?: number;\n /** Lifetime in seconds [min, max] or scalar (default: [0.5, 1.5]) */\n lifetime?: RangeValue;\n /** Speed in pixels per second [min, max] (default: [50, 150]) */\n speed?: RangeValue;\n /** Emission angle in radians [min, max] (default: [0, Math.PI * 2]) */\n angle?: RangeValue;\n /** Angular spread around angle in radians (default: 0) */\n spread?: number;\n /** Particle size in pixels at birth [min, max] (default: [4, 8]) */\n startSize?: RangeValue;\n /** Particle size in pixels at death [min, max] (default: [0, 2]) */\n endSize?: RangeValue;\n /** Starting color (default: Color.WHITE) */\n startColor?: Color | string;\n /** Ending color (default: Color.TRANSPARENT) */\n endColor?: Color | string;\n /** Constant external acceleration (e.g. gravity: { x: 0, y: 150 }) */\n gravity?: Vector2 | { x: number; y: number };\n /** Acceleration directed away from emitter origin (positive) or inward (negative) */\n radialAcceleration?: RangeValue;\n /** Perpendicular orbital acceleration (vortex effect) */\n tangentialAcceleration?: RangeValue;\n /** Angular spin speed in radians per second [min, max] */\n angularVelocity?: RangeValue;\n /** Canvas composite operation (default: 'source-over', use 'lighter' for fire/glow) */\n blendMode?: GlobalCompositeOperation;\n /** Particle visual shape */\n shape?: 'circle' | 'rect' | 'sprite';\n /** Texture or Sprite used when shape === 'sprite' */\n texture?: CanvasImageSource | Sprite | any;\n}\n\nexport class ParticleSystem {\n public position: Vector2 = new Vector2(0, 0);\n public config: Required<Omit<ParticleEmitterConfig, 'gravity' | 'texture' | 'startColor' | 'endColor'>> & {\n gravity: Vector2;\n startColor: Color;\n endColor: Color;\n texture?: CanvasImageSource | Sprite | any;\n };\n\n private _pool: Particle[] = [];\n private _activeCount: number = 0;\n private _emitTimer: number = 0;\n public isEmitting: boolean = true;\n\n constructor(config: ParticleEmitterConfig = {}) {\n const max = config.maxParticles ?? 500;\n const startCol = config.startColor instanceof Color\n ? config.startColor\n : Color.parse(config.startColor ?? '#ffffff');\n const endCol = config.endColor instanceof Color\n ? config.endColor\n : Color.parse(config.endColor ?? 'rgba(255,255,255,0)');\n\n this.config = {\n maxParticles: max,\n rate: config.rate ?? 50,\n lifetime: config.lifetime ?? [0.5, 1.5],\n speed: config.speed ?? [50, 150],\n angle: config.angle ?? [0, Math.PI * 2],\n spread: config.spread ?? 0,\n startSize: config.startSize ?? [4, 8],\n endSize: config.endSize ?? [0, 2],\n startColor: startCol,\n endColor: endCol,\n gravity: config.gravity instanceof Vector2\n ? config.gravity.clone()\n : new Vector2(config.gravity?.x ?? 0, config.gravity?.y ?? 0),\n radialAcceleration: config.radialAcceleration ?? 0,\n tangentialAcceleration: config.tangentialAcceleration ?? 0,\n angularVelocity: config.angularVelocity ?? 0,\n blendMode: config.blendMode ?? 'source-over',\n shape: config.shape ?? 'circle',\n texture: config.texture\n };\n\n // Pre-allocate fixed pool (zero runtime allocations)\n for (let i = 0; i < max; i++) {\n this._pool.push({\n active: false,\n x: 0, y: 0,\n vx: 0, vy: 0,\n life: 0, maxLife: 1,\n startSize: 4, endSize: 0, currentSize: 4,\n rotation: 0, angularVelocity: 0,\n startR: 255, startG: 255, startB: 255, startA: 1,\n endR: 255, endG: 255, endB: 255, endA: 0,\n r: 255, g: 255, b: 255, a: 1\n });\n }\n }\n\n public get activeCount(): number {\n return this._activeCount;\n }\n\n private _resolveRange(val: RangeValue): [number, number] {\n return Array.isArray(val) ? val : [val, val];\n }\n\n /**\n * Instantly emits N particles (e.g. for explosions or impacts).\n */\n public burst(count: number, originX: number = this.position.x, originY: number = this.position.y): void {\n for (let i = 0; i < count; i++) {\n if (this._activeCount >= this.config.maxParticles) break;\n this._spawnParticle(originX, originY);\n }\n }\n\n private _spawnParticle(x: number, y: number): void {\n if (this._activeCount >= this.config.maxParticles) return;\n\n const p = this._pool[this._activeCount];\n p.active = true;\n p.x = x;\n p.y = y;\n\n const [speedMin, speedMax] = this._resolveRange(this.config.speed);\n const speed = MathUtils.randomRange(speedMin, speedMax);\n\n const [angMin, angMax] = this._resolveRange(this.config.angle);\n let angle = MathUtils.randomRange(angMin, angMax);\n if (this.config.spread > 0) {\n angle += MathUtils.randomRange(-this.config.spread / 2, this.config.spread / 2);\n }\n\n p.vx = Math.cos(angle) * speed;\n p.vy = Math.sin(angle) * speed;\n\n const [lifeMin, lifeMax] = this._resolveRange(this.config.lifetime);\n p.life = 0;\n p.maxLife = Math.max(0.001, MathUtils.randomRange(lifeMin, lifeMax));\n\n const [sSizeMin, sSizeMax] = this._resolveRange(this.config.startSize);\n p.startSize = MathUtils.randomRange(sSizeMin, sSizeMax);\n\n const [eSizeMin, eSizeMax] = this._resolveRange(this.config.endSize);\n p.endSize = MathUtils.randomRange(eSizeMin, eSizeMax);\n p.currentSize = p.startSize;\n\n const [angVelMin, angVelMax] = this._resolveRange(this.config.angularVelocity);\n p.angularVelocity = MathUtils.randomRange(angVelMin, angVelMax);\n p.rotation = MathUtils.randomRange(0, Math.PI * 2);\n\n p.startR = this.config.startColor.r;\n p.startG = this.config.startColor.g;\n p.startB = this.config.startColor.b;\n p.startA = this.config.startColor.a;\n\n p.endR = this.config.endColor.r;\n p.endG = this.config.endColor.g;\n p.endB = this.config.endColor.b;\n p.endA = this.config.endColor.a;\n\n p.r = p.startR;\n p.g = p.startG;\n p.b = p.startB;\n p.a = p.startA;\n\n this._activeCount++;\n }\n\n /**\n * Advances simulation using O(1) swap-and-pop despawning with zero allocations.\n */\n public update(dt: number): void {\n if (dt <= 0) return;\n\n // 1. Continuous emission\n if (this.isEmitting && this.config.rate > 0) {\n this._emitTimer += dt;\n const interval = 1 / this.config.rate;\n while (this._emitTimer >= interval) {\n this._spawnParticle(this.position.x, this.position.y);\n this._emitTimer -= interval;\n }\n }\n\n // 2. Physics & color updates via Swap-and-Pop\n const gx = this.config.gravity.x;\n const gy = this.config.gravity.y;\n const [radMin, radMax] = this._resolveRange(this.config.radialAcceleration);\n const [tanMin, tanMax] = this._resolveRange(this.config.tangentialAcceleration);\n const hasRadial = radMin !== 0 || radMax !== 0;\n const hasTan = tanMin !== 0 || tanMax !== 0;\n\n for (let i = 0; i < this._activeCount; i++) {\n const p = this._pool[i];\n p.life += dt;\n\n // Despawn check: Swap with last active particle\n if (p.life >= p.maxLife) {\n this._activeCount--;\n if (i < this._activeCount) {\n const last = this._pool[this._activeCount];\n this._pool[this._activeCount] = p;\n this._pool[i] = last;\n i--; // Re-process current index with newly swapped particle\n }\n p.active = false;\n continue;\n }\n\n // Progress normalized [0, 1]\n const t = p.life / p.maxLife;\n\n // Constant gravity\n p.vx += gx * dt;\n p.vy += gy * dt;\n\n // Radial and tangential forces\n if (hasRadial || hasTan) {\n const dx = p.x - this.position.x;\n const dy = p.y - this.position.y;\n const dist = Math.sqrt(dx * dx + dy * dy);\n if (dist > 0.0001) {\n const nx = dx / dist;\n const ny = dy / dist;\n\n if (hasRadial) {\n const radAcc = MathUtils.randomRange(radMin, radMax);\n p.vx += nx * radAcc * dt;\n p.vy += ny * radAcc * dt;\n }\n\n if (hasTan) {\n const tanAcc = MathUtils.randomRange(tanMin, tanMax);\n p.vx += -ny * tanAcc * dt;\n p.vy += nx * tanAcc * dt;\n }\n }\n }\n\n // Position update\n p.x += p.vx * dt;\n p.y += p.vy * dt;\n\n // Rotation\n if (p.angularVelocity !== 0) {\n p.rotation += p.angularVelocity * dt;\n }\n\n // Size interpolation\n p.currentSize = p.startSize + (p.endSize - p.startSize) * t;\n\n // RGBA color interpolation (scalar arithmetic)\n p.r = Math.round(p.startR + (p.endR - p.startR) * t);\n p.g = Math.round(p.startG + (p.endG - p.startG) * t);\n p.b = Math.round(p.startB + (p.endB - p.startB) * t);\n p.a = p.startA + (p.endA - p.startA) * t;\n }\n }\n\n private _getRawContext(ctx: CanvasRenderingContext2D | ICanvasRenderingContext2D | CanvasContext | any): any {\n return ctx instanceof CanvasContext ? ctx.rawContext : ctx;\n }\n\n /**\n * Fast Canvas2D batch rendering.\n */\n public render(context: CanvasRenderingContext2D | ICanvasRenderingContext2D | CanvasContext | any): void {\n if (this._activeCount === 0) return;\n\n const ctx = this._getRawContext(context);\n const prevComposite = ctx.globalCompositeOperation;\n if (this.config.blendMode !== 'source-over') {\n ctx.globalCompositeOperation = this.config.blendMode;\n }\n\n const shape = this.config.shape;\n\n for (let i = 0; i < this._activeCount; i++) {\n const p = this._pool[i];\n if (p.currentSize <= 0.01 || p.a <= 0) continue;\n\n ctx.fillStyle = `rgba(${p.r},${p.g},${p.b},${p.a})`;\n\n if (shape === 'circle') {\n ctx.beginPath();\n ctx.arc(p.x, p.y, Math.max(0.1, p.currentSize), 0, Math.PI * 2);\n ctx.fill();\n } else if (shape === 'rect') {\n const half = p.currentSize;\n if (p.rotation !== 0) {\n ctx.save();\n ctx.translate(p.x, p.y);\n ctx.rotate(p.rotation);\n ctx.fillRect(-half, -half, half * 2, half * 2);\n ctx.restore();\n } else {\n ctx.fillRect(p.x - half, p.y - half, half * 2, half * 2);\n }\n } else if (shape === 'sprite' && this.config.texture) {\n const tex = this.config.texture;\n const size = p.currentSize * 2;\n ctx.save();\n ctx.translate(p.x, p.y);\n if (p.rotation !== 0) ctx.rotate(p.rotation);\n ctx.globalAlpha = p.a;\n\n if (tex instanceof Sprite) {\n tex.draw(ctx, 0, 0, 0, size / tex.width, size / tex.height);\n } else {\n ctx.drawImage(tex, -p.currentSize, -p.currentSize, size, size);\n }\n ctx.restore();\n }\n }\n\n if (this.config.blendMode !== 'source-over') {\n ctx.globalCompositeOperation = prevComposite;\n }\n }\n\n public clear(): void {\n this._activeCount = 0;\n this._emitTimer = 0;\n }\n}\n","import { Color } from '../math/Color';\nimport { Vector2 } from '../math/Vector2';\nimport { CanvasContext } from './CanvasContext';\nimport { ICanvasRenderingContext2D } from './CanvasMock';\n\nexport type ContextLike = CanvasRenderingContext2D | ICanvasRenderingContext2D | CanvasContext | any;\n\nexport class Shapes {\n private static _getRaw(ctx: ContextLike): any {\n return ctx instanceof CanvasContext ? ctx.rawContext : ctx;\n }\n\n private static _resolveColor(color: Color | string): string {\n return color instanceof Color ? color.toRgbaString() : color;\n }\n\n public static line(\n ctx: ContextLike,\n x1: number,\n y1: number,\n x2: number,\n y2: number,\n color: Color | string,\n lineWidth: number = 1,\n lineCap: CanvasLineCap = 'butt'\n ): void {\n const raw = this._getRaw(ctx);\n raw.strokeStyle = this._resolveColor(color);\n raw.lineWidth = lineWidth;\n raw.lineCap = lineCap;\n raw.beginPath();\n raw.moveTo(x1, y1);\n raw.lineTo(x2, y2);\n raw.stroke();\n }\n\n public static rect(\n ctx: ContextLike,\n x: number,\n y: number,\n width: number,\n height: number,\n color: Color | string,\n filled: boolean = true,\n lineWidth: number = 1\n ): void {\n const raw = this._getRaw(ctx);\n const col = this._resolveColor(color);\n if (filled) {\n raw.fillStyle = col;\n raw.fillRect(x, y, width, height);\n } else {\n raw.strokeStyle = col;\n raw.lineWidth = lineWidth;\n raw.strokeRect(x, y, width, height);\n }\n }\n\n public static roundedRect(\n ctx: ContextLike,\n x: number,\n y: number,\n width: number,\n height: number,\n radius: number,\n color: Color | string,\n filled: boolean = true,\n lineWidth: number = 1\n ): void {\n const raw = this._getRaw(ctx);\n const col = this._resolveColor(color);\n raw.beginPath();\n\n // Use native roundRect if supported by modern browser or mock\n if (typeof raw.roundRect === 'function') {\n raw.roundRect(x, y, width, height, radius);\n } else {\n // Robust geometric fallback for older canvas or headless Node.js\n const r = Math.min(radius, width / 2, height / 2);\n raw.moveTo(x + r, y);\n raw.lineTo(x + width - r, y);\n raw.arcTo(x + width, y, x + width, y + r, r);\n raw.lineTo(x + width, y + height - r);\n raw.arcTo(x + width, y + height, x + width - r, y + height, r);\n raw.lineTo(x + r, y + height);\n raw.arcTo(x, y + height, x, y + height - r, r);\n raw.lineTo(x, y + r);\n raw.arcTo(x, y, x + r, y, r);\n raw.closePath();\n }\n\n if (filled) {\n raw.fillStyle = col;\n raw.fill();\n } else {\n raw.strokeStyle = col;\n raw.lineWidth = lineWidth;\n raw.stroke();\n }\n }\n\n public static circle(\n ctx: ContextLike,\n x: number,\n y: number,\n radius: number,\n color: Color | string,\n filled: boolean = true,\n lineWidth: number = 1\n ): void {\n const raw = this._getRaw(ctx);\n const col = this._resolveColor(color);\n raw.beginPath();\n raw.arc(x, y, radius, 0, Math.PI * 2);\n if (filled) {\n raw.fillStyle = col;\n raw.fill();\n } else {\n raw.strokeStyle = col;\n raw.lineWidth = lineWidth;\n raw.stroke();\n }\n }\n\n public static arc(\n ctx: ContextLike,\n x: number,\n y: number,\n radius: number,\n startAngle: number,\n endAngle: number,\n color: Color | string,\n anticlockwise: boolean = false,\n lineWidth: number = 1\n ): void {\n const raw = this._getRaw(ctx);\n raw.strokeStyle = this._resolveColor(color);\n raw.lineWidth = lineWidth;\n raw.beginPath();\n raw.arc(x, y, radius, startAngle, endAngle, anticlockwise);\n raw.stroke();\n }\n\n public static ellipse(\n ctx: ContextLike,\n x: number,\n y: number,\n radiusX: number,\n radiusY: number,\n rotation: number = 0,\n color: Color | string,\n filled: boolean = true,\n lineWidth: number = 1\n ): void {\n const raw = this._getRaw(ctx);\n const col = this._resolveColor(color);\n raw.beginPath();\n if (typeof raw.ellipse === 'function') {\n raw.ellipse(x, y, radiusX, radiusY, rotation, 0, Math.PI * 2);\n } else {\n raw.save();\n raw.translate(x, y);\n raw.rotate(rotation);\n raw.scale(radiusX, radiusY);\n raw.arc(0, 0, 1, 0, Math.PI * 2);\n raw.restore();\n }\n\n if (filled) {\n raw.fillStyle = col;\n raw.fill();\n } else {\n raw.strokeStyle = col;\n raw.lineWidth = lineWidth;\n raw.stroke();\n }\n }\n\n public static polygon(\n ctx: ContextLike,\n points: Array<{ x: number; y: number } | Vector2>,\n color: Color | string,\n filled: boolean = true,\n lineWidth: number = 1\n ): void {\n if (points.length < 3) return;\n const raw = this._getRaw(ctx);\n const col = this._resolveColor(color);\n raw.beginPath();\n raw.moveTo(points[0].x, points[0].y);\n for (let i = 1; i < points.length; i++) {\n raw.lineTo(points[i].x, points[i].y);\n }\n raw.closePath();\n\n if (filled) {\n raw.fillStyle = col;\n raw.fill();\n } else {\n raw.strokeStyle = col;\n raw.lineWidth = lineWidth;\n raw.stroke();\n }\n }\n\n public static path(\n ctx: ContextLike,\n points: Array<{ x: number; y: number } | Vector2>,\n color: Color | string,\n closed: boolean = false,\n lineWidth: number = 1\n ): void {\n if (points.length < 2) return;\n const raw = this._getRaw(ctx);\n raw.strokeStyle = this._resolveColor(color);\n raw.lineWidth = lineWidth;\n raw.beginPath();\n raw.moveTo(points[0].x, points[0].y);\n for (let i = 1; i < points.length; i++) {\n raw.lineTo(points[i].x, points[i].y);\n }\n if (closed) raw.closePath();\n raw.stroke();\n }\n}\n","import { Color } from '../math/Color';\nimport { createMockCanvas } from './CanvasMock';\n\nexport class AssetLoader {\n private _textures: Map<string, CanvasImageSource> = new Map();\n private _inFlight: Map<string, Promise<CanvasImageSource>> = new Map();\n\n public loadedCount: number = 0;\n public totalCount: number = 0;\n\n public get isLoading(): boolean {\n return this._inFlight.size > 0;\n }\n\n public get progress(): number {\n return this.totalCount === 0 ? 1 : this.loadedCount / this.totalCount;\n }\n\n /**\n * Loads an image asynchronously with zero crash risk.\n * If the file is missing or network fails, logs a warning and returns a procedural fallback.\n */\n public loadTexture(key: string, url: string): Promise<CanvasImageSource> {\n if (this._textures.has(key)) {\n return Promise.resolve(this._textures.get(key)!);\n }\n\n if (this._inFlight.has(key)) {\n return this._inFlight.get(key)!;\n }\n\n this.totalCount++;\n\n let resolvePromise!: (img: CanvasImageSource) => void;\n const promise = new Promise<CanvasImageSource>((resolve) => {\n resolvePromise = resolve;\n }).finally(() => {\n this._inFlight.delete(key);\n });\n\n this._inFlight.set(key, promise);\n\n // Headless / Node.js test environment check\n if (typeof window === 'undefined' || typeof Image === 'undefined') {\n const mockImg = this.createCheckerboardTexture(32, 32);\n this._textures.set(key, mockImg);\n this.loadedCount++;\n resolvePromise(mockImg);\n return promise;\n }\n\n const img = new Image();\n img.onload = () => {\n this._textures.set(key, img);\n this.loadedCount++;\n resolvePromise(img);\n };\n\n img.onerror = (err) => {\n console.warn(`[AssetLoader] Texture \"${key}\" failed to load from \"${url}\". Substituting procedural fallback.`, err);\n const fallback = this.createCheckerboardTexture(32, 32);\n this._textures.set(key, fallback);\n this.loadedCount++;\n resolvePromise(fallback);\n };\n\n img.src = url;\n return promise;\n\n }\n\n /**\n * Batch loads multiple textures with optional progress callback.\n */\n public async loadTextures(\n manifest: Record<string, string>,\n onProgress?: (progress: number) => void\n ): Promise<Map<string, CanvasImageSource>> {\n const keys = Object.keys(manifest);\n const promises = keys.map(key => this.loadTexture(key, manifest[key]));\n\n let loaded = 0;\n for (const p of promises) {\n await p;\n loaded++;\n onProgress?.(loaded / keys.length);\n }\n\n return this._textures;\n }\n\n public getTexture(key: string): CanvasImageSource | undefined {\n return this._textures.get(key);\n }\n\n public hasTexture(key: string): boolean {\n return this._textures.has(key);\n }\n\n public registerTexture(key: string, texture: CanvasImageSource): void {\n this._textures.set(key, texture);\n }\n\n /**\n * Generates a high-contrast magenta/black checkerboard fallback texture.\n */\n public createCheckerboardTexture(\n width: number = 32,\n height: number = 32,\n color1: Color | string = '#ff00ff',\n color2: Color | string = '#000000',\n tileSize: number = 8\n ): CanvasImageSource {\n const c1 = color1 instanceof Color ? color1.toRgbaString() : color1;\n const c2 = color2 instanceof Color ? color2.toRgbaString() : color2;\n\n if (typeof document === 'undefined') {\n const mock = createMockCanvas(width, height);\n const ctx = mock.getContext('2d')!;\n const cols = Math.ceil(width / tileSize);\n const rows = Math.ceil(height / tileSize);\n for (let r = 0; r < rows; r++) {\n for (let c = 0; c < cols; c++) {\n ctx.fillStyle = (r + c) % 2 === 0 ? c1 : c2;\n ctx.fillRect(c * tileSize, r * tileSize, tileSize, tileSize);\n }\n }\n return mock as unknown as CanvasImageSource;\n }\n\n const canvas = document.createElement('canvas');\n canvas.width = width;\n canvas.height = height;\n const ctx = canvas.getContext('2d');\n if (!ctx) return canvas;\n\n const cols = Math.ceil(width / tileSize);\n const rows = Math.ceil(height / tileSize);\n\n for (let r = 0; r < rows; r++) {\n for (let c = 0; c < cols; c++) {\n ctx.fillStyle = (r + c) % 2 === 0 ? c1 : c2;\n ctx.fillRect(c * tileSize, r * tileSize, tileSize, tileSize);\n }\n }\n\n return canvas;\n }\n\n /**\n * Generates a solid 1x1 or custom size color texture.\n */\n public createSolidTexture(\n width: number = 1,\n height: number = 1,\n color: Color | string = Color.WHITE\n ): CanvasImageSource {\n const colStr = color instanceof Color ? color.toRgbaString() : color;\n\n if (typeof document === 'undefined') {\n const mock = createMockCanvas(width, height);\n const ctx = mock.getContext('2d')!;\n ctx.fillStyle = colStr;\n ctx.fillRect(0, 0, width, height);\n return mock as unknown as CanvasImageSource;\n }\n\n const canvas = document.createElement('canvas');\n canvas.width = width;\n canvas.height = height;\n const ctx = canvas.getContext('2d');\n if (ctx) {\n ctx.fillStyle = colStr;\n ctx.fillRect(0, 0, width, height);\n }\n return canvas;\n }\n\n /**\n * Generates a smooth circular gradient texture (ideal for particle systems).\n */\n public createCircleTexture(\n radius: number = 16,\n color: Color | string = Color.WHITE\n ): CanvasImageSource {\n const size = radius * 2;\n const col = color instanceof Color ? color : Color.parse(color);\n\n if (typeof document === 'undefined') {\n const mock = createMockCanvas(size, size);\n const ctx = mock.getContext('2d')!;\n ctx.fillStyle = col.toRgbaString();\n ctx.beginPath();\n ctx.arc(radius, radius, radius, 0, Math.PI * 2);\n ctx.fill();\n return mock as unknown as CanvasImageSource;\n }\n\n const canvas = document.createElement('canvas');\n canvas.width = size;\n canvas.height = size;\n const ctx = canvas.getContext('2d');\n if (ctx) {\n const grad = ctx.createRadialGradient(radius, radius, 0, radius, radius, radius);\n grad.addColorStop(0, col.toRgbaString());\n grad.addColorStop(1, `rgba(${col.r},${col.g},${col.b},0)`);\n\n ctx.fillStyle = grad;\n ctx.beginPath();\n ctx.arc(radius, radius, radius, 0, Math.PI * 2);\n ctx.fill();\n }\n return canvas;\n }\n\n public clear(): void {\n this._textures.clear();\n this._inFlight.clear();\n this.loadedCount = 0;\n this.totalCount = 0;\n }\n}\n","import { MathUtils } from '../math/MathUtils';\nimport type { IScene } from './Scene';\n\n/**\n * Standard easing function signature: maps progress t in [0, 1] to eased value.\n */\nexport type EasingFunction = (t: number) => number;\n\n/**\n * Built-in easing functions for smooth scene transitions.\n */\nexport const Easing = {\n linear: (t: number): number => t,\n easeInQuad: (t: number): number => t * t,\n easeOutQuad: (t: number): number => t * (2 - t),\n easeInOutQuad: (t: number): number =>\n t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t,\n easeInCubic: (t: number): number => t * t * t,\n easeOutCubic: (t: number): number => {\n const p = t - 1;\n return p * p * p + 1;\n },\n easeInOutCubic: (t: number): number =>\n t < 0.5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1,\n smoothstep: (t: number): number => MathUtils.smoothstep(0, 1, t)\n} as const;\n\n/**\n * Base transition configuration options.\n */\nexport interface TransitionOptions {\n /** Duration of transition in seconds (default: 0.5s) */\n duration?: number;\n /** Easing function to apply to progress (default: Easing.linear) */\n easing?: EasingFunction;\n}\n\n/**\n * Abstract base class for all scene visual transitions.\n */\nexport abstract class SceneTransition {\n public duration: number;\n public elapsed: number = 0;\n public progress: number = 0;\n public isComplete: boolean = false;\n public easing: EasingFunction;\n\n /**\n * If true, transition has a distinct midpoint (e.g. Fade to solid color)\n * where the actual scene switch takes place.\n */\n public readonly hasMidpoint: boolean = false;\n public midpointTriggered: boolean = false;\n\n constructor(options: TransitionOptions = {}) {\n this.duration = Math.max(0, options.duration ?? 0.5);\n this.easing = options.easing ?? Easing.linear;\n if (this.duration === 0) {\n this.isComplete = true;\n this.progress = 1.0;\n }\n }\n\n /**\n * Reset transition timers and flags before starting.\n */\n public reset(): void {\n this.elapsed = 0;\n this.progress = 0;\n this.isComplete = this.duration === 0;\n this.midpointTriggered = false;\n }\n\n /**\n * Initialize transition for a specific scene pairing.\n */\n public start(_fromScene: IScene | null, _toScene: IScene | null): void {\n this.reset();\n }\n\n /**\n * Advance transition time and calculate eased progress.\n */\n public update(dt: number): void {\n if (this.isComplete) return;\n\n this.elapsed += dt;\n const rawProgress = this.duration > 0 ? Math.min(1.0, this.elapsed / this.duration) : 1.0;\n this.progress = MathUtils.clamp01(this.easing(rawProgress));\n\n if (rawProgress >= 1.0) {\n this.isComplete = true;\n this.progress = 1.0;\n }\n }\n\n /**\n * Render the transitioning visual state.\n */\n public abstract render(\n ctx: CanvasRenderingContext2D | any,\n fromScene: IScene | null,\n toScene: IScene | null\n ): void;\n\n /**\n * Helper to retrieve canvas logical dimensions.\n */\n protected getCanvasDimensions(ctx: any): { width: number; height: number } {\n const width = ctx?.virtualWidth ?? ctx?.canvas?.width ?? 800;\n const height = ctx?.virtualHeight ?? ctx?.canvas?.height ?? 600;\n return { width, height };\n }\n}\n\n/**\n * Options for FadeTransition.\n */\nexport interface FadeTransitionOptions extends TransitionOptions {\n /** Fade color (default: '#000000' black) */\n color?: string;\n}\n\n/**\n * Two-phase solid color fade transition:\n * Phase 1 (0 -> 50%): fades fromScene to color.\n * Midpoint (50%): scenes swap.\n * Phase 2 (50% -> 100%): fades color to toScene.\n */\nexport class FadeTransition extends SceneTransition {\n public override readonly hasMidpoint: boolean = true;\n public readonly color: string;\n\n constructor(options: FadeTransitionOptions = {}) {\n super(options);\n this.color = options.color ?? '#000000';\n }\n\n public render(\n ctx: CanvasRenderingContext2D | any,\n fromScene: IScene | null,\n toScene: IScene | null\n ): void {\n const { width, height } = this.getCanvasDimensions(ctx);\n\n let overlayAlpha: number;\n if (this.progress <= 0.5) {\n // Phase 1: Render fromScene, fade to color\n fromScene?.render(ctx);\n overlayAlpha = this.progress * 2.0;\n } else {\n // Phase 2: Render toScene, fade from color\n toScene?.render(ctx);\n overlayAlpha = (1.0 - this.progress) * 2.0;\n }\n\n overlayAlpha = MathUtils.clamp01(overlayAlpha);\n if (overlayAlpha > 0) {\n ctx.save();\n ctx.fillStyle = this.color;\n ctx.globalAlpha = overlayAlpha;\n ctx.fillRect(0, 0, width, height);\n ctx.restore();\n }\n }\n}\n\n/**\n * Slide transition directions and presentation modes.\n */\nexport type SlideDirection = 'left' | 'right' | 'up' | 'down';\nexport type SlideMode = 'push' | 'cover' | 'reveal';\n\nexport interface SlideTransitionOptions extends TransitionOptions {\n direction?: SlideDirection;\n mode?: SlideMode;\n}\n\n/**\n * Slide transition translating scenes across screen boundaries.\n */\nexport class SlideTransition extends SceneTransition {\n public readonly direction: SlideDirection;\n public readonly mode: SlideMode;\n\n constructor(options: SlideTransitionOptions = {}) {\n super(options);\n this.direction = options.direction ?? 'left';\n this.mode = options.mode ?? 'push';\n }\n\n public render(\n ctx: CanvasRenderingContext2D | any,\n fromScene: IScene | null,\n toScene: IScene | null\n ): void {\n const { width, height } = this.getCanvasDimensions(ctx);\n\n let dirX = 0;\n let dirY = 0;\n switch (this.direction) {\n case 'left':\n dirX = -width;\n break;\n case 'right':\n dirX = width;\n break;\n case 'up':\n dirY = -height;\n break;\n case 'down':\n dirY = height;\n break;\n }\n\n let fromX = 0;\n let fromY = 0;\n let toX = 0;\n let toY = 0;\n\n switch (this.mode) {\n case 'push':\n fromX = dirX * this.progress;\n fromY = dirY * this.progress;\n toX = dirX * (this.progress - 1.0);\n toY = dirY * (this.progress - 1.0);\n break;\n case 'cover':\n fromX = 0;\n fromY = 0;\n toX = dirX * (this.progress - 1.0);\n toY = dirY * (this.progress - 1.0);\n break;\n case 'reveal':\n fromX = dirX * this.progress;\n fromY = dirY * this.progress;\n toX = 0;\n toY = 0;\n break;\n }\n\n // Render underlying scene first in cover mode, or fromScene in push mode\n if (this.mode === 'reveal') {\n if (toScene) {\n ctx.save();\n ctx.translate(toX, toY);\n toScene.render(ctx);\n ctx.restore();\n }\n if (fromScene) {\n ctx.save();\n ctx.translate(fromX, fromY);\n fromScene.render(ctx);\n ctx.restore();\n }\n } else {\n if (fromScene) {\n ctx.save();\n ctx.translate(fromX, fromY);\n fromScene.render(ctx);\n ctx.restore();\n }\n if (toScene) {\n ctx.save();\n ctx.translate(toX, toY);\n toScene.render(ctx);\n ctx.restore();\n }\n }\n }\n}\n\n/**\n * CrossFade transition blending transparency directly between scenes.\n */\nexport class CrossFadeTransition extends SceneTransition {\n public render(\n ctx: CanvasRenderingContext2D | any,\n fromScene: IScene | null,\n toScene: IScene | null\n ): void {\n const p = MathUtils.clamp01(this.progress);\n\n if (fromScene && p < 1.0) {\n ctx.save();\n ctx.globalAlpha = 1.0 - p;\n fromScene.render(ctx);\n ctx.restore();\n }\n\n if (toScene && p > 0.0) {\n ctx.save();\n ctx.globalAlpha = p;\n toScene.render(ctx);\n ctx.restore();\n }\n }\n}\n\n/**\n * Instantaneous scene switch with 0s duration.\n */\nexport class InstantTransition extends SceneTransition {\n constructor() {\n super({ duration: 0 });\n }\n\n public render(\n ctx: CanvasRenderingContext2D | any,\n _fromScene: IScene | null,\n toScene: IScene | null\n ): void {\n toScene?.render(ctx);\n }\n}\n","import { UIElement, UIElementOptions } from './UIElement';\nimport { Rect } from '../math/Rect';\nimport { Color } from '../math/Color';\nimport { MathUtils } from '../math/MathUtils';\nimport { UILabel } from './UILabel';\nimport { drawRoundedRectPath } from './UIPanel';\nimport { UIAnchor, UIPivot } from './UIAnchor';\n\nexport type UIProgressDirection = 'horizontal-ltr' | 'horizontal-rtl' | 'vertical-btt' | 'vertical-ttb';\n\nexport interface UIProgressBarOptions extends UIElementOptions {\n value?: number;\n min?: number;\n max?: number;\n direction?: UIProgressDirection;\n backgroundColor?: string | Color;\n borderColor?: string | Color;\n borderWidth?: number;\n borderRadius?: number;\n fillColor?: string | Color;\n fillPadding?: number;\n fillBorderRadius?: number;\n showText?: boolean;\n textFormat?: (val: number, max: number, normalized: number) => string;\n}\n\n/**\n * Responsive Progress Bar for Health, Mana, Shields, and Loading Bars.\n */\nexport class UIProgressBar extends UIElement {\n public value: number;\n public min: number;\n public max: number;\n public direction: UIProgressDirection;\n\n public backgroundColor: string | Color;\n public borderColor: string | Color;\n public borderWidth: number;\n public borderRadius: number;\n\n public fillColor: string | Color;\n public fillPadding: number;\n public fillBorderRadius: number;\n\n public showText: boolean;\n public textFormat?: (val: number, max: number, normalized: number) => string;\n public label?: UILabel;\n\n constructor(options: UIProgressBarOptions = {}) {\n super({\n size: options.size ?? { x: 200, y: 24 },\n ...options\n });\n\n this.min = options.min ?? 0;\n this.max = options.max ?? 100;\n this.value = options.value !== undefined ? options.value : this.max;\n this.direction = options.direction ?? 'horizontal-ltr';\n\n this.backgroundColor = options.backgroundColor ?? '#1e1e2e';\n this.borderColor = options.borderColor ?? '#313244';\n this.borderWidth = options.borderWidth ?? 1;\n this.borderRadius = options.borderRadius ?? 4;\n\n this.fillColor = options.fillColor ?? '#22c55e';\n this.fillPadding = options.fillPadding ?? 2;\n this.fillBorderRadius = options.fillBorderRadius ?? 2;\n\n this.showText = options.showText ?? false;\n this.textFormat = options.textFormat;\n\n if (this.showText) {\n this.label = new UILabel({\n text: this._getFormattedText(),\n fontSize: Math.max(10, Math.floor(this.size.y * 0.6)),\n align: 'center',\n baseline: 'middle',\n anchor: UIAnchor.Center,\n pivot: UIPivot.Center,\n interactive: false\n });\n this.addChild(this.label);\n }\n }\n\n public get normalizedValue(): number {\n if (this.max <= this.min) return 0;\n return MathUtils.clamp01((this.value - this.min) / (this.max - this.min));\n }\n\n public set normalizedValue(norm: number) {\n this.value = this.min + MathUtils.clamp01(norm) * (this.max - this.min);\n this._syncLabel();\n }\n\n public setProgress(current: number, max?: number): this {\n if (max !== undefined) this.max = max;\n this.value = Math.max(this.min, Math.min(this.max, current));\n this._syncLabel();\n return this;\n }\n\n private _getFormattedText(): string {\n const norm = this.normalizedValue;\n if (this.textFormat) {\n return this.textFormat(this.value, this.max, norm);\n }\n return `${Math.round(norm * 100)}%`;\n }\n\n private _syncLabel(): void {\n if (this.label && this.showText) {\n this.label.text = this._getFormattedText();\n }\n }\n\n protected override draw(raw: any, localBounds: Rect): void {\n const { x, y, width, height } = localBounds;\n\n // 1. Draw Background Track\n raw.beginPath();\n drawRoundedRectPath(raw, x, y, width, height, this.borderRadius);\n raw.fillStyle = this.backgroundColor instanceof Color ? this.backgroundColor.toRgbaString() : this.backgroundColor;\n raw.fill();\n\n if (this.borderWidth > 0 && this.borderColor) {\n raw.strokeStyle = this.borderColor instanceof Color ? this.borderColor.toRgbaString() : this.borderColor;\n raw.lineWidth = this.borderWidth;\n raw.stroke();\n }\n\n // 2. Draw Fill Track\n const norm = this.normalizedValue;\n if (norm <= 0) return;\n\n const pad = this.fillPadding;\n const innerX = x + pad;\n const innerY = y + pad;\n const innerW = Math.max(0, width - pad * 2);\n const innerH = Math.max(0, height - pad * 2);\n\n let fx = innerX;\n let fy = innerY;\n let fw = innerW;\n let fh = innerH;\n\n switch (this.direction) {\n case 'horizontal-ltr':\n fw = innerW * norm;\n break;\n case 'horizontal-rtl':\n fw = innerW * norm;\n fx = innerX + (innerW - fw);\n break;\n case 'vertical-btt':\n fh = innerH * norm;\n fy = innerY + (innerH - fh);\n break;\n case 'vertical-ttb':\n fh = innerH * norm;\n break;\n }\n\n if (fw > 0 && fh > 0) {\n raw.beginPath();\n drawRoundedRectPath(raw, fx, fy, fw, fh, this.fillBorderRadius);\n raw.fillStyle = this.fillColor instanceof Color ? this.fillColor.toRgbaString() : this.fillColor;\n raw.fill();\n }\n }\n}\n","/**\n * Mock representation of an automated AudioParam.\n */\nexport class MockAudioParam {\n public value: number;\n public defaultValue: number;\n public minValue: number;\n public maxValue: number;\n public scheduledEvents: Array<{ type: string; value: number; time: number }> = [];\n\n constructor(defaultValue: number = 0, minValue: number = -3.4e38, maxValue: number = 3.4e38) {\n this.value = defaultValue;\n this.defaultValue = defaultValue;\n this.minValue = minValue;\n this.maxValue = maxValue;\n }\n\n public setValueAtTime(value: number, startTime: number): this {\n this.value = value;\n this.scheduledEvents.push({ type: 'setValue', value, time: startTime });\n return this;\n }\n\n public linearRampToValueAtTime(value: number, endTime: number): this {\n this.value = value;\n this.scheduledEvents.push({ type: 'linearRamp', value, time: endTime });\n return this;\n }\n\n public exponentialRampToValueAtTime(value: number, endTime: number): this {\n this.value = value;\n this.scheduledEvents.push({ type: 'exponentialRamp', value, time: endTime });\n return this;\n }\n\n public setTargetAtTime(target: number, startTime: number, _timeConstant: number): this {\n this.value = target;\n this.scheduledEvents.push({ type: 'setTarget', value: target, time: startTime });\n return this;\n }\n\n public cancelScheduledValues(cancelTime: number): this {\n this.scheduledEvents = this.scheduledEvents.filter(e => e.time < cancelTime);\n return this;\n }\n}\n\n/**\n * Base mock audio node.\n */\nexport class MockAudioNode {\n public context: MockAudioContext;\n public connections: (MockAudioNode | MockAudioParam)[] = [];\n\n constructor(context: MockAudioContext) {\n this.context = context;\n }\n\n public connect(destination: MockAudioNode | MockAudioParam): any {\n this.connections.push(destination);\n return destination;\n }\n\n public disconnect(destination?: MockAudioNode | MockAudioParam): void {\n if (!destination) {\n this.connections.length = 0;\n } else {\n const idx = this.connections.indexOf(destination);\n if (idx !== -1) this.connections.splice(idx, 1);\n }\n }\n}\n\n/**\n * Mock GainNode with an automated gain parameter.\n */\nexport class MockGainNode extends MockAudioNode {\n public gain: MockAudioParam;\n\n constructor(context: MockAudioContext) {\n super(context);\n this.gain = new MockAudioParam(1.0, 0, 100);\n }\n}\n\n/**\n * Mock OscillatorNode.\n */\nexport class MockOscillatorNode extends MockAudioNode {\n public type: OscillatorType = 'sine';\n public frequency: MockAudioParam;\n public detune: MockAudioParam;\n public started: boolean = false;\n public stopped: boolean = false;\n public startTime: number = 0;\n public stopTime: number = 0;\n public onended: ((ev?: any) => void) | null = null;\n\n constructor(context: MockAudioContext) {\n super(context);\n this.frequency = new MockAudioParam(440, 0, 24000);\n this.detune = new MockAudioParam(0, -153600, 153600);\n }\n\n public start(when: number = 0): void {\n this.started = true;\n this.startTime = when;\n }\n\n public stop(when: number = 0): void {\n this.stopped = true;\n this.stopTime = when;\n if (this.onended) {\n queueMicrotask(() => {\n if (this.onended) this.onended();\n });\n }\n }\n}\n\n/**\n * Mock AudioBuffer.\n */\nexport class MockAudioBuffer {\n public numberOfChannels: number;\n public length: number;\n public sampleRate: number;\n public duration: number;\n private _channels: Float32Array[];\n\n constructor(options: { numberOfChannels: number; length: number; sampleRate: number }) {\n this.numberOfChannels = options.numberOfChannels;\n this.length = options.length;\n this.sampleRate = options.sampleRate;\n this.duration = options.length / options.sampleRate;\n this._channels = [];\n for (let i = 0; i < options.numberOfChannels; i++) {\n this._channels.push(new Float32Array(options.length));\n }\n }\n\n public getChannelData(channel: number): Float32Array {\n if (channel < 0 || channel >= this.numberOfChannels) {\n throw new RangeError(`MockAudioBuffer: Channel ${channel} out of bounds`);\n }\n return this._channels[channel];\n }\n\n public copyFromChannel(destination: Float32Array, channelNumber: number, bufferOffset: number = 0): void {\n const src = this.getChannelData(channelNumber);\n destination.set(src.subarray(bufferOffset, bufferOffset + destination.length));\n }\n\n public copyToChannel(source: Float32Array, channelNumber: number, bufferOffset: number = 0): void {\n const dest = this.getChannelData(channelNumber);\n dest.set(source, bufferOffset);\n }\n}\n\n/**\n * Mock AudioBufferSourceNode.\n */\nexport class MockAudioBufferSourceNode extends MockAudioNode {\n public buffer: MockAudioBuffer | null = null;\n public playbackRate: MockAudioParam;\n public detune: MockAudioParam;\n public loop: boolean = false;\n public loopStart: number = 0;\n public loopEnd: number = 0;\n public started: boolean = false;\n public stopped: boolean = false;\n public onended: ((ev?: any) => void) | null = null;\n\n constructor(context: MockAudioContext) {\n super(context);\n this.playbackRate = new MockAudioParam(1.0, 0, 1024);\n this.detune = new MockAudioParam(0, -153600, 153600);\n }\n\n public start(_when: number = 0, _offset: number = 0, _duration?: number): void {\n this.started = true;\n }\n\n public stop(_when: number = 0): void {\n this.stopped = true;\n if (this.onended) {\n queueMicrotask(() => {\n if (this.onended) this.onended();\n });\n }\n }\n}\n\n/**\n * Mock AudioContext.\n */\nexport class MockAudioContext {\n public state: 'suspended' | 'running' | 'closed' = 'suspended';\n public currentTime: number = 0;\n public sampleRate: number = 44100;\n public destination: MockAudioNode;\n\n constructor() {\n this.destination = new MockAudioNode(this);\n }\n\n public createGain(): MockGainNode {\n return new MockGainNode(this);\n }\n\n public createOscillator(): MockOscillatorNode {\n return new MockOscillatorNode(this);\n }\n\n public createBufferSource(): MockAudioBufferSourceNode {\n return new MockAudioBufferSourceNode(this);\n }\n\n public createBuffer(channels: number, length: number, sampleRate: number): MockAudioBuffer {\n return new MockAudioBuffer({ numberOfChannels: channels, length, sampleRate });\n }\n\n public async resume(): Promise<void> {\n this.state = 'running';\n }\n\n public async suspend(): Promise<void> {\n this.state = 'suspended';\n }\n\n public async close(): Promise<void> {\n this.state = 'closed';\n }\n\n public advanceTime(seconds: number): void {\n this.currentTime += seconds;\n }\n\n public decodeAudioData(arrayBuffer: ArrayBuffer): Promise<MockAudioBuffer> {\n return Promise.resolve(new MockAudioBuffer({\n numberOfChannels: 2,\n length: 44100,\n sampleRate: 44100\n }));\n }\n}\n\n/**\n * Installs mock audio classes onto the global object for headless unit testing.\n */\nexport function installAudioMocks(): void {\n (globalThis as any).AudioContext = MockAudioContext;\n (globalThis as any).webkitAudioContext = MockAudioContext;\n (globalThis as any).AudioBuffer = MockAudioBuffer;\n}\n","import { Component } from '../Component';\nimport { Sprite, type SpriteConfig } from '../../rendering/Sprite';\nimport type { Renderer } from '../../rendering/Renderer';\nimport type { Color } from '../../math/Color';\nimport type { Rect } from '../../math/Rect';\nimport { Vector2 } from '../../math/Vector2';\n\n/**\n * Component that renders a 2D Sprite using the Entity's Transform2D.\n */\nexport class SpriteComponent extends Component {\n public sprite: Sprite;\n public zIndex: number = 0;\n\n constructor(spriteOrConfig: Sprite | SpriteConfig) {\n super();\n if (spriteOrConfig instanceof Sprite) {\n this.sprite = spriteOrConfig;\n } else {\n this.sprite = new Sprite(spriteOrConfig);\n }\n }\n\n public get width(): number {\n return this.sprite.width;\n }\n\n public set width(val: number) {\n this.sprite.width = val;\n }\n\n public get height(): number {\n return this.sprite.height;\n }\n\n public set height(val: number) {\n this.sprite.height = val;\n }\n\n public get anchor(): Vector2 {\n return this.sprite.anchor;\n }\n\n public set anchor(val: Vector2) {\n this.sprite.anchor.copy(val);\n }\n\n public get tint(): Color | null {\n return this.sprite.tint;\n }\n\n public set tint(val: Color | string | null) {\n this.sprite.setTint(val);\n }\n\n public get flipX(): boolean {\n return this.sprite.flipX;\n }\n\n public set flipX(val: boolean) {\n this.sprite.flipX = val;\n }\n\n public get flipY(): boolean {\n return this.sprite.flipY;\n }\n\n public set flipY(val: boolean) {\n this.sprite.flipY = val;\n }\n\n public get opacity(): number {\n return this.sprite.opacity;\n }\n\n public set opacity(val: number) {\n this.sprite.opacity = Math.max(0, Math.min(1, val));\n }\n\n public getBounds(out?: Rect): Rect {\n return this.sprite.getBounds(out);\n }\n\n public override onRender(renderer: Renderer): void {\n if (!this.sprite || !this.sprite.texture) return;\n\n const camera = this.entity.entityManager?.camera;\n\n renderer.submit({\n layer: this.entity.layer,\n zIndex: this.entity.zIndex + this.zIndex,\n camera: camera ?? undefined,\n render: (ctx) => {\n this.sprite.drawTransform(ctx, this.entity.transform);\n }\n });\n }\n}\n","import { Component } from '../Component';\nimport { Shapes } from '../../rendering/Shapes';\nimport type { Renderer } from '../../rendering/Renderer';\nimport type { Color } from '../../math/Color';\nimport { Vector2 } from '../../math/Vector2';\nimport { CanvasContext } from '../../rendering/CanvasContext';\n\nexport type ShapeType = 'rect' | 'circle' | 'roundedRect' | 'ellipse' | 'polygon' | 'line';\n\nexport interface ShapeComponentConfig {\n type?: ShapeType;\n color?: Color | string;\n filled?: boolean;\n lineWidth?: number;\n size?: Vector2 | { x: number; y: number };\n radius?: number;\n cornerRadius?: number;\n radiusX?: number;\n radiusY?: number;\n points?: Vector2[];\n offset?: Vector2 | { x: number; y: number };\n zIndex?: number;\n}\n\n/**\n * Component that renders primitive vector shapes using the Entity's Transform2D.\n */\nexport class ShapeComponent extends Component {\n public shapeType: ShapeType;\n public color: Color | string;\n public filled: boolean;\n public lineWidth: number;\n public size: Vector2;\n public radius: number;\n public cornerRadius: number;\n public radiusX: number;\n public radiusY: number;\n public points: Vector2[];\n public offset: Vector2;\n public zIndex: number;\n\n constructor(config: ShapeComponentConfig = {}) {\n super();\n this.shapeType = config.type ?? 'rect';\n this.color = config.color ?? '#ffffff';\n this.filled = config.filled ?? true;\n this.lineWidth = config.lineWidth ?? 1;\n this.size = config.size instanceof Vector2\n ? config.size.clone()\n : new Vector2(config.size?.x ?? 32, config.size?.y ?? 32);\n this.radius = config.radius ?? 16;\n this.cornerRadius = config.cornerRadius ?? 4;\n this.radiusX = config.radiusX ?? 16;\n this.radiusY = config.radiusY ?? 8;\n this.points = config.points\n ? config.points.map((p) => (p instanceof Vector2 ? p.clone() : new Vector2((p as any).x, (p as any).y)))\n : [];\n this.offset = config.offset instanceof Vector2\n ? config.offset.clone()\n : new Vector2(config.offset?.x ?? 0, config.offset?.y ?? 0);\n this.zIndex = config.zIndex ?? 0;\n }\n\n // ==========================================\n // Static Factory Helpers\n // ==========================================\n\n public static rect(\n width: number,\n height: number,\n color: Color | string = '#ffffff',\n filled: boolean = true\n ): ShapeComponent {\n return new ShapeComponent({ type: 'rect', size: new Vector2(width, height), color, filled });\n }\n\n public static circle(\n radius: number,\n color: Color | string = '#ffffff',\n filled: boolean = true\n ): ShapeComponent {\n return new ShapeComponent({ type: 'circle', radius, color, filled });\n }\n\n public static roundedRect(\n width: number,\n height: number,\n cornerRadius: number = 4,\n color: Color | string = '#ffffff',\n filled: boolean = true\n ): ShapeComponent {\n return new ShapeComponent({\n type: 'roundedRect',\n size: new Vector2(width, height),\n cornerRadius,\n color,\n filled\n });\n }\n\n public static polygon(\n points: Vector2[],\n color: Color | string = '#ffffff',\n filled: boolean = true\n ): ShapeComponent {\n return new ShapeComponent({ type: 'polygon', points, color, filled });\n }\n\n public static line(\n points: Vector2[],\n color: Color | string = '#ffffff',\n lineWidth: number = 1\n ): ShapeComponent {\n return new ShapeComponent({ type: 'line', points, color, filled: false, lineWidth });\n }\n\n // ==========================================\n // Render Hook\n // ==========================================\n\n public override onRender(renderer: Renderer): void {\n const camera = this.entity.entityManager?.camera;\n\n renderer.submit({\n layer: this.entity.layer,\n zIndex: this.entity.zIndex + this.zIndex,\n camera: camera ?? undefined,\n render: (ctx) => {\n const raw = ctx instanceof CanvasContext ? ctx.rawContext : ctx;\n raw.save();\n this.entity.transform.updateWorldMatrix().transformContext(raw as any);\n\n const ox = this.offset.x;\n const oy = this.offset.y;\n\n switch (this.shapeType) {\n case 'rect':\n Shapes.rect(\n raw,\n ox - this.size.x / 2,\n oy - this.size.y / 2,\n this.size.x,\n this.size.y,\n this.color,\n this.filled,\n this.lineWidth\n );\n break;\n case 'circle':\n Shapes.circle(raw, ox, oy, this.radius, this.color, this.filled, this.lineWidth);\n break;\n case 'roundedRect':\n Shapes.roundedRect(\n raw,\n ox - this.size.x / 2,\n oy - this.size.y / 2,\n this.size.x,\n this.size.y,\n this.cornerRadius,\n this.color,\n this.filled,\n this.lineWidth\n );\n break;\n case 'ellipse':\n Shapes.ellipse(raw, ox, oy, this.radiusX, this.radiusY, 0, this.color, this.filled, this.lineWidth);\n break;\n case 'polygon':\n Shapes.polygon(raw, this.points, this.color, this.filled, this.lineWidth);\n break;\n case 'line':\n Shapes.path(raw, this.points, this.color, false, this.lineWidth);\n break;\n }\n\n raw.restore();\n }\n });\n }\n}\n","import { Component } from '../Component';\nimport type { Vector2 } from '../../math/Vector2';\nimport type { Collider2D } from '../../physics/Collider2D';\nimport type { ContactManifold } from '../../physics/ContactSolver';\nimport type { Renderer } from '../../rendering/Renderer';\n\n/**\n * Open-ended Script Component designed for custom gameplay behaviors,\n * input handling, and event reaction.\n */\nexport abstract class ScriptComponent extends Component {\n // ==========================================\n // Ergonomic Shortcuts\n // ==========================================\n\n public get position(): Vector2 {\n return this.entity.transform.position;\n }\n\n public get rotation(): number {\n return this.entity.transform.rotation;\n }\n\n public set rotation(val: number) {\n this.entity.transform.rotation = val;\n }\n\n public get scale(): Vector2 {\n return this.entity.transform.scale;\n }\n\n public destroyEntity(): void {\n this.entity.destroy();\n }\n\n // ==========================================\n // Overridable Lifecycle Hooks\n // ==========================================\n\n public override onStart(): void {}\n public override onUpdate(_dt: number): void {}\n public override onFixedUpdate(_dt: number): void {}\n public override onRender(_renderer: Renderer): void {}\n public override onDestroy(): void {}\n\n // ==========================================\n // Overridable Physics Event Hooks\n // ==========================================\n\n public onCollisionEnter(_other: Collider2D, _manifold: ContactManifold): void {}\n public onCollisionStay(_other: Collider2D, _manifold: ContactManifold): void {}\n public onCollisionExit(_other: Collider2D): void {}\n public onTriggerEnter(_other: Collider2D): void {}\n public onTriggerStay(_other: Collider2D): void {}\n public onTriggerExit(_other: Collider2D): void {}\n}\n\n/**\n * Semantic alias for ScriptComponent to support Godot/Unity naming conventions.\n */\nexport { ScriptComponent as Behavior };\n","/**\n * FrameworkGame - Production-grade 2D Game Framework for Web/HTML5\n */\n\nexport const VERSION = '1.0.0';\nexport const FRAMEWORK_NAME = 'FrameworkGame';\n\n// Math & Geometry Subsystem\nexport * from './math/index';\n\n// Core Engine Subsystem (Game, createGame, GameLoop, Time, EventEmitter)\nexport * from './core/index';\n\n// 2D Rendering Pipeline Subsystem\nexport * from './rendering/index';\n\n// Unified Input Subsystem\nexport * from './input/index';\n\n// 2D Physics Engine Subsystem\nexport * from './physics/index';\n\n// Scene Management Subsystem\nexport * from './scene/index';\n\n// UI Subsystem\nexport * from './ui/index';\n\n// Web Audio Subsystem\nexport * from './audio/index';\n\n// Entity-Component System\nexport * from './entity/index';\n"],"mappings":"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"}
|