smolworld / src /js /engine.js
p3nGu1nZz's picture
✨ Refactor physics module; add math utilities and event handling classes; update state structure for 3D entities
7ffaa9e
import { createTerminal } from './terminal.js';
import { createInputHandler } from './input.js';
import { Scene } from './scene.js';
import { LayerType } from './layer.js'; // Only need LayerType
import { mergeConfig, getConfig } from './config.js';
import { state } from './state.js';
import { Time } from './time.js';
import { Physics } from './physics.js';
function start(userConfig) {
if (state.engineStarted) {
console.error("Engine.start() called more than once!");
return;
}
// Initialize config first
mergeConfig(userConfig);
state.engineStarted = true;
// Create and setup canvas
const canvas = document.createElement('canvas');
document.body.appendChild(canvas);
state.ctx = canvas.getContext('2d');
// Create scene first
state.scene = new Scene();
state.scene.start();
// Define and call resizeCanvas after scene creation
const resizeCanvas = () => {
state.canvasWidth = canvas.width = window.innerWidth;
state.canvasHeight = canvas.height = window.innerHeight;
// Now camera is available
state.scene.camera.setViewport(state.canvasWidth, state.canvasHeight);
};
resizeCanvas();
// Create input handler with canvas and scene
state.inputHandler = createInputHandler(canvas, state.scene);
// Create terminal last
const terminalLayer = state.scene.getLayer(LayerType.TERMINAL);
state.terminal = createTerminal(canvas, state.ctx, state.inputHandler);
terminalLayer.addEntity(state.terminal);
const config = getConfig(); // Get config at the start function level
// Add resize listener
window.addEventListener('resize', resizeCanvas);
}
export function run(userConfig) {
state.currentConfig = userConfig;
if (!state.engineStarted) {
start(userConfig);
}
const config = getConfig();
state.angularSpeed = config.initialAngularSpeed;
state.physics = new Physics(config);
// Game functions
function Update(deltaTime) {
// Clear the canvas
state.ctx.clearRect(0, 0, state.canvasWidth, state.canvasHeight);
// Update camera
state.scene.camera.update(deltaTime);
// Update scene (this will update entities)
state.scene.update(deltaTime);
// FPS calculation
state.fps = Math.round(1 / deltaTime);
// Draw scene (now includes debug layer)
state.scene.draw(state.ctx);
// Draw terminal text
state.terminal.drawText();
}
function FixedUpdate(deltaTime) {
state.physics.update(deltaTime);
}
// Game loop
function gameLoop() {
state.animationFrameId = requestAnimationFrame(gameLoop);
Time.update();
while (Time.accumulatedTime >= Time.fixedDeltaTime) {
FixedUpdate(Time.fixedDeltaTime);
Time.resetAccumulator();
}
Update(Time.deltaTime);
}
// Start the game loop
gameLoop();
}