<!DOCTYPE html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Изменение времени по голосу</title>
    <style>
        body {
            margin: 0;
            overflow: hidden;
            font-family: Arial, sans-serif;
        }
        #game-container {
            position: relative;
            width: 100vw;
            height: 100vh;
            transition: background-color 0.5s ease;
        }
        #sky {
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 70%;
            transition: background-color 0.5s ease;
        }
        #ground {
            position: absolute;
            bottom: 0;
            left: 0;
            width: 100%;
            height: 30%;
            background-color: #4a7c59;
            transition: background-color 0.5s ease;
        }
        #sun-moon {
            position: absolute;
            width: 80px;
            height: 80px;
            border-radius: 50%;
            transition: all 0.5s ease;
        }
        #buildings {
            position: absolute;
            bottom: 30%;
            left: 0;
            width: 100%;
            height: 20%;
        }
        .building {
            position: absolute;
            bottom: 0;
            background-color: #555;
            transition: background-color 0.5s ease;
        }
        .window {
            position: absolute;
            background-color: #333;
            transition: background-color 0.5s ease;
        }
        #controls {
            position: absolute;
            top: 20px;
            left: 20px;
            background-color: rgba(255, 255, 255, 0.8);
            padding: 15px;
            border-radius: 10px;
            z-index: 100;
        }
        #time-display {
            font-size: 24px;
            font-weight: bold;
            margin-bottom: 10px;
        }
        #pitch-display, #volume-display {
            font-size: 16px;
            margin-bottom: 5px;
        }
        button {
            padding: 10px 15px;
            margin-right: 5px;
            background-color: #4CAF50;
            color: white;
            border: none;
            border-radius: 5px;
            cursor: pointer;
        }
        button:hover {
            background-color: #45a049;
        }
        #stars {
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 70%;
            transition: opacity 0.5s ease;
            opacity: 0;
        }
        .star {
            position: absolute;
            background-color: white;
            border-radius: 50%;
        }
        #instructions {
            position: absolute;
            bottom: 20px;
            left: 20px;
            background-color: rgba(255, 255, 255, 0.8);
            padding: 15px;
            border-radius: 10px;
            max-width: 300px;
        }
    </style>
