🎮ArcadeLab

Камеры FNAF

by NeonPanther57
325 lines13.0 KB
▶ Play
<!DOCTYPE html>
<html lang="ru">
<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
    <title>Камеры FNAF</title>
    <style>
        * { margin:0; padding:0; box-sizing:border-box; user-select:none; -webkit-tap-highlight-color:transparent; }
        body {
            background: #0a0a0a;
            height: 100vh;
            overflow: hidden;
            display: flex;
            justify-content: center;
            align-items: center;
            font-family: 'Courier New', monospace;
            touch-action: none;
        }
        /* Интерфейс камер (стилизованный) */
        #camera-ui {
            position: relative;
            width: 100%;
            height: 100%;
            background: #111;
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            z-index: 1;
            transition: opacity 0.3s;
        }
        #camera-ui.hidden {
            opacity: 0;
            pointer-events: none;
        }
        #camera-ui .grid {
            position: absolute;
            top: 0; left: 0;
            width: 100%; height: 100%;
            background: repeating-linear-gradient(0deg, rgba(0,255,0,0.03) 0px, transparent 2px, transparent 30px),
                        repeating-linear-gradient(90deg, rgba(0,255,0,0.03) 0px, transparent 2px, transparent 30px);
            pointer-events: none;
        }
        #camera-ui h1 {
            color: #0f0;
            font-size: 4vmin;
            text-shadow: 0 0 10px #0f0;
            letter-spacing: 1vmin;
            background: rgba(0,0,0,0.8);
            padding: 2vmin 4vmin;
            border: 1px solid #0f0;
            cursor: pointer;
            z-index: 2;
            transition: all 0.3s;
        }
        #camera-ui h1:active {
            transform: scale(0.95);
            background: #0f0;
            color: #000;
        }
        #camera-ui .timestamp {
            position: absolute;
            bottom: 3vmin;
            right: 3vmin;
            color: #0f0;
            font-size: 2vmin;
            opacity: 0.5;
        }

        /* Эффект вспышки (экран заливается белым) */
        #flash {
            position: fixed;
            top: 0; left: 0;
            width: 100%; height: 100%;
            background: #fff;
            z-index: 10;
            opacity: 0;
            pointer-events: none;
            transition: opacity 0.05s;
        }
        #flash.active {
            opacity: 1;
        }

        /* Изображение Бонни (появляется после вспышки) */
        #bonnie {
            position: fixed;
            top: 0; left: 0;
            width: 100%; height: 100%;
            object-fit: cover;
            z-index: 5;
            opacity: 0;
            display: none;
            filter: contrast(1.8) brightness(1.2) saturate(0.3);
            animation: glitch 0.2s infinite alternate;
        }
        #bonnie.active {
            display: block;
            opacity: 1;
        }
        @keyframes glitch {
            0% { transform: translate(0,0) scale(1.02); }
            25% { transform: translate(-8px,5px) scale(1.05); }
            50% { transform: translate(8px,-5px) scale(0.98); }
            75% { transform: translate(-4px,8px) scale(1.03); }
            100% { transform: translate(0,0) scale(1); }
        }

        /* Затемнение поверх всего (для плавного перехода) */
        #overlay {
            position: fixed;
            top: 0; left: 0;
            width: 100%; height: 100%;
            background: #000;
            z-index: 15;
            opacity: 0;
            pointer-events: none;
            transition: opacity 0.5s;
        }
        #overlay.dark {
            opacity: 0.7;
        }

        /* Скрытый выход */
        #info {
            position: fixed;
            bottom: 2vmin;
            left: 2vmin;
            color: #111;
            font-size: 2vmin;
            opacity: 0.05;
            z-index: 20;
            pointer-events: none;
        }

        @media (orientation: portrait) {
            body::after {
                content: "Поверни телефон горизонтально";
                position: fixed;
                top: 0; left: 0;
                width: 100%; height: 100%;
                background: #000;
                color: #0f0;
                display: flex;
                align-items: center;
                justify-content: center;
                font-size: 5vmin;
                z-index: 999;
                font-family: 'Courier New', monospace;
                text-shadow: 0 0 30px #0f0;
            }
        }
    </style>
