fix my code to correctly render cube:

const canvas = document.getElementById('scene');
const ctx = canvas.getContext('2d');

class Scene {
    constructor() {
        this.objects = []
    }
    
    add(object) {
        this.objects.push(object)
    }

    remove(object) {
        this.objects = this.objects.filter(obj => obj !== object);
    }
    
    draw(camera) {
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        this.objects.forEach(object => {
            object.draw(ctx, camera);
        });
    }
}

class Camera {
    constructor(x, y, z) {
        this.x = x; // Położenie kamery w osi X
        this.y = y; // Położenie kamery w osi Y
        this.z = z; // Położenie kamery w osi Z
    }

    updatePosition(dx, dy, dz) {
        this.x += dx;
        this.y += dy;
        this.z += dz;
    }
}

class BasicMaterial {
    constructor(color) {
        this.color = color;
    }
}

class Cube {
    constructor(x, y, z, width, height, depth, material) {
        this.x = x;
        this.y = y;
        this.z = z;
        this.width = width;
        this.height = height;
        this.depth = depth;
        this.material = material; // Przechowujemy materiał
    }

    get_vertices() {
        const { x, y, z, width, height, depth } = this;
        return [
            [x, y, z],                      // 0
            [x + width, y, z],              // 1
            [x + width, y + height, z],     // 2
            [x, y + height, z],              // 3
            [x, y, z + depth],               // 4
            [x + width, y, z + depth],       // 5
            [x + width, y + height, z + depth], // 6
            [x, y + height, z + depth]       // 7
        ];
    }

    project(vertex, camera) {
        const fov = 256; // pole widzenia
        const distance = 4; // odległość kamery
        const scale = fov / (distance + vertex[2] - camera.z); // Zmiana na z, aby uwzględnić położenie kamery
        const x = (vertex[0] - camera.x) * scale + canvas.width / 2;
        const y = -(vertex[1] - camera.y) * scale + canvas.height / 2; // Odwrócenie osi Y
        return [x, y];
    }

    draw(ctx, camera) {
        const vertices = this.get_vertices();
        const projected = vertices.map(vertex => this.project(vertex, camera));
        
        ctx.beginPath();
        
        // Rysowanie przednich krawędzi
        for (let i = 0; i < 4; i++) {
            const [x, y] = projected[i];
            ctx.moveTo(x, y);
            const [nextX, nextY] = projected[(i + 1) % 4];
            ctx.lineTo(nextX, nextY);
        }
        
        // Rysowanie tylnych krawędzi
        for (let i = 4; i < 8; i++) {
            const [x, y] = projected[i];
            ctx.moveTo(x, y);
            const [nextX, nextY] = projected[(i + 1) % 4 + 4]; // Użycie indeksu z przesunięciem o 4
            ctx.lineTo(nextX, nextY);
        }
        
        // Łączenie krawędzi przednich i tylnych
        for (let i = 0; i < 4; i++) {
            ctx.moveTo(projected[i][0], projected[i][1]);
            ctx.lineTo(projected[i + 4][0], projected[i + 4][1]);
        }

        // Kolorowanie ścian
        const faces = [
            [0, 1, 2, 3], // Front
            [4, 5, 6, 7], // Back
            [0, 1, 5, 4], // Right
            [2, 3, 7, 6], // Left
            [1, 2, 6, 5], // Top
            [0, 3, 7, 4]  // Bottom
        ];

        faces.forEach((face, index) => {
            ctx.beginPath();
            face.forEach(vertexIndex => {
                const [x, y] = projected[vertexIndex];
                ctx.lineTo(x, y);
            });
            ctx.closePath();
            ctx.fillStyle = this.material.color; // Ustaw kolor z materiału
            ctx.fill();
            ctx.strokeStyle = 'black';
            ctx.stroke();
        });
    }
}

class Square {
    constructor(x, y, width, height, material) {
        this.x = x;
        this.y = y;
        this.width = width;
        this.height = height;
        this.material = material; // Przechowujemy materiał
    }

    project(camera) {
        const scale = 256 / (256 + (this.y - camera.y)); // Prosta projekcja 2D
        const x = (this.x - camera.x) * scale + canvas.width / 2;
        const y = -(this.y - camera.y) * scale + canvas.height / 2;
        return [x, y];
    }

    draw(ctx, camera) {
        const [x, y] = this.project(camera);
        ctx.fillStyle = this.material.color; // Ustaw kolor z materiału
        ctx.fillRect(x, y, this.width, this.height);
    }
}

const scene = new Scene();
const camera = new Camera(0, 0, 200); // Ustawienie początkowej pozycji kamery
const cubeMaterial = new BasicMaterial('lightblue'); // Ustawienie koloru materiału dla sześcianu
const cube = new Cube(50, 50, 50, 50, 50, 50, cubeMaterial); // Przypisanie materiału do sześcianu
const squareMaterial = new BasicMaterial('green'); // Ustawienie koloru materiału dla kwadratu
const square = new Square(100, 100, 30, 30, squareMaterial); // Tworzenie nowego kwadratu

document.addEventListener("keypress", (e) => {
    if (e.key == 'w') {
        camera.updatePosition(0, 0, -1); // Przesuwanie kamery do przodu
    }
    if (e.key == 's') {
        camera.updatePosition(0, 0, 1); // Przesuwanie kamery do tyłu
    }
    if (e.key == 'd') {
        camera.updatePosition(1, 0, 0); // Przesuwanie kamery w prawo
    }
    if (e.key == 'a') {
        camera.updatePosition(-1, 0, 0); // Przesuwanie kamery w lewo
    }
    if (e.key == 'r') {
        scene.remove(cube);
    }
});

scene.add(cube);
scene.add(square); // Dodanie kwadratu do sceny

function animate() {
    scene.draw(camera);
    requestAnimationFrame(animate);
}

animate();