UNPKG

2d-physics-engine

Version:

A lightweight, flexible 2D physics engine with ECS architecture, built with TypeScript

140 lines 4.63 kB
import { Physics } from '../systems/PhysicsSystem/Physics.system'; import { Rendering } from '../systems/Rendering.system'; export class Iterator { constructor(inputManager, canvas, canvasCtx, config) { Object.defineProperty(this, "inputManager", { enumerable: true, configurable: true, writable: true, value: inputManager }); Object.defineProperty(this, "fixedTimeStep", { enumerable: true, configurable: true, writable: true, value: 1 / 60 }); // 60 FPS physics Object.defineProperty(this, "maxDeltaTime", { enumerable: true, configurable: true, writable: true, value: 0.1 }); Object.defineProperty(this, "debug", { enumerable: true, configurable: true, writable: true, value: false }); Object.defineProperty(this, "systems", { enumerable: true, configurable: true, writable: true, value: [] }); Object.defineProperty(this, "scene", { enumerable: true, configurable: true, writable: true, value: null }); Object.defineProperty(this, "lastFrameTime", { enumerable: true, configurable: true, writable: true, value: 0 }); Object.defineProperty(this, "isRunning", { enumerable: true, configurable: true, writable: true, value: false }); Object.defineProperty(this, "accumulator", { enumerable: true, configurable: true, writable: true, value: 0 }); if (!canvas || !canvasCtx) { throw new Error('Canvas and canvas-context are required for engine initialization.'); } this.fixedTimeStep = config?.fixedTimeStep ?? this.fixedTimeStep; this.maxDeltaTime = config?.maxDeltaTime ?? this.maxDeltaTime; this.debug = config?.debug ?? this.debug; // Initialize systems this.systems.push(new Rendering(canvas, canvasCtx), new Physics()); this.loop = this.loop.bind(this); } setScene(scene) { if (this.scene) { this.scene.onUnload(); } this.scene = scene; scene.onLoad(); } addSystem(system) { this.systems.push(system); } start() { if (!this.isRunning) { this.isRunning = true; this.lastFrameTime = performance.now(); this.accumulator = 0; requestAnimationFrame(this.loop); } } stop() { this.isRunning = false; } loop(currentTime) { if (!this.isRunning) return; // Clamps the delta time to maxDeltaTime in seconds to prevent large jumps if the game lags const deltaTime = Math.min((currentTime - this.lastFrameTime) / 1000, this.maxDeltaTime); this.lastFrameTime = currentTime; if (this.debug) { this.logDebugInfo(deltaTime); } // Fixed timestep updates for physics this.accumulator += deltaTime; while (this.accumulator >= this.fixedTimeStep) { this.fixedUpdate(this.fixedTimeStep); this.accumulator -= this.fixedTimeStep; } // Variable timestep updates for everything else this.update(deltaTime); requestAnimationFrame(this.loop); } logDebugInfo(deltaTime) { // TODO: print log info on canvas instead of console console.log({ fps: Math.round(1 / deltaTime), deltaTime: deltaTime.toFixed(4), entities: this.scene?.getEntities().length ?? 0, accumulator: this.accumulator.toFixed(4), }); } fixedUpdate(fixedDeltaTime) { if (this.scene) { for (const system of this.systems) { if (system.needsFixedUpdate) { system.update(fixedDeltaTime, this.scene); } } } } update(deltaTime) { this.inputManager.update(); if (this.scene) { // Update systems that don't need fixed timestep for (const system of this.systems) { if (!system.needsFixedUpdate) { system.update(deltaTime, this.scene); } } this.scene.update(deltaTime); } } } //# sourceMappingURL=Iterator.js.map