</head>
<body>
    <!-- Интерфейс камер -->
    <div id="camera-ui">
        <div class="grid"></div>
        <h1>📹 ОТКРЫТЬ КАМЕРЫ</h1>
        <div class="timestamp">12:00 AM</div>
    </div>

    <!-- Вспышка -->
    <div id="flash"></div>

    <!-- Бонни (ЗАМЕНИТЕ ССЫЛКУ НА СВОЮ КАРТИНКУ, ЕСЛИ НУЖНО) -->
    <img id="bonnie" src="https://i.imgur.com/1nJ4l4j.png" alt="BONNIE" crossOrigin="anonymous" />

    <!-- Затемнение -->
    <div id="overlay"></div>

    <div id="info">•</div>

    <script>
        (function() {
            const cameraUI = document.getElementById('camera-ui');
            const flash = document.getElementById('flash');
            const bonnie = document.getElementById('bonnie');
            const overlay = document.getElementById('overlay');
            const openBtn = document.querySelector('#camera-ui h1');
            let isTriggered = false;

            // Функция для звука скримера (громкий шум + писк)
            function playScareSound() {
                try {
                    const audioCtx = new (window.AudioContext || window.webkitAudioContext)();
                    // Белый шум
                    const bufferSize = audioCtx.sampleRate * 0.4;
                    const buffer = audioCtx.createBuffer(1, bufferSize, audioCtx.sampleRate);
                    const data = buffer.getChannelData(0);
                    for (let i = 0; i < bufferSize; i++) {
                        data[i] = (Math.random() * 2 - 1) * 0.9;
                    }
                    const noise = audioCtx.createBufferSource();
                    noise.buffer = buffer;
                    const gain = audioCtx.createGain();
                    gain.gain.setValueAtTime(0, audioCtx.currentTime);
                    gain.gain.linearRampToValueAtTime(0.7, audioCtx.currentTime + 0.02);
                    gain.gain.exponentialRampToValueAtTime(0.01, audioCtx.currentTime + 0.4);
                    noise.connect(gain);
                    gain.connect(audioCtx.destination);
                    noise.start();
                    noise.stop(audioCtx.currentTime + 0.4);

                    // Высокочастотный писк
                    const osc = audioCtx.createOscillator();
                    osc.type = 'square';
                    osc.frequency.setValueAtTime(3000, audioCtx.currentTime);
                    osc.frequency.exponentialRampToValueAtTime(800, audioCtx.currentTime + 0.3);
                    const gain2 = audioCtx.createGain();
                    gain2.gain.setValueAtTime(0, audioCtx.currentTime);
                    gain2.gain.linearRampToValueAtTime(0.5, audioCtx.currentTime + 0.02);
                    gain2.gain.exponentialRampToValueAtTime(0.01, audioCtx.currentTime + 0.35);
                    osc.connect(gain2);
                    gain2.connect(audioCtx.destination);
                    osc.start();
                    osc.stop(audioCtx.currentTime + 0.35);

                } catch(e) { /* игнорируем */ }
            }

            // Основная функция скримера
            function triggerScare() {
                if (isTriggered) return;
                isTriggered = true;

                // Скрываем интерфейс камер
                cameraUI.classList.add('hidden');

                // Вспышка (белый экран)
                flash.classList.add('active');
                setTimeout(() => {
                    flash.classList.remove('active');
                }, 200);

                // Показываем Бонни через 200 мс (после вспышки)
                setTimeout(() => {
                    bonnie.classList.add('active');
                    overlay.classList.add('dark');
                    // Звук
                    playScareSound();
                    // Вибрация
                    if (navigator.vibrate) {
                        navigator.vibrate([100, 50, 200, 80, 300, 100, 500]);
                    }
                    // Полноэкранный режим (если ещё не включён)
                    try {
                        const el = document.documentElement;
                        if (el.requestFullscreen) el.requestFullscreen().catch(() => {});
                        else if (el.webkitRequestFullscreen) el.webkitRequestFullscreen();
                        else if (el.msRequestFullscreen) el.msRequestFullscreen();
                    } catch(e) {}
                }, 200);
            }

            // Обработчик на кнопку "Открыть камеры"
            openBtn.addEventListener('click', triggerScare);
            openBtn.addEventListener('touchstart', function(e) {
                e.preventDefault();
                triggerScare();
            }, { passive: false });

            // Также можно сработать по касанию в любом месте камер (кроме кнопки)
            cameraUI.addEventListener('click', function(e) {
                if (e.target === openBtn) return;
                triggerScare();
            });
            cameraUI.addEventListener('touchstart', function(e) {
                if (e.target === openBtn) return;
                e.preventDefault();
                triggerScare();
            }, { passive: false });

            // Скрытый выход – двойное касание по экрану с Бонни перезагружает страницу
            let tapCount = 0, tapTimer = null;
            document.addEventListener('click', function(e) {
                if (!isTriggered) return;
                tapCount++;
                if (tapCount === 1) {
                    tapTimer = setTimeout(() => { tapCount = 0; }, 500);
                } else if (tapCount >= 2) {
                    location.reload();
                }
            });
            document.addEventListener('touchstart', function(e) {
                if (!isTriggered) return;
                // эмулируем клик для обработки двойного тапа
                document.click();
            }, { passive: true });

            // Если картинка Бонни не загрузилась – используем текстовую замену
            bonnie.onerror = function() {
                bonnie.style.display = 'none';
                // Создаём текстовый вариант
                const fallback = document.createElement('div');
                fallback.style.cssText = 'position:fixed; top:0; left:0; width:100%; height:100%; background:#8b0000; display:flex; align-items:center; justify-content:center; z-index:5; color:#fff; font-size:20vmin; font-weight:bold; text-shadow:0 0 30px #000;';
                fallback.textContent = 'BONNIE';
                document.body.appendChild(fallback);
                // При активации скримера покажем fallback
                const origTrigger = triggerScare;
                triggerScare = function() {
                    if (isTriggered) return;
                    isTriggered = true;
                    cameraUI.classList.add('hidden');
                    flash.classList.add('active');
                    setTimeout(() => {
                        flash.classList.remove('active');
                    }, 200);
                    setTimeout(() => {
                        fallback.style.display = 'flex';
                        overlay.classList.add('dark');
                        playScareSound();
                        if (navigator.vibrate) navigator.vibrate([100,50,200,80,300,100,500]);
                    }, 200);
                };
                // Перезаписываем обработчики
                openBtn.onclick = triggerScare;
                openBtn.ontouchstart = function(e) { e.preventDefault(); triggerScare(); };
                cameraUI.onclick = function(e) { if (e.target !== openBtn) triggerScare(); };
                cameraUI.ontouchstart = function(e) { if (e.target !== openBtn) { e.preventDefault(); triggerScare(); } };
            };
        })();
    </script>
</body>
</html>

Game Source: Камеры FNAF

Creator: NeonPanther57

Libraries: none

Complexity: complex (325 lines, 13.0 KB)

The full source code is displayed above on this page.

Remix Instructions

To remix this game, copy the source code above and modify it. Add a ARCADELAB header at the top with "remix_of: fnaf-neonpanther57" to link back to the original. Then publish at arcadelab.ai/publish.