The code works every once in a while and shows a white screen

I’m desperate to make this code work but it only shows a white screen the buttons it works every once in a while do y’all have any fix?
3D Racing Game (website)

3D Racing Game body { margin: 0; overflow: hidden; -webkit-touch-callout: none; -webkit-user-select: none; -khtml-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; } #leftArrow, #rightArrow, #brakeBtn, #accelerateBtn, #settingsBtn, #qualitySlider { position: absolute; bottom: 20px; width: 100px; height: 100px; background-color: rgba(0, 0, 0, 0.5); color: white; font-size: 24px; display: flex; align-items: center; justify-content: center; cursor: pointer; } #leftArrow { left: 20px; transform: rotate(-90deg); } #rightArrow { left: 140px; transform: rotate(90deg); } #brakeBtn { right: 20px; } #accelerateBtn { right: 140px; } #settingsBtn { right: 260px; } #qualitySlider { right: 20px; bottom: 140px; display: none; flex-direction: column; } #gameOver { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); font-size: 48px; color: red; display: none; } #shopButton { position: absolute; top: 70%; left: 50%; transform: translate(-50%, -50%); font-size: 24px; color: white; background-color: blue; padding: 10px 20px; cursor: pointer; display: none; } #coinCounter { position: absolute; top: 20px; left: 20px; font-size: 24px; color: white; background-color: rgba(0, 0, 0, 0.5); padding: 10px; } #shopScreen { position: absolute; width: 100%; height: 100%; background-color: white; display: none; flex-direction: column; align-items: center; justify-content: center; } #backButton { position: absolute; top: 20px; left: 20px; font-size: 24px; color: white; background-color: red; padding: 10px 20px; cursor: pointer; } #carModelContainer { width: 400px; height: 300px; } #rightArrowShop, #leftArrowShop { position: absolute; top: 50%; font-size: 24px; cursor: pointer; } #rightArrowShop { right: -40px; } #leftArrowShop { left: -40px; } #carCapabilities { position: absolute; top: 200px; right: 20px; font-size: 24px; color: black; } #purchaseButton, #equipButton { position: absolute; top: 320px; font-size: 24px; color: white; background-color: green; padding: 10px 20px; cursor: pointer; } #equipButton { background-color: orange; display: none; } #speedometer { position: absolute; top: 20px; left: 50%; transform: translateX(-50%); font-size: 24px; color: white; background-color: rgba(0, 0, 0, 0.5); padding: 10px; }
Brake
Accel
Settings
Quality:
Game Over
Shop
Coins: 0
Back
Acceleration: —|———
Top Speed: 450 km/h
Purchase for 30 Coins
Equip
Speed: 0 km/h
let scene, camera, renderer; let player, opponents = []; let coins = []; let moveLeft = false, moveRight = false; let brake = false, accelerate = false; let currentSpeed = 0; const minSpeed = 0; const maxSpeed = 450 / 36; // Max speed converted to Three.js units let accelerationRate = 0.5; const brakeRate = 0.5; let opponentSpawnInterval = 60; let coinSpawnInterval = 180; // Add coins every 3 seconds let frameCount = 0; let gameOver = false; const roadLines = []; let clock; let lastTime = performance.now(); let quality = 'high'; const roadWidth = 20;
    let coinsCollected = 0;
    let carColor = 'red'; // Default car color
    let carCapabilities = {
        acceleration: 0.5,
        topSpeed: 450
    };
    let gameState = {
        coins: 0,
        purchasedCars: [],
        equippedCar: 'red'
    };

    init();
    animate();

    function init() {
        loadGameState();
        scene = new THREE.Scene();
        camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
        camera.position.set(0, 5, 12);
        renderer = new THREE.WebGLRenderer({ antialias: true });
        updateQuality();
        renderer.setSize(window.innerWidth, window.innerHeight);
        renderer.setPixelRatio(window.devicePixelRatio);
        document.body.appendChild(renderer.domElement);
        clock = new THREE.Clock();

        createPlayer(carColor);

        const roadGeometry = new THREE.PlaneGeometry(roadWidth, 200);
        const roadMaterial = new THREE.MeshStandardMaterial({ color: 0x808080 });
        const road = new THREE.Mesh(roadGeometry, roadMaterial);
        road.rotation.x = -Math.PI / 2;
        road.position.y = -0.5;
        scene.add(road);

        const grassGeometry = new THREE.PlaneGeometry(60, 200);
        const grassMaterial = new THREE.MeshStandardMaterial({ color: 0x00ff00 });
        const grassLeft = new THREE.Mesh(grassGeometry, grassMaterial);
        grassLeft.rotation.x = -Math.PI / 2;
        grassLeft.position.set(-40, -0.51, 0);
        scene.add(grassLeft);

        const grassRight = new THREE.Mesh(grassGeometry, grassMaterial);
        grassRight.rotation.x = -Math.PI / 2;
        grassRight.position.set(40, -0.51, 0);
        scene.add(grassRight);

        const treeGeometry = new THREE.CylinderGeometry(0.5, 0.5, 3, 8);
        const treeMaterial = new THREE.MeshStandardMaterial({ color: 0x8b4513 });
        const foliageGeometry = new THREE.SphereGeometry(2, 8, 8);
        const foliageMaterial = new THREE.MeshStandardMaterial({ color: 0x228b22 });

        for (let i = -50; i < 50; i += 20) {
            const tree = new THREE.Group();
            const trunk = new THREE.Mesh(treeGeometry, treeMaterial);
            const foliage = new THREE.Mesh(foliageGeometry, foliageMaterial);
            foliage.position.y = 2.5;
            tree.add(trunk);
            tree.add(foliage);
            tree.position.set(i, 1.5, -20);
            scene.add(tree);
        }

        const wallGeometry = new THREE.PlaneGeometry(200, 10);
        const wallMaterial = new THREE.MeshBasicMaterial({ color: 0xff0000, side: THREE.DoubleSide, visible: false });

        const wallLeft = new THREE.Mesh(wallGeometry, wallMaterial);
        wallLeft.position.set(-roadWidth / 2, 5, 0); // Positioned right at the edge of the road
        wallLeft.rotation.y = Math.PI / 2;
        scene.add(wallLeft);

        const wallRight = new THREE.Mesh(wallGeometry, wallMaterial);
        wallRight.position.set(roadWidth / 2, 5, 0); // Positioned right at the edge of the road
        wallRight.rotation.y = Math.PI / 2;
        scene.add(wallRight);

        const sunGeometry = new THREE.SphereGeometry(5, 32, 32);
        const sunMaterial = new THREE.MeshBasicMaterial({ color: 0xffff00 });
        const sun = new THREE.Mesh(sunGeometry, sunMaterial);
        sun.position.set(0, 50, -100);
        scene.add(sun);

        const skyGeometry = new THREE.SphereGeometry(500, 32, 32);
        const skyMaterial = new THREE.MeshBasicMaterial({ color: 0x87ceeb, side: THREE.BackSide });
        const sky = new THREE.Mesh(skyGeometry, skyMaterial);
        scene.add(sky);

        const ambientLight = new THREE.AmbientLight(0xffffff, 0.5);
        scene.add(ambientLight);

        const directionalLight = new THREE.DirectionalLight(0xffffff, 1);
        directionalLight.position.set(0, 10, 10);
        scene.add(directionalLight);

        document.getElementById('leftArrow').addEventListener('touchstart', () => moveLeft = true);
        document.getElementById('leftArrow').addEventListener('touchend', () => moveLeft = false);
        document.getElementById('rightArrow').addEventListener('touchstart', () => moveRight = true);
        document.getElementById('rightArrow').addEventListener('touchend', () => moveRight = false);
        document.getElementById('brakeBtn').addEventListener('touchstart', () => brake = true);
        document.getElementById('brakeBtn').addEventListener('touchend', () => brake = false);
        document.getElementById('accelerateBtn').addEventListener('touchstart', () => accelerate = true);
        document.getElementById('accelerateBtn').addEventListener('touchend', () => accelerate = false);
        document.getElementById('settingsBtn').addEventListener('click', () => {
            document.getElementById('qualitySlider').style.display = 
                document.getElementById('qualitySlider').style.display === 'none' ? 'flex' : 'none';
        });

        document.getElementById('shopButton').addEventListener('click', showShopScreen);
        document.getElementById('backButton').addEventListener('click', hideShopScreen);
        document.getElementById('rightArrowShop').addEventListener('click', () => changeCarColor('blue'));
        document.getElementById('leftArrowShop').addEventListener('click', () => changeCarColor('red'));
        document.getElementById('purchaseButton').addEventListener('click', purchaseCar);
        document.getElementById('equipButton').addEventListener('click', equipCar);

        document.addEventListener('dblclick', (e) => e.preventDefault());
    }

    function createPlayer(color) {
        if (player) scene.remove(player);

        player = createCarMesh(color);
        player.position.y = 0.5;
        scene.add(player);
    }

    function createShopCar(color) {
        const carModelContainer = document.getElementById('carModelContainer');
        carModelContainer.innerHTML = '';

        const shopScene = new THREE.Scene();
        const shopCamera = new THREE.PerspectiveCamera(75, carModelContainer.clientWidth / carModelContainer.clientHeight, 0.1, 1000);
        shopCamera.position.set(0, 5, 10);

        const shopRenderer = new THREE.WebGLRenderer({ antialias: true });
        shopRenderer.setSize(carModelContainer.clientWidth, carModelContainer.clientHeight);
        carModelContainer.appendChild(shopRenderer.domElement);

        const shopCar = createCarMesh(color);
        shopCar.position.set(0, 0.5, 0);
        shopScene.add(shopCar);

        const ambientLight = new THREE.AmbientLight(0xffffff, 0.5);
        shopScene.add(ambientLight);

        const directionalLight = new THREE.DirectionalLight(0xffffff, 1);
        directionalLight.position.set(0, 10, 10);
        shopScene.add(directionalLight);

        function animateShop() {
            requestAnimationFrame(animateShop);
            shopCar.rotation.y += 0.01;
            shopRenderer.render(shopScene, shopCamera);
        }
        animateShop();
    }

    function createCarMesh(color) {
        const playerMaterial = new THREE.MeshStandardMaterial({ color });

        const carBody = new THREE.BoxGeometry(1.2, 0.6, 3);
        const frontWing = new THREE.BoxGeometry(1.8, 0.12, 0.6);
        const rearWing = new THREE.BoxGeometry(1.8, 0.12, 0.6);
        const rearSpoiler = new THREE.BoxGeometry(0.12, 0.6, 0.6);
        const frontWheel = new THREE.CylinderGeometry(0.36, 0.36, 0.24, 32);
        const rearWheel = new THREE.CylinderGeometry(0.36, 0.36, 0.24, 32);

        const bodyMesh = new THREE.Mesh(carBody, playerMaterial);
        const frontWingMesh = new THREE.Mesh(frontWing, playerMaterial);
        const rearWingMesh = new THREE.Mesh(rearWing, playerMaterial);
        const rearSpoilerMesh = new THREE.Mesh(rearSpoiler, playerMaterial);
        const frontWheelMeshL = new THREE.Mesh(frontWheel, playerMaterial);
        const frontWheelMeshR = new THREE.Mesh(frontWheel, playerMaterial);
        const rearWheelMeshL = new THREE.Mesh(rearWheel, playerMaterial);
        const rearWheelMeshR = new THREE.Mesh(rearWheel, playerMaterial);

        frontWingMesh.position.set(0, -0.3, 1.2);
        rearWingMesh.position.set(0, -0.3, -1.2);
        rearSpoilerMesh.position.set(0, 0.6, -1.2);
        frontWheelMeshL.position.set(-0.84, -0.3, 1.44);
        frontWheelMeshR.position.set(0.84, -0.3, 1.44);
        rearWheelMeshL.position.set(-0.84, -0.3, -1.44);
        rearWheelMeshR.position.set(0.84, -0.3, -1.44);

        frontWheelMeshL.rotation.z = Math.PI / 2;
        frontWheelMeshR.rotation.z = Math.PI / 2;
        rearWheelMeshL.rotation.z = Math.PI / 2;
        rearWheelMeshR.rotation.z = Math.PI / 2;

        const car = new THREE.Group();
        car.add(bodyMesh);
        car.add(frontWingMesh);
        car.add(rearWingMesh);
        car.add(rearSpoilerMesh);
        car.add(frontWheelMeshL);
        car.add(frontWheelMeshR);
        car.add(rearWheelMeshL);
        car.add(rearWheelMeshR);

        return car;
    }

    function showShopScreen() {
        document.getElementById('shopScreen').style.display = 'flex';
        updateShopUI();
        createShopCar(carColor); // Ensure the correct car is displayed
    }

    function hideShopScreen() {
        document.getElementById('shopScreen').style.display = 'none';
    }

    function changeCarColor(color) {
        carColor = color;
        createShopCar(color);

        if (color === 'blue') {
            document.getElementById('carCapabilities').style.display = 'block';
            document.getElementById('acceleration').innerText = 'Acceleration: ——|———';
            document.getElementById('topSpeed').innerText = 'Top Speed: 470 km/h';
            if (gameState.purchasedCars.includes('blue')) {
                document.getElementById('purchaseButton').style.display = 'none';
                document.getElementById('equipButton').style.display = 'block';
            } else {
                document.getElementById('purchaseButton').style.display = 'block';
                document.getElementById('equipButton').style.display = 'none';
            }
        } else {
            document.getElementById('carCapabilities').style.display = 'none';
            document.getElementById('purchaseButton').style.display = 'none';
            document.getElementById('equipButton').style.display = 'block';
        }

        updateShopUI();
    }

    function purchaseCar() {
        if (coinsCollected < 30) return;
        if (!gameState.purchasedCars.includes('blue')) {
            gameState.purchasedCars.push('blue');
            coinsCollected -= 30;
            document.getElementById('coinCounter').innerText = `Coins: ${coinsCollected}`;
            document.getElementById('purchaseButton').innerText = 'Purchased successfully';
            setTimeout(() => {
                document.getElementById('purchaseButton').style.display = 'none';
                document.getElementById('equipButton').style.display = 'block';
                document.getElementById('purchaseButton').innerText = 'Purchase for 30 Coins';
            }, 3000);
            saveGameState();
        }
    }

    function equipCar() {
        gameState.equippedCar = carColor;
        createPlayer(carColor);
        if (carColor === 'blue') {
            accelerationRate = 0.7;
            maxSpeed = 470 / 36;
        } else {
            accelerationRate = 0.5;
            maxSpeed = 450 / 36;
        }
        saveGameState();
        updateShopUI();
    }

    function updateShopUI() {
        if (carColor === 'red') {
            document.getElementById('purchaseButton').style.display = 'none';
            document.getElementById('equipButton').style.display = 'block';
            document.getElementById('equipButton').innerText = gameState.equippedCar === 'red' ? 'Equipped' : 'Equip';
        } else if (carColor === 'blue') {
            document.getElementById('equipButton').innerText = gameState.equippedCar === 'blue' ? 'Equipped' : 'Equip';
        }
    }

    function spawnOpponent() {
        if (opponents.length > 5) return;

        const opponentMaterial = new THREE.MeshStandardMaterial({ color: Math.random() * 0xffffff });

        const carBody = new THREE.BoxGeometry(1.2, 0.6, 3);
        const frontWing = new THREE.BoxGeometry(1.8, 0.12, 0.6);
        const rearWing = new THREE.BoxGeometry(1.8, 0.12, 0.6);
        const rearSpoiler = new THREE.BoxGeometry(0.12, 0.6, 0.6);
        const frontWheel = new THREE.CylinderGeometry(0.36, 0.36, 0.24, 32);
        const rearWheel = new THREE.CylinderGeometry(0.36, 0.36, 0.24, 32);

        const bodyMesh = new THREE.Mesh(carBody, opponentMaterial);
        const frontWingMesh = new THREE.Mesh(frontWing, opponentMaterial);
        const rearWingMesh = new THREE.Mesh(rearWing, opponentMaterial);
        const rearSpoilerMesh = new THREE.Mesh(rearSpoiler, opponentMaterial);
        const frontWheelMeshL = new THREE.Mesh(frontWheel, opponentMaterial);
        const frontWheelMeshR = new THREE.Mesh(frontWheel, opponentMaterial);
        const rearWheelMeshL = new THREE.Mesh(rearWheel, opponentMaterial);
        const rearWheelMeshR = new THREE.Mesh(rearWheel, opponentMaterial);

        frontWingMesh.position.set(0, -0.3, 1.2);
        rearWingMesh.position.set(0, -0.3, -1.2);
        rearSpoilerMesh.position.set(0, 0.6, -1.2);
        frontWheelMeshL.position.set(-0.84, -0.3, 1.44);
        frontWheelMeshR.position.set(0.84, -0.3, 1.44);
        rearWheelMeshL.position.set(-0.84, -0.3, -1.44);
        rearWheelMeshR.position.set(0.84, -0.3, -1.44);

        frontWheelMeshL.rotation.z = Math.PI / 2;
        frontWheelMeshR.rotation.z = Math.PI / 2;
        rearWheelMeshL.rotation.z = Math.PI / 2;
        rearWheelMeshR.rotation.z = Math.PI / 2;

        const opponent = new THREE.Group();
        opponent.add(bodyMesh);
        opponent.add(frontWingMesh);
        opponent.add(rearWingMesh);
        opponent.add(rearSpoilerMesh);
        opponent.add(frontWheelMeshL);
        opponent.add(frontWheelMeshR);
        opponent.add(rearWheelMeshL);
        opponent.add(rearWheelMeshR);

        const spawnX = Math.floor(Math.random() * 10) * 2 - 10;
        opponent.position.set(spawnX, 0.5, -50);
        opponents.push(opponent);
        scene.add(opponent);
    }

    function spawnCoin() {
        if (coins.length > 5) return;

        const coinGeometry = new THREE.CylinderGeometry(0.2, 0.2, 0.05, 32);
        const coinMaterial = new THREE.MeshStandardMaterial({ color: 0xffff00 });
        const coin = new THREE.Mesh(coinGeometry, coinMaterial);
        coin.rotation.x = Math.PI / 2;
        const spawnX = Math.floor(Math.random() * roadWidth) - roadWidth / 2;
        coin.position.set(spawnX, 0.25, -50);
        coins.push(coin);
        scene.add(coin);
    }

    function updateQuality() {
        const qualityLevel = document.getElementById('quality').value;
        if (qualityLevel === 'low') {
            renderer.setPixelRatio(0.5);
            renderer.setSize(window.innerWidth / 2, window.innerHeight / 2);
        } else if (qualityLevel === 'medium') {
            renderer.setPixelRatio(1);
            renderer.setSize(window.innerWidth, window.innerHeight);
        } else if (qualityLevel === 'high') {
            renderer.setPixelRatio(1);
            renderer.setSize(window.innerWidth, window.innerHeight);
            renderer.setQuality('high');
        }
    }

    function animate() {
        if (gameOver) return;

        requestAnimationFrame(animate);

        const now = performance.now();
        const delta = (now - lastTime) / 1000;
        lastTime = now;

        if (moveLeft && player.position.x > -roadWidth / 2 + 0.5) player.position.x -= currentSpeed * delta;
        if (moveRight && player.position.x < roadWidth / 2 - 0.5) player.position.x += currentSpeed * delta;

        if (accelerate) {
            currentSpeed += accelerationRate * delta;
            currentSpeed = Math.min(currentSpeed, maxSpeed);
        } else if (brake) {
            currentSpeed -= brakeRate * delta;
            currentSpeed = Math.max(currentSpeed, minSpeed);
        }

        document.getElementById('speedometer').textContent = `Speed: ${Math.round(currentSpeed * 36)} km/h`;

        frameCount++;
        if (frameCount % opponentSpawnInterval === 0) {
            spawnOpponent();
        }

        if (frameCount % coinSpawnInterval === 0) {
            spawnCoin();
        }

        for (let i = 0; i < opponents.length; i++) {
            opponents[i].position.z += currentSpeed * delta;
            if (opponents[i].position.z > 10) {
                scene.remove(opponents[i]);
                opponents.splice(i, 1);
                i--;
            }

            if (player.position.distanceTo(opponents[i].position) < 1.5) {
                document.getElementById('gameOver').style.display = 'block';
                document.getElementById('shopButton').style.display = 'block';
                gameOver = true;
                return;
            }
        }

        for (let i = 0; i < coins.length; i++) {
            coins[i].position.z += currentSpeed * delta;
            if (coins[i].position.z > 10) {
                scene.remove(coins[i]);
                coins.splice(i, 1);
                i--;
            }

            if (player.position.distanceTo(coins[i].position) < 1) {
                coinsCollected++;
                document.getElementById('coinCounter').innerText = `Coins: ${coinsCollected}`;
                scene.remove(coins[i]);
                coins.splice(i, 1);
                i--;
                saveGameState();
            }
        }

        roadLines.forEach(line => {
            line.position.z += currentSpeed * delta * 2;
            if (line.position.z > 10) {
                line.position.z = -90;
            }
        });

        scene.children.forEach(child => {
            if (child.type === 'Group' && child.children[0].geometry.type === 'CylinderGeometry') {
                child.position.z += currentSpeed * delta;
                if (child.position.z > 10) {
                    child.position.z = -50;
                }
            }
        });

        camera.position.x = player.position.x;
        camera.position.z = player.position.z + 10;
        camera.lookAt(player.position);

        renderer.render(scene, camera);
    }

    function loadGameState() {
        const savedState = localStorage.getItem('gameState');
        if (savedState) {
            gameState = JSON.parse(savedState);
            coinsCollected = gameState.coins;
            document.getElementById('coinCounter').innerText = `Coins: ${coinsCollected}`;
            carColor = gameState.equippedCar;
            createPlayer(carColor);
            if (carColor === 'blue') {
                accelerationRate = 0.7;
                maxSpeed = 470 / 36;
            } else {
                accelerationRate = 0.5;
                maxSpeed = 450 / 36;
            }
        }
    }

    function saveGameState() {
        gameState.coins = coinsCollected;
        localStorage.setItem('gameState', JSON.stringify(gameState));
    }
</script>

First of all please make the formatting of the code better so that other people can understand it easily.

Secondly the code is working fine for me even after spamming restart several times.

1 Like

Update: the problem is website data I need to delete the website data for it to work but when I delete it all the saved progress goes away so anyone has any fix for local storage!?

If you want to delete the website’s local storage just use localStorage.clear() this will remove everything thats inside the storage.

Reference: Window: localStorage property - Web APIs | MDN

You can clear the local storage before the canvas loads or by using a button, that’s up to you.