File size: 4,447 Bytes
7ffaa9e
 
 
 
 
 
7b453e7
 
 
7ffaa9e
 
 
7b453e7
 
7ffaa9e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7b453e7
 
7ffaa9e
 
 
 
 
 
 
 
 
 
7b453e7
 
 
7ffaa9e
 
 
 
 
 
 
 
 
 
 
7b453e7
7ffaa9e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7b453e7
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
import { Layer, GameLayer, GUILayer, DebugLayer, TerminalLayer, LayerType } from './layer.js';  // Add LayerType
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() {
        // Create layer hierarchy with correct order
        const gameLayer = new GameLayer();
        const guiLayer = new GUILayer();
        const debugLayer = new DebugLayer();
        const terminalLayer = new TerminalLayer();

        // Set up layer hierarchy (bottom to top)
        gameLayer.setParent(this.rootLayer);     // game -> root
        guiLayer.setParent(gameLayer);           // gui -> game
        debugLayer.setParent(guiLayer);          // debug -> gui
        terminalLayer.setParent(debugLayer);     // terminal -> debug (top-most)

        // Create and add debug controls
        const fpsCounter = new FPSCounter();
        const zoomControls = new ZoomControls();
        debugLayer.addEntity(fpsCounter);
        debugLayer.addEntity(zoomControls);

        // Store references needed by state
        state.fpsCounter = fpsCounter;
        state.zoomControls = zoomControls;

        // Create test entity with circular motion
        const config = getConfig();
        const testEntity = new Entity();
        testEntity.boundingBox = { width: config.squareSize, height: config.squareSize };

        // Set initial position
        const centerX = 0;
        const centerY = 0;
        testEntity.transform.setPosition(
            centerX + Math.cos(0) * config.radius,
            centerY + Math.sin(0) * config.radius,
            0
        );

        // Store animation state with the entity
        testEntity.animationState = {
            angle: 0,
            speed: config.initialAngularSpeed,
            centerX,
            centerY,
            radius: config.radius
        };

        // Add update method to the entity
        testEntity.update = (deltaTime) => {
            const state = testEntity.animationState;
            state.speed += config.angularAcceleration * deltaTime;
            state.angle += state.speed * deltaTime;

            // Update position based on circular motion
            testEntity.transform.setPosition(
                state.centerX + Math.cos(state.angle) * state.radius,
                state.centerY + Math.sin(state.angle) * state.radius,
                0
            );
        };

        // Add entity to game layer
        gameLayer.addEntity(testEntity);
        state.testEntity = testEntity;  // Store reference in state

        // Initial camera setup
        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') {  // Don't include root layer in handlers
                layers.push(current);
            }
            current = current.child;
        }
        return layers;
    }

    draw(ctx) {
        // Start drawing from root layer
        this.rootLayer.draw(ctx, this.camera);
    }

    update(deltaTime) {
        // Update all entities in the game layer
        const gameLayer = this.getLayer(LayerType.GAME);
        gameLayer?.entities.forEach(entity => {
            if (entity.update) {
                entity.update(deltaTime);
            }
        });

        // Update debug layer's FPS counter
        const debugLayer = this.getLayer(LayerType.DEBUG);
        if (debugLayer) {
            debugLayer.entities.forEach(entity => {
                if (entity.constructor.name === 'FPSCounter' && entity.update) {
                    entity.update(
                        // We store fps in state.fps
                        window.state?.fps ?? 0,
                        // Pass camera velocity
                        this.camera?.currentVelocity ?? { x: 0, y: 0 }
                    );
                }
            });
        }
    }
}