<html lang="ru">
<head>
    <meta charset="UTF-8">
    <title>3D Червяк</title>
    <style>
        body { margin: 0; overflow: hidden; }
        #menu {
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background: rgba(255, 255, 255, 0.8);
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            z-index: 10;
        }
        #menu h1 { margin-bottom: 20px; }
        #menu label { margin-bottom: 10px; }
        #menu button { padding: 10px 20px; font-size: 16px; }
        #score {
            position: absolute;
            top: 10px;
            left: 10px;
            color: black;
            font-size: 24px;
            z-index: 5;
        }
    </style>
</head>
<body>
    <div id="menu">
        <h1>Выберите настройки червяка</h1>
        <label>
            Выберите тип червяка:
            <select id="snakeType">
                <option value="default">Обычный червяк</option>
                <option value="textured">Червяк с текстурами</option>
            </select>
        </label>
        <div id="colorPicker">
            <label>
                Выберите цвет червяка:
                <input type="color" id="snakeColor" value="#FFFF00">
            </label>
        </div>
        <div id="textureUploader" style="display: none;">
            <label>
                Загрузите изображение для текстуры:
                <input type="file" id="textureFile" accept="image/png, image/jpeg">
            </label>
        </div>
        <button id="startButton">Начать игру</button>
    </div>

    <div id="score">Счет: 0</div>

    <!-- Подключаем Three.js из официального CDN -->
    <script src="https://unpkg.com/three@0.152.0/build/three.min.js"></script>

    <script>
        var scene, camera, renderer;
        var wormSegments = [], positions = [];
        var direction = new THREE.Vector3(0, 0, -1);
        var speed = 0.1;
        var food;
        var keyStates = {};
        var numSegments = 2; // Червяк начинает с двух сегментов
        var segmentSpacing = 5;
        var score = 0;
        var snake, textureGlobal, snakeColorGlobal = "#FFFF00", snakeTypeGlobal = "default";
        var segmentGeometry, segmentMaterial;

        document.getElementById('snakeType').addEventListener('change', function() {
            snakeTypeGlobal = this.value;
            document.getElementById('textureUploader').style.display = snakeTypeGlobal === 'textured' ? 'block' : 'none';
            document.getElementById('colorPicker').style.display = snakeTypeGlobal === 'default' ? 'block' : 'none';
        });

        document.getElementById('startButton').addEventListener('click', function() {
            snakeColorGlobal = document.getElementById('snakeColor').value;
            var textureFileInput = document.getElementById('textureFile');
            var textureFile = textureFileInput.files.length > 0 ? textureFileInput.files[0] : null;
            document.getElementById('menu').style.display = 'none';
            init(snakeTypeGlobal, snakeColorGlobal, textureFile);
        });

        function init(snakeType, snakeColor, textureFile) {
            scene = new THREE.Scene();
            scene.background = new THREE.Color(0x87CEEB);

            camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
            camera.position.set(0, 5, 20);

            renderer = new THREE.WebGLRenderer({ antialias: true });
            renderer.setSize(window.innerWidth, window.innerHeight);
            document.body.appendChild(renderer.domElement);

            var light = new THREE.AmbientLight(0xffffff, 0.5);
            scene.add(light);

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

            // Добавляем точечный источник света для улучшения освещения
            var pointLight = new THREE.PointLight(0xffffff, 0.5);
            pointLight.position.set(0, 10, 0);
            scene.add(pointLight);

            var groundGeometry = new THREE.PlaneGeometry(100, 100);
            var groundMaterial = new THREE.MeshStandardMaterial({ color: 0x008000 });
            var ground = new THREE.Mesh(groundGeometry, groundMaterial);
            ground.rotation.x = -Math.PI / 2;
            scene.add(ground);

            if (snakeType === 'textured' && textureFile) {
                var reader = new FileReader();
                reader.onload = function(event) {
                    var textureLoader = new THREE.TextureLoader();
                    textureLoader.load(event.target.result, function(texture) {
                        textureGlobal = texture;
                        createSnake();
                        createFood();
                        animate();
                    });
                };
                reader.readAsDataURL(textureFile);
            } else {
                createSnake();
                createFood();
                animate();
            }

            document.addEventListener('keydown', onKeyDown);
            document.addEventListener('keyup', onKeyUp);
            window.addEventListener('resize', onWindowResize);
        }

        function createSnake() {
            wormSegments = [];
            positions = [];

            // Используем сферу для создания сегментов червяка
            segmentGeometry = new THREE.SphereGeometry(0.5, 32, 32);

            if (snakeTypeGlobal === 'textured' && textureGlobal) {
                segmentMaterial = new THREE.MeshStandardMaterial({ map: textureGlobal });
            } else {
                if (snakeColorGlobal && typeof snakeColorGlobal === 'string') {
                    segmentMaterial = new THREE.MeshStandardMaterial({ color: new THREE.Color(snakeColorGlobal) });
                } else {
                    segmentMaterial = new THREE.MeshStandardMaterial({ color: 0xFFFF00 });
                }
            }

            snake = { position: new THREE.Vector3(0, 0.5, 0) };
            positions.push(snake.position.clone());

            for (var i = 0; i < numSegments; i++) {
                var segment = new THREE.Mesh(segmentGeometry, segmentMaterial);
                segment.position.copy(snake.position);

                wormSegments.push(segment);
                scene.add(segment);
            }
        }

        function createFood() {
            var geometry = new THREE.SphereGeometry(0.5, 16, 16);
            var material = new THREE.MeshStandardMaterial({ color: 0xff0000 });
            food = new THREE.Mesh(geometry, material);
            food.position.set(
                Math.floor(Math.random() * 20 - 10),
                0.5, // Устанавливаем по Y на 0.5
                Math.floor(Math.random() * 20 - 10)
            );
            scene.add(food);
        }

        function onKeyDown(event) { keyStates[event.code] = true; }
        function onKeyUp(event) { keyStates[event.code] = false; }

        function updateDirection() {
            var turnSpeed = 0.05;
            if (keyStates['KeyA']) direction.applyAxisAngle(new THREE.Vector3(0, 1, 0), turnSpeed);
            if (keyStates['KeyD']) direction.applyAxisAngle(new THREE.Vector3(0, 1, 0), -turnSpeed);
            direction.normalize();
        }

        function animate() {
            requestAnimationFrame(animate);

            updateDirection();

            var currentSpeed = speed;

            var newPosition = snake.position.clone().add(direction.clone().multiplyScalar(currentSpeed));
            newPosition.y = 0.5; // Устанавливаем по Y на 0.5
            snake.position.copy(newPosition);

            // Добавляем новую позицию головы в начало массива
            positions.unshift(snake.position.clone());
            if (positions.length > (numSegments + 1) * segmentSpacing) {
                positions.pop();
            }

            // Обновляем позиции сегментов червяка
            for (var i = 0; i < wormSegments.length; i++) {
                var index = (i + 1) * segmentSpacing;
                if (positions[index]) {
                    wormSegments[i].position.copy(positions[index]);
                }
            }

            // Проверка на столкновение с едой
            if (snake.position.distanceTo(food.position) < 1) {
                scene.remove(food);
                createFood();

                // Увеличиваем длину червяка на 1 сегмент
                var segment = new THREE.Mesh(segmentGeometry, segmentMaterial);

                // Устанавливаем позицию нового сегмента в последней известной позиции
                segment.position.copy(wormSegments[wormSegments.length - 1].position);

                wormSegments.push(segment);
                scene.add(segment);

                numSegments += 1;
                score += 10;
                document.getElementById('score').textContent = 'Счет: ' + score;
            }

            var cameraOffset = new THREE.Vector3(0, 5, 10).applyQuaternion(new THREE.Quaternion().setFromAxisAngle(new THREE.Vector3(0, 1, 0), direction.angleTo(new THREE.Vector3(0, 0, -1))));
            camera.position.copy(snake.position.clone().add(cameraOffset));
            camera.lookAt(snake.position);

            renderer.render(scene, camera);
        }

        function onWindowResize() {
            camera.aspect = window.innerWidth / window.innerHeight;
            camera.updateProjectionMatrix();
            renderer.setSize(window.innerWidth, window.innerHeight);
        }
    </script>
</body>
</html>
сделай камеру фиксированой чтоб она не двигалась а просто следовала за червяком