|
import { Layer, GameLayer, GUILayer, DebugLayer, TerminalLayer, LayerType } from './layer.js'; |
|
import { Camera } from './camera.js'; |
|
import { FPSCounter, ZoomControls } from './gui.js'; |
|
import { Entity } from './entity.js'; |
|
import { getConfig } from './config.js'; |
|
import { state } from './state.js'; |
|
|
|
export class Scene { |
|
constructor() { |
|
this.rootLayer = new Layer('root'); |
|
this.camera = new Camera(); |
|
this.entities = new Map(); |
|
} |
|
|
|
start() { |
|
|
|
const gameLayer = new GameLayer(); |
|
const guiLayer = new GUILayer(); |
|
const debugLayer = new DebugLayer(); |
|
const terminalLayer = new TerminalLayer(); |
|
|
|
|
|
gameLayer.setParent(this.rootLayer); |
|
guiLayer.setParent(gameLayer); |
|
debugLayer.setParent(guiLayer); |
|
terminalLayer.setParent(debugLayer); |
|
|
|
|
|
const fpsCounter = new FPSCounter(); |
|
const zoomControls = new ZoomControls(); |
|
debugLayer.addEntity(fpsCounter); |
|
debugLayer.addEntity(zoomControls); |
|
|
|
|
|
state.fpsCounter = fpsCounter; |
|
state.zoomControls = zoomControls; |
|
|
|
|
|
const config = getConfig(); |
|
const testEntity = new Entity(); |
|
testEntity.boundingBox = { width: config.squareSize, height: config.squareSize }; |
|
|
|
|
|
const centerX = 0; |
|
const centerY = 0; |
|
testEntity.transform.setPosition( |
|
centerX + Math.cos(0) * config.radius, |
|
centerY + Math.sin(0) * config.radius, |
|
0 |
|
); |
|
|
|
|
|
testEntity.animationState = { |
|
angle: 0, |
|
speed: config.initialAngularSpeed, |
|
centerX, |
|
centerY, |
|
radius: config.radius |
|
}; |
|
|
|
|
|
testEntity.update = (deltaTime) => { |
|
const state = testEntity.animationState; |
|
state.speed += config.angularAcceleration * deltaTime; |
|
state.angle += state.speed * deltaTime; |
|
|
|
|
|
testEntity.transform.setPosition( |
|
state.centerX + Math.cos(state.angle) * state.radius, |
|
state.centerY + Math.sin(state.angle) * state.radius, |
|
0 |
|
); |
|
}; |
|
|
|
|
|
gameLayer.addEntity(testEntity); |
|
state.testEntity = testEntity; |
|
|
|
|
|
this.camera.moveTo(0, 0, 0); |
|
} |
|
|
|
getLayer(type) { |
|
let current = this.rootLayer; |
|
while (current) { |
|
if (current.type === type) { |
|
return current; |
|
} |
|
current = current.child; |
|
} |
|
return null; |
|
} |
|
|
|
getLayers() { |
|
const layers = []; |
|
let current = this.rootLayer; |
|
while (current) { |
|
if (current.type !== 'root') { |
|
layers.push(current); |
|
} |
|
current = current.child; |
|
} |
|
return layers; |
|
} |
|
|
|
draw(ctx) { |
|
|
|
this.rootLayer.draw(ctx, this.camera); |
|
} |
|
|
|
update(deltaTime) { |
|
|
|
const gameLayer = this.getLayer(LayerType.GAME); |
|
gameLayer?.entities.forEach(entity => { |
|
if (entity.update) { |
|
entity.update(deltaTime); |
|
} |
|
}); |
|
|
|
|
|
const debugLayer = this.getLayer(LayerType.DEBUG); |
|
if (debugLayer) { |
|
debugLayer.entities.forEach(entity => { |
|
if (entity.constructor.name === 'FPSCounter' && entity.update) { |
|
entity.update( |
|
|
|
window.state?.fps ?? 0, |
|
|
|
this.camera?.currentVelocity ?? { x: 0, y: 0 } |
|
); |
|
} |
|
}); |
|
} |
|
} |
|
} |
|
|