feat: add poc
This commit is contained in:
parent
43d27b04d9
commit
4a4fa05ce4
53 changed files with 6191 additions and 0 deletions
139
src/core/Engine.js
Normal file
139
src/core/Engine.js
Normal file
|
|
@ -0,0 +1,139 @@
|
|||
import { System } from './System.js';
|
||||
import { Entity } from './Entity.js';
|
||||
import { EventBus } from './EventBus.js';
|
||||
|
||||
/**
|
||||
* Main game engine - manages ECS, game loop, and systems
|
||||
*/
|
||||
export class Engine {
|
||||
constructor(canvas) {
|
||||
this.canvas = canvas;
|
||||
this.ctx = canvas.getContext('2d');
|
||||
this.entities = [];
|
||||
this.systems = [];
|
||||
this.events = new EventBus();
|
||||
this.running = false;
|
||||
this.lastTime = 0;
|
||||
|
||||
// Set canvas size
|
||||
this.canvas.width = 1024;
|
||||
this.canvas.height = 768;
|
||||
|
||||
// Game state
|
||||
this.deltaTime = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a system to the engine
|
||||
*/
|
||||
addSystem(system) {
|
||||
if (system instanceof System) {
|
||||
system.init(this);
|
||||
this.systems.push(system);
|
||||
// Sort by priority (lower priority runs first)
|
||||
this.systems.sort((a, b) => a.priority - b.priority);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Emit an event locally
|
||||
*/
|
||||
emit(event, data) {
|
||||
this.events.emit(event, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Subscribe to an event
|
||||
*/
|
||||
on(event, callback) {
|
||||
return this.events.on(event, callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create and add an entity
|
||||
*/
|
||||
createEntity() {
|
||||
const entity = new Entity();
|
||||
this.entities.push(entity);
|
||||
return entity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove an entity
|
||||
*/
|
||||
removeEntity(entity) {
|
||||
const index = this.entities.indexOf(entity);
|
||||
if (index > -1) {
|
||||
this.entities.splice(index, 1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all entities
|
||||
*/
|
||||
getEntities() {
|
||||
return this.entities.filter(e => e.active);
|
||||
}
|
||||
|
||||
/**
|
||||
* Main game loop
|
||||
*/
|
||||
start() {
|
||||
if (this.running) return;
|
||||
this.running = true;
|
||||
this.lastTime = performance.now();
|
||||
this.gameLoop();
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop the game loop
|
||||
*/
|
||||
stop() {
|
||||
this.running = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Game loop using requestAnimationFrame
|
||||
*/
|
||||
gameLoop = (currentTime = 0) => {
|
||||
if (!this.running) return;
|
||||
|
||||
// Calculate delta time
|
||||
this.deltaTime = (currentTime - this.lastTime) / 1000; // Convert to seconds
|
||||
this.lastTime = currentTime;
|
||||
|
||||
// Clamp delta time to prevent large jumps
|
||||
this.deltaTime = Math.min(this.deltaTime, 0.1);
|
||||
|
||||
// Update all systems
|
||||
const menuSystem = this.systems.find(s => s.name === 'MenuSystem');
|
||||
const gameState = menuSystem ? menuSystem.getGameState() : 'playing';
|
||||
const isPaused = gameState === 'paused' || gameState === 'start';
|
||||
|
||||
this.systems.forEach(system => {
|
||||
// Skip game systems if paused/start menu (but allow MenuSystem, UISystem, and RenderSystem)
|
||||
if (isPaused && system.name !== 'MenuSystem' && system.name !== 'UISystem' && system.name !== 'RenderSystem') {
|
||||
return;
|
||||
}
|
||||
system.update(this.deltaTime, this.entities);
|
||||
});
|
||||
|
||||
// Update input system's previous states at end of frame
|
||||
const inputSystem = this.systems.find(s => s.name === 'InputSystem');
|
||||
if (inputSystem && inputSystem.updatePreviousStates) {
|
||||
inputSystem.updatePreviousStates();
|
||||
}
|
||||
|
||||
// Continue loop
|
||||
requestAnimationFrame(this.gameLoop);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the canvas
|
||||
*/
|
||||
clear() {
|
||||
this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue