🎮ArcadeLab

NEBULA CALC | СЕКРЕТНАЯ ИГРА

by SparkHawk26
577 lines20.2 KB
▶ Play
<!DOCTYPE html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
    <title>NEBULA CALC | СЕКРЕТНАЯ ИГРА</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
            user-select: none;
        }

        body {
            min-height: 100vh;
            background: radial-gradient(circle at 30% 10%, #0c0a1a, #020105);
            display: flex;
            justify-content: center;
            align-items: center;
            font-family: 'Segoe UI', 'Courier New', monospace;
            padding: 20px;
            transition: all 0.3s;
        }

        /* КАЛЬКУЛЯТОР (виден по умолчанию) */
        .calculator-wrapper {
            width: 100%;
            max-width: 450px;
            margin: 0 auto;
            transition: 0.3s;
        }

        body.game-mode .calculator-wrapper {
            display: none;
        }

        body.game-mode .game-container {
            display: block;
        }

        .calculator {
            background: linear-gradient(145deg, #1e1a2f, #0f0b1a);
            border-radius: 56px;
            padding: 24px 20px 30px 20px;
            box-shadow: 0 25px 45px rgba(0, 0, 0, 0.6);
            border: 1px solid rgba(156, 80, 255, 0.35);
        }

        .screen {
            background: #07050e;
            padding: 25px 20px;
            border-radius: 48px;
            margin-bottom: 30px;
            border: 1px solid #3c2a6e;
        }

        .previous-operand {
            min-height: 32px;
            font-size: 1.2rem;
            color: #b58eff;
            text-align: right;
        }

        .current-operand {
            font-size: 3rem;
            font-weight: 700;
            color: #f0e6ff;
            text-align: right;
            word-break: break-all;
            text-shadow: 0 0 6px #9b4dff;
        }

        .buttons {
            display: grid;
            grid-template-columns: repeat(4, 1fr);
            gap: 14px;
        }

        button {
            background: #15102a;
            border: none;
            padding: 18px 0;
            font-size: 1.6rem;
            font-weight: bold;
            border-radius: 48px;
            color: #e2d6ff;
            cursor: pointer;
            transition: 0.08s linear;
            box-shadow: 0 6px 0 #0a0720;
            border: 1px solid rgba(128, 90, 240, 0.4);
        }

        button:active {
            transform: translateY(3px);
            box-shadow: 0 2px 0 #0a0720;
        }

        .operator {
            background: #2a1a55;
            color: #dbbaff;
            font-size: 1.9rem;
        }

        .equals {
            background: #9b4dff;
            color: #1a0f2e;
            box-shadow: 0 6px 0 #5c2ab3;
        }

        .clear, .delete {
            background: #3d1f5e;
        }
        .delete {
            background: #5a2a82;
        }

        .secret-hint {
            text-align: center;
            margin-top: 20px;
            font-size: 0.75rem;
            color: #8a6fcf;
        }

        /* ИГРОВОЙ КОНТЕЙНЕР (скрыт) */
        .game-container {
            display: none;
            width: 100%;
            max-width: 900px;
            background: #0c0820;
            border-radius: 56px;
            padding: 20px;
            border: 2px solid #9b4dff;
        }

        .game-header {
            display: flex;
            justify-content: space-between;
            background: #180e2e;
            padding: 12px 20px;
            border-radius: 60px;
            margin-bottom: 18px;
            color: #f2dd9f;
            font-weight: bold;
            flex-wrap: wrap;
            gap: 10px;
        }

        canvas {
            display: block;
            margin: 0 auto;
            border-radius: 24px;
            background: #0d0a1a;
            width: 100%;
            height: auto;
            cursor: pointer;
        }

        .secret-controls {
            display: flex;
            justify-content: center;
            gap: 20px;
            margin-top: 20px;
        }

        .sec-btn {
            background: #2d1f53;
            padding: 10px 20px;
            font-size: 1.4rem;
            border-radius: 48px;
            color: #ffd966;
            box-shadow: 0 4px 0 #0e0820;
        }

        .back-btn {
            background: #671b5e;
        }

        .cheat-info {
            text-align: center;
            margin-top: 12px;
            color: #ffdc97;
            background: #00000088;
            padding: 6px;
            border-radius: 60px;
            font-size: 0.8rem;
        }

        @media (max-width: 560px) {
            button { padding: 12px 0; font-size: 1.3rem; }
            .sec-btn { font-size: 1rem; padding: 8px 16px; }
        }
    </style>
</head>
<body>

    <!-- КАЛЬКУЛЯТОР -->
    <div class="calculator-wrapper">
        <div class="calculator">
            <div class="screen">
                <div class="previous-operand" id="previousOperand"></div>
                <div class="current-operand" id="currentOperand">0</div>
            </div>
            <div class="buttons">
                <button class="clear" data-action="clear">C</button>
                <button class="delete" data-action="delete">⌫</button>
                <button class="operator" data-operator="%">%</button>
                <button class="operator" data-operator="/">÷</button>
                <button data-number="7">7</button>
                <button data-number="8">8</button>
                <button data-number="9">9</button>
                <button class="operator" data-operator="*">×</button>
                <button data-number="4">4</button>
                <button data-number="5">5</button>
                <button data-number="6">6</button>
                <button class="operator" data-operator="-">−</button>
                <button data-number="1">1</button>
                <button data-number="2">2</button>
                <button data-number="3">3</button>
                <button class="operator" data-operator="+">+</button>
                <button data-number="0">0</button>
                <button data-number=".">.</button>
                <button class="equals" id="equalsBtn">=</button>
            </div>
            <div class="secret-hint">
                🔮 СЕКРЕТ: нажми = при числе 258425 или введи 25+84+25=
            </div>
        </div>
    </div>

    <!-- СЕКРЕТНАЯ ИГРА SUBVS -->
    <div class="game-container" id="secretGame">
        <div class="game-header">
            <span>🌀 SUBVS: SUBWAY SURFERS STYLE 🐹</span>
            <span>🏆 СЧЁТ: <span id="gameScore">0</span></span>
            <span>🐹 ХОМЯКИ: <span id="gameCoins">0</span></span>
            <span>⚡ РЕКОРД: <span id="gameBest">0</span></span>
        </div>
        <canvas id="gameCanvas" width="800" height="500" style="width:100%; max-width:800px; aspect-ratio:800/500"></canvas>
        <div class="secret-controls">
            <button class="sec-btn" id="leftBtn">◀ ЛЕВО</button>
            <button class="sec-btn" id="rightBtn">ПРАВО ▶</button>
            <button class="sec-btn back-btn" id="exitBtn">🔒 ВЫЙТИ</button>
        </div>
        <div class="cheat-info">✨ ЧИТЫ АКТИВИРОВАНЫ! Уклоняйся от поездов, собирай хомяков ✨</div>
    </div>

    <script>
        // ========== КАЛЬКУЛЯТОР С АКТИВАЦИЕЙ ПО КОДУ ==========
        const previousOperandEl = document.getElementById('previousOperand');
        const currentOperandEl = document.getElementById('currentOperand');
        let current = "0";
        let previous = "";
        let operation = null;
        let resetScreen = false;

        function formatNumber(num) {
            let str = num.toString();
            let parts = str.split('.');
            parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, " ");
            return parts.join('.');
        }

        function updateDisplay() {
            currentOperandEl.innerText = formatNumber(current);
            if (operation && previous !== "") {
                previousOperandEl.innerText = `${formatNumber(previous)} ${operation}`;
            } else {
                previousOperandEl.innerText = previous ? formatNumber(previous) : "";
            }
        }

        function appendNumber(num) {
            if (resetScreen) {
                current = "";
                resetScreen = false;
            }
            if (num === '.' && current.includes('.')) return;
            if (current === "0" && num !== '.') current = num;
            else current += num;
            updateDisplay();
        }

        function chooseOperation(op) {
            if (current === "") return;
            if (previous !== "" && !resetScreen) compute();
            operation = op;
            previous = current;
            current = "";
            resetScreen = false;
            updateDisplay();
        }

        function compute() {
            if (!operation || previous === "" || current === "") return;
            let a = parseFloat(previous.replace(/\s/g, ''));
            let b = parseFloat(current.replace(/\s/g, ''));
            if (isNaN(a) || isNaN(b)) return;
            let result;
            switch (operation) {
                case '+': result = a + b; break;
                case '-': result = a - b; break;
                case '×': result = a * b; break;
                case '÷': result = b === 0 ? "Ошибка" : a / b; break;
                case '%': result = a % b; break;
                default: return;
            }
            if (result === "Ошибка") {
                current = "∞";
                previous = "";
                operation = null;
                resetScreen = true;
                updateDisplay();
                return;
            }
            result = parseFloat(result.toFixed(8));
            current = result.toString();
            operation = null;
            previous = "";
            resetScreen = true;
            updateDisplay();

            // ⭐⭐⭐ АКТИВАЦИЯ СЕКРЕТА ⭐⭐⭐
            let rawResult = current.replace(/\s/g, '');
            // Если результат равен 258425 (после вычисления 25+84+25 или 258425=)
            if (rawResult === "258425") {
                openSecretGame();
            }
        }

        function clearAll() {
            current = "0";
            previous = "";
            operation = null;
            resetScreen = false;
            updateDisplay();
        }

        function deleteLast() {
            if (resetScreen) return;
            if (current.length === 1 || current === "0") current = "0";
            else current = current.slice(0, -1);
            updateDisplay();
        }

        // При нажатии = сначала вычисляем, а потом проверяем
        document.getElementById('equalsBtn').addEventListener('click', () => {
            compute();
        });

        document.querySelectorAll('[data-number]').forEach(btn => {
            btn.addEventListener('click', () => appendNumber(btn.dataset.number));
        });
        document.querySelectorAll('[data-operator]').forEach(btn => {
            btn.addEventListener('click', () => chooseOperation(btn.dataset.operator));
        });
        document.querySelector('[data-action="clear"]').addEventListener('click', clearAll);
        document.querySelector('[data-action="delete"]').addEventListener('click', deleteLast);

        updateDisplay();

        // ========== ОТКРЫТИЕ СЕКРЕТНОЙ ИГРЫ ==========
        function openSecretGame() {
            if (document.body.classList.contains('game-mode')) return;
            document.body.classList.add('game-mode');
            startGame();
        }

        function closeSecretGame() {
            document.body.classList.remove('game-mode');
            if (gameLoopId) cancelAnimationFrame(gameLoopId);
            gameActive = false;
        }

        // ========== 2D ИГРА SUBWAY STYLE (хомяки, поезда, бегун) ==========
        let canvas = document.getElementById('gameCanvas');
        let ctx = canvas?.getContext('2d');
        let gameActive = true;
        let score = 0;
        let coins = 0;
        let best = localStorage.getItem('subwayBestHam') ? parseInt(localStorage.getItem('subwayBestHam')) : 0;
        let playerLane = 1;
        let trainsList = [];
        let hamstersList = [];
        let gameFrame = 0;
        let speed = 4.2;

        const LANE_W = 110;
        const BASE_X = 180;
        const PLAY_W = 40, PLAY_H = 50;
        const TRAIN_W = 48, TRAIN_H = 58;
        const HAM_W = 34, HAM_H = 34;

        function updateGameUI() {
            document.getElementById('gameScore').innerText = Math.floor(score);
            document.getElementById('gameCoins').innerText = coins;
            document.getElementById('gameBest').innerText = best;
        }

        function spawnTrain() {
            let lane = Math.floor(Math.random() * 3);
            trainsList.push({ lane, y: -TRAIN_H - Math.random() * 50 });
        }
        function spawnHamster() {
            let lane = Math.floor(Math.random() * 3);
            hamstersList.push({ lane, y: -HAM_H - Math.random() * 60, rot: Math.random() * Math.PI * 2 });
        }

        function updateGamePhysics() {
            if (!gameActive) return;
            speed = 4 + Math.floor(score / 500) * 0.7;
            if (speed > 11) speed = 11;

            for (let t of trainsList) t.y += speed;
            trainsList = trainsList.filter(t => t.y < canvas.height + 100);
            for (let h of hamstersList) {
                h.y += speed;
                h.rot = (h.rot + 0.1) % (Math.PI * 2);
            }
            hamstersList = hamstersList.filter(h => h.y < canvas.height + 100);

            let trainRate = Math.max(22, 45 - Math.floor(score / 120));
            let hamRate = Math.max(14, 32 - Math.floor(score / 100));
            if (gameFrame % trainRate === 0) spawnTrain();
            if (gameFrame % hamRate === 0) spawnHamster();

            let playerX = BASE_X + playerLane * LANE_W + LANE_W/2 - PLAY_W/2;
            let playerY = canvas.height - PLAY_H - 18;
            let playerRect = { x: playerX, y: playerY, w: PLAY_W, h: PLAY_H };

            // поезда
            for (let i=0; i<trainsList.length; i++) {
                let t = trainsList[i];
                let tx = BASE_X + t.lane * LANE_W + LANE_W/2 - TRAIN_W/2;
                if (playerRect.x < tx + TRAIN_W && playerRect.x + PLAY_W > tx &&
                    playerRect.y < t.y + TRAIN_H && playerRect.y + PLAY_H > t.y) {
                    gameActive = false;
                    if (Math.floor(score) > best) {
                        best = Math.floor(score);
                        localStorage.setItem('subwayBestHam', best);
                    }
                    updateGameUI();
                    return;
                }
            }

            // хомяки
            for (let i=0; i<hamstersList.length; i++) {
                let h = hamstersList[i];
                let hx = BASE_X + h.lane * LANE_W + LANE_W/2 - HAM_W/2;
                if (playerRect.x < hx + HAM_W && playerRect.x + PLAY_W > hx &&
                    playerRect.y < h.y + HAM_H && playerRect.y + PLAY_H > h.y) {
                    coins++;
                    hamstersList.splice(i,1);
                    i--;
                    updateGameUI();
                }
            }
            score += 0.25;
            updateGameUI();
            gameFrame++;
        }

        function drawGame() {
            if (!ctx) return;
            ctx.clearRect(0, 0, canvas.width, canvas.height);
            ctx.fillStyle = "#130c24";
            ctx.fillRect(0, 0, canvas.width, canvas.height);
            // рельсы
            for (let i=0; i<=3; i++) {
                let rx = BASE_X + i * LANE_W - 5;
                ctx.beginPath();
                ctx.strokeStyle = "#b37bff";
                ctx.lineWidth = 3;
                for (let s=0; s<canvas.height+40; s+=35) {
                    ctx.beginPath();
                    ctx.moveTo(rx, s);
                    ctx.lineTo(rx+8, s+18);
                    ctx.stroke();
                }
            }
            // поезда
            for (let t of trainsList) {
                let x = BASE_X + t.lane * LANE_W + LANE_W/2 - TRAIN_W/2;
                ctx.fillStyle = "#4a2b7a";
                ctx.fillRect(x, t.y, TRAIN_W, TRAIN_H);
                ctx.fillStyle = "#dcaaff";
                ctx.fillRect(x+8, t.y+12, TRAIN_W-16, 10);
                ctx.fillStyle = "#ffbc6e";
                ctx.beginPath();
                ctx.arc(x+TRAIN_W/2, t.y+14, 7, 0, Math.PI*2);
                ctx.fill();
            }
            // хомяки вращающиеся
            for (let h of hamstersList) {
                let x = BASE_X + h.lane * LANE_W + LANE_W/2 - HAM_W/2;
                ctx.save();
                ctx.translate(x+HAM_W/2, h.y+HAM_H/2);
                ctx.rotate(h.rot);
                ctx.fillStyle = "#bc8a5a";
                ctx.beginPath();
                ctx.ellipse(0, 0, HAM_W/2.2, HAM_H/2.2, 0, 0, Math.PI*2);
                ctx.fill();
                ctx.fillStyle = "#4f2d15";
                ctx.beginPath();
                ctx.ellipse(-6, -5, 4, 5, 0, 0, Math.PI*2);
                ctx.ellipse(6, -5, 4, 5, 0, 0, Math.PI*2);
                ctx.fill();
                ctx.fillStyle = "white";
                ctx.beginPath();
                ctx.arc(-5, -7, 2, 0, Math.PI*2);
                ctx.arc(5, -7, 2, 0, Math.PI*2);
                ctx.fill();
                ctx.fillStyle = "#ffad60";
                ctx.font = "20px monospace";
                ctx.fillText("🐹", -10, -6);
                ctx.restore();
            }
            // игрок
            let px = BASE_X + playerLane * LANE_W + LANE_W/2 - PLAY_W/2;
            let py = canvas.height - PLAY_H - 18;
            ctx.fillStyle = "#bf6eff";
            ctx.fillRect(px, py, PLAY_W, PLAY_H);
            ctx.fillStyle = "#ffce70";
            ctx.beginPath();
            ctx.ellipse(px+PLAY_W/2, py-6, 14, 10, 0, 0, Math.PI*2);
            ctx.fill();
            ctx.fillStyle = "#2c1c42";
            ctx.fillRect(px+10, py+28, 7, 12);
            ctx.fillRect(px+PLAY_W-17, py+28, 7, 12);
            if (!gameActive) {
                ctx.font = "bold 28monospace";
                ctx.fillStyle = "#ffbf7a";
                ctx.fillText("💀 ИГРА ОКОНЧЕНА", canvas.width/2-140, canvas.height/2);
            }
        }

        let gameLoopId = null;
        function gameLoop() {
            if (!ctx) return;
            if (gameActive) updateGamePhysics();
            drawGame();
            gameLoopId = requestAnimationFrame(gameLoop);
        }

        function startGame() {
            if (!canvas) canvas = document.getElementById('gameCanvas');
            if (!ctx) ctx = canvas?.getContext('2d');
            gameActive = true;
            score = 0;
            coins = 0;
            trainsList = [];
            hamstersList = [];
            playerLane = 1;
            gameFrame = 0;
            speed = 4.2;
            updateGameUI();
            if (gameLoopId) cancelAnimationFrame(gameLoopId);
            gameLoop();
        }

        // управление
        document.getElementById('leftBtn')?.addEventListener('click', () => { if (gameActive && playerLane > 0) playerLane--; });
        document.getElementById('rightBtn')?.addEventListener('click', () => { if (gameActive && playerLane < 2) playerLane++; });
        document.getElementById('exitBtn')?.addEventListener('click', closeSecretGame);
        window.addEventListener('keydown', (e) => {
            if (document.body.classList.contains('game-mode')) {
                if (e.key === 'ArrowLeft') { if (gameActive && playerLane > 0) playerLane--; e.preventDefault(); }
                if (e.key === 'ArrowRight') { if (gameActive && playerLane < 2) playerLane++; e.preventDefault(); }
            }
        });

        // Запасной способ: если ввели 258425 и нажали =
        window.openSecretGame = openSecretGame;
    </script>
</body>
</html>

Game Source: NEBULA CALC | СЕКРЕТНАЯ ИГРА

Creator: SparkHawk26

Libraries: none

Complexity: complex (577 lines, 20.2 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: nebula-calc-sparkhawk26" to link back to the original. Then publish at arcadelab.ai/publish.