</head>
<body>
    <div id="game-container">
        <div id="sky"></div>
        <div id="stars"></div>
        <div id="sun-moon"></div>
        <div id="buildings"></div>
        <div id="ground"></div>
        
        <div id="controls">
            <div id="time-display">12:00</div>
            <div id="pitch-display">Тембр: 0</div>
            <div id="volume-display">Громкость: 0</div>
            <button id="start-btn">Начать запись голоса</button>
            <button id="stop-btn" disabled>Остановить</button>
        </div>
        
        <div id="instructions">
            <h3>Инструкция:</h3>
            <p>1. Нажмите "Начать запись голоса" и разрешите доступ к микрофону</p>
            <p>2. Говорите с разным тембром голоса:</p>
            <p>- Низкий тембр = ночь/раннее утро</p>
            <p>- Средний тембр = день</p>
            <p>- Высокий тембр = вечер/закат</p>
            <p>3. Громкость голоса влияет на яркость сцены</p>
        </div>
    </div>

    <script>
        // Создаем элементы сцены
        function setupScene() {
            // Создаем здания
            const buildingsContainer = document.getElementById('buildings');
            const buildingCount = 8;
            for (let i = 0; i < buildingCount; i++) {
                const building = document.createElement('div');
                building.classList.add('building');
                const height = 50 + Math.random() * 100;
                const width = 40 + Math.random() * 60;
                building.style.height = height + 'px';
                building.style.width = width + 'px';
                building.style.left = (i * (100 / buildingCount)) + '%';
                
                // Добавляем окна
                const windowRows = Math.floor(height / 20);
                const windowCols = Math.floor(width / 15);
                for (let r = 0; r < windowRows; r++) {
                    for (let c = 0; c < windowCols; c++) {
                        const windowEl = document.createElement('div');
                        windowEl.classList.add('window');
                        windowEl.style.width = '10px';
                        windowEl.style.height = '15px';
                        windowEl.style.left = (c * 15 + 5) + 'px';
                        windowEl.style.top = (r * 20 + 5) + 'px';
                        building.appendChild(windowEl);
                    }
                }
                
                buildingsContainer.appendChild(building);
            }
            
            // Создаем звезды
            const starsContainer = document.getElementById('stars');
            for (let i = 0; i < 100; i++) {
                const star = document.createElement('div');
                star.classList.add('star');
                const size = 1 + Math.random() * 2;
                star.style.width = size + 'px';
                star.style.height = size + 'px';
                star.style.left = Math.random() * 100 + '%';
                star.style.top = Math.random() * 100 + '%';
                starsContainer.appendChild(star);
            }
        }

        // Изменение времени суток
        function updateTimeOfDay(hour, minute, pitch, volume) {
            const gameContainer = document.getElementById('game-container');
            const sky = document.getElementById('sky');
            const ground = document.getElementById('ground');
            const sunMoon = document.getElementById('sun-moon');
            const buildings = document.querySelectorAll('.building');
            const windows = document.querySelectorAll('.window');
            const stars = document.getElementById('stars');
            
            // Нормализуем время (0-24)
            const time = hour + minute / 60;
            
            // Положение солнца/луны
            const angle = (time / 24) * 2 * Math.PI - Math.PI / 2;
            const radius = Math.min(window.innerWidth, window.innerHeight) * 0.4;
            const centerX = window.innerWidth / 2;
            const centerY = window.innerHeight * 0.7;
            const x = centerX + radius * Math.cos(angle);
            const y = centerY + radius * Math.sin(angle);
            
            sunMoon.style.left = (x - 40) + 'px';
            sunMoon.style.top = (y - 40) + 'px';
            
            // Цвета в зависимости от времени суток
            let skyColor, groundColor, sunMoonColor, buildingColor, windowColor;
            let starsOpacity = 0;
            
            // Раннее утро (5-7)
            if (time >= 5 && time < 7) {
                skyColor = `rgb(${Math.floor(59 + (158-59) * (time-5)/2)}, ${Math.floor(88 + (206-88) * (time-5)/2)}, ${Math.floor(128 + (235-128) * (time-5)/2)})`;
                groundColor = '#385c46';
                sunMoonColor = '#ff9e4f';
                buildingColor = '#555';
                windowColor = '#333';
            }
            // День (7-17)
            else if (time >= 7 && time < 17) {
                skyColor = '#9eceff';
                groundColor = '#4a7c59';
                sunMoonColor = '#ffee00';
                buildingColor = '#666';
                windowColor = '#444';
            }
            // Закат (17-19)
            else if (time >= 17 && time < 19) {
                const factor = (time - 17) / 2;
                skyColor = `rgb(${Math.floor(158 + (255-158) * factor)}, ${Math.floor(206 + (107-206) * factor)}, ${Math.floor(235 + (62-235) * factor)})`;
                groundColor = '#3d5d49';
                sunMoonColor = '#ff6700';
                buildingColor = '#555';
                windowColor = '#b3721f';
            }
            // Вечер (19-21)
            else if (time >= 19 && time < 21) {
                const factor = (time - 19) / 2;
                skyColor = `rgb(${Math.floor(255 - (255-20) * factor)}, ${Math.floor(107 - (107-42) * factor)}, ${Math.floor(62 - (62-87) * factor)})`;
                groundColor = '#2e463a';
                sunMoonColor = `rgb(${Math.floor(255 - 200 * factor)}, ${Math.floor(103 - 43 * factor)}, ${Math.floor(0 + 230 * factor)})`;
                buildingColor = '#444';
                windowColor = '#ffdb70';
                starsOpacity = factor;
            }
            // Ночь (21-5)
            else {
                skyColor = '#14283b';
                groundColor = '#1e2e26';
                sunMoonColor = '#e0e0e0';
                buildingColor = '#333';
                windowColor = '#ffdb70';
                starsOpacity = 1;
            }
            
            // Применяем цвета с учетом громкости (яркости)
            const brightnessMultiplier = 0.7 + volume * 0.3;
            
            // Функция для увеличения яркости цвета
            function adjustBrightness(hexOrRgb, multiplier) {
                // Для RGB формата
                if (hexOrRgb.startsWith('rgb')) {
                    const rgbValues = hexOrRgb.match(/\d+/g).map(Number);
                    return `rgb(${Math.min(255, Math.floor(rgbValues[0] * multiplier))}, ${Math.min(255, Math.floor(rgbValues[1] * multiplier))}, ${Math.min(255, Math.floor(rgbValues[2] * multiplier))})`;
                }
                
                // Для HEX формата
                const hex = hexOrRgb.replace('#', '');
                let r = parseInt(hex.substring(0, 2), 16);
                let g = parseInt(hex.substring(2, 4), 16);
                let b = parseInt(hex.substring(4, 6), 16);
                
                r = Math.min(255, Math.floor(r * multiplier));
                g = Math.min(255, Math.floor(g * multiplier));
                b = Math.min(255, Math.floor(b * multiplier));
                
                return `#${r.toString(16).padStart(2, '0')}${g.toString(16).padStart(2, '0')}${b.toString(16).padStart(2, '0')}`;
            }
            
            // Применяем подстроенные цвета
            sky.style.backgroundColor = skyColor;
            ground.style.backgroundColor = adjustBrightness(groundColor, brightnessMultiplier);
            sunMoon.style.backgroundColor = adjustBrightness(sunMoonColor, brightnessMultiplier);
            
            buildings.forEach(building => {
                building.style.backgroundColor = adjustBrightness(buildingColor, brightnessMultiplier);
            });
            
            windows.forEach(window => {
                // Ночью окна горят
                if (time >= 19 || time < 7) {
                    // Случайно определяем, горит ли окно
                    if (window.dataset.lit === undefined) {
                        window.dataset.lit = Math.random() > 0.3 ? 'true' : 'false';
                    }
                    if (window.dataset.lit === 'true') {
                        window.style.backgroundColor = adjustBrightness(windowColor, brightnessMultiplier);
                    } else {
                        window.style.backgroundColor = '#333';
                    }
                } else {
                    // Днем окна темные
                    window.style.backgroundColor = '#444';
                    delete window.dataset.lit;
                }
            });
            
            stars.style.opacity = starsOpacity;
        }

        // Обработка аудио
        let audioContext;
        let analyser;
        let microphone;
        let javascriptNode;
        let hours = 12;
        let minutes = 0;
        let lastPitch = 0;
        let lastVolume = 0;
        
        function startAudioProcessing() {
            const startBtn = document.getElementById('start-btn');
            const stopBtn = document.getElementById('stop-btn');
            
            startBtn.disabled = true;
            stopBtn.disabled = false;
            
            audioContext = new (window.AudioContext || window.webkitAudioContext)();
            analyser = audioContext.createAnalyser();
            analyser.fftSize = 2048;
            
            // Запрашиваем доступ к микрофону
            navigator.mediaDevices.getUserMedia({ audio: true })
                .then(function(stream) {
                    microphone = audioContext.createMediaStreamSource(stream);
                    microphone.connect(analyser);
                    
                    // Создаем обработчик для анализа звука
                    javascriptNode = audioContext.createScriptProcessor(2048, 1, 1);
                    analyser.connect(javascriptNode);
                    javascriptNode.connect(audioContext.destination);
                    
                    // Устанавливаем обработчик для анализа звука
                    javascriptNode.onaudioprocess = processAudio;
                })
                .catch(function(err) {
                    console.error('Ошибка доступа к микрофону:', err);
                    alert('Не удалось получить доступ к микрофону. Проверьте настройки браузера.');
                    startBtn.disabled = false;
                    stopBtn.disabled = true;
                });
        }
        
        function stopAudioProcessing() {
            const startBtn = document.getElementById('start-btn');
            const stopBtn = document.getElementById('stop-btn');
            
            startBtn.disabled = false;
            stopBtn.disabled = true;
            
            if (javascriptNode) {
                javascriptNode.onaudioprocess = null;
                javascriptNode.disconnect();
            }
            
            if (microphone) {
                microphone.disconnect();
            }
            
            if (analyser) {
                analyser.disconnect();
            }
            
            if (audioContext) {
                audioContext.close();
            }
        }
        
        function processAudio(event) {
            const bufferLength = analyser.frequencyBinCount;
            const dataArray = new Uint8Array(bufferLength);
            analyser.getByteFrequencyData(dataArray);
            
            // Вычисляем среднюю частоту (тембр)
            let sum = 0;
            let count = 0;
            
            // Используем только значимую часть спектра
            for (let i = 5; i < bufferLength / 4; i++) {
                if (dataArray[i] > 10) { // Игнорируем шум
                    sum += i * dataArray[i];
                    count += dataArray[i];
                }
            }
            
            // Вычисляем среднюю громкость
            let volumeSum = 0;
            for (let i = 0; i < bufferLength; i++) {
                volumeSum += dataArray[i];
            }
            let volumeAvg = volumeSum / bufferLength / 255;
            
            if (count > 0) {
                const normalizedPitch = sum / count / (bufferLength / 8);
                
                // Сглаживаем значения для более плавного перехода
                lastPitch = lastPitch * 0.7 + normalizedPitch * 0.3;
                lastVolume = lastVolume * 0.7 + volumeAvg * 0.3;
                
                // Обновляем отображение текущих значений
                document.getElementById('pitch-display').textContent = `Тембр: ${lastPitch.toFixed(2)}`;
                document.getElementById('volume-display').textContent = `Громкость: ${lastVolume.toFixed(2)}`;
                
                // Меняем время суток в зависимости от тембра
                hours = Math.floor(lastPitch * 24);
                minutes = Math.floor((lastPitch * 24 - hours) * 60);
                
                // Обновляем отображение времени
                document.getElementById('time-display').textContent = 
                    `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}`;
                
                // Обновляем сцену
                updateTimeOfDay(hours, minutes, lastPitch, lastVolume);
            }
        }
        
        // Инициализация
        window.onload = function() {
            setupScene();
            updateTimeOfDay(hours, minutes, 0.5, 0.5);
            
            // Устанавливаем обработчики событий для кнопок
            document.getElementById('start-btn').addEventListener('click', startAudioProcessing);
            document.getElementById('stop-btn').addEventListener('click', stopAudioProcessing);
            
            // Устанавливаем интервал для обновления времени даже без звука
            setInterval(function() {
                if (!audioContext) {
                    minutes++;
                    if (minutes >= 60) {
                        minutes = 0;
                        hours++;
                        if (hours >= 24) {
                            hours = 0;
                        }
                    }
                    
                    document.getElementById('time-display').textContent = 
                        `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}`;
                    
                    updateTimeOfDay(hours, minutes, hours / 24, 0.5);
                }
            }, 1000);
        };
    </script>
</body>
</html>