🎮ArcadeLab

Ребёрт — РАБОЧИЙ

by AtomicScout38
621 lines24.3 KB
▶ Play
<!DOCTYPE html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Ребёрт — РАБОЧИЙ</title>
    <style>
        * { box-sizing: border-box; margin: 0; user-select: none; }
        body {
            min-height: 100vh;
            background: #0b141a;
            display: flex;
            justify-content: center;
            align-items: center;
            font-family: 'Segoe UI', system-ui, sans-serif;
            padding: 16px;
        }
        .game {
            max-width: 750px;
            width: 100%;
            background: #16232e;
            border-radius: 40px;
            padding: 24px 20px 32px;
            border: 1px solid #2f4b5e;
            box-shadow: 0 20px 40px #00000088;
        }
        h1 {
            text-align: center;
            color: #b3dfee;
            font-weight: 300;
            letter-spacing: 3px;
            font-size: 1.8rem;
            margin-bottom: 8px;
        }
        .stats {
            display: flex;
            flex-wrap: wrap;
            gap: 8px;
            justify-content: space-between;
            background: #0f1e28;
            border-radius: 60px;
            padding: 12px 18px;
            margin-bottom: 14px;
        }
        .stat-item {
            color: #c3ddee;
            font-size: 0.9rem;
        }
        .stat-item span {
            font-weight: 700;
            font-size: 1.5rem;
            display: inline-block;
            min-width: 45px;
        }
        .stat-item .money-color { color: #f7e97e; }
        .stat-item .click-color { color: #6fc3ff; }
        .stat-item .income-color { color: #7ae0a0; }
        .stat-item .multiplier-color { color: #ff8a8a; }
        .click-btn {
            width: 100%;
            padding: 24px;
            font-size: 2.2rem;
            font-weight: 700;
            background: #1f3a4a;
            border: none;
            border-radius: 80px;
            color: #f0ffe0;
            text-shadow: 0 3px 0 #0b1d28;
            box-shadow: 0 8px 0 #0a1c27, inset 0 0 0 1px #4a7a92;
            cursor: pointer;
            transition: all 0.05s linear;
            margin-bottom: 14px;
            letter-spacing: 4px;
        }
        .click-btn:active { transform: translateY(4px); box-shadow: 0 4px 0 #0a1c27; }
        .click-btn.disabled {
            opacity: 0.4;
            pointer-events: none;
            filter: grayscale(0.6);
        }
        .subtext {
            text-align: center;
            color: #6793a8;
            font-size: 0.9rem;
            margin-top: -10px;
            margin-bottom: 16px;
        }
        .upgrade-group {
            background: #13212c;
            border-radius: 28px;
            padding: 14px 12px;
            margin-bottom: 12px;
            border-left: 4px solid #3f7a94;
        }
        .group-title {
            color: #aacfdf;
            font-weight: 600;
            font-size: 1rem;
            margin-bottom: 8px;
            display: flex;
            justify-content: space-between;
        }
        .group-title small {
            font-weight: 400;
            color: #5f8ba0;
            font-size: 0.75rem;
        }
        .upgrade-grid {
            display: grid;
            grid-template-columns: 1fr 1fr 1fr;
            gap: 8px;
        }
        .upgrade-card {
            background: #1d3341;
            border-radius: 16px;
            padding: 10px 6px;
            text-align: center;
            cursor: pointer;
            border: 1px solid #2d5064;
            transition: 0.05s;
            box-shadow: 0 3px 0 #0b1a24;
        }
        .upgrade-card:active { transform: scale(0.95); box-shadow: 0 1px 0 #0b1a24; }
        .upgrade-card.disabled {
            opacity: 0.4;
            pointer-events: none;
            filter: grayscale(0.5);
        }
        .upgrade-card .name { color: #ecf9ff; font-weight: 600; font-size: 0.9rem; }
        .upgrade-card .desc { color: #a1c2d4; font-size: 0.7rem; }
        .upgrade-card .cost {
            background: #0b1f2b;
            padding: 2px 12px;
            border-radius: 30px;
            color: #f5e56b;
            font-weight: 700;
            font-size: 0.8rem;
            display: inline-block;
            margin-top: 3px;
        }
        .upgrade-card .cost.click-cost { color: #6fc3ff; background: #0b1a2b; }
        .upgrade-card .level {
            color: #6d97ae;
            font-size: 0.65rem;
        }
        .reset-area {
            display: flex;
            gap: 12px;
            margin-top: 14px;
            align-items: center;
            flex-wrap: wrap;
        }
        .reset-btn {
            flex: 1;
            padding: 12px;
            border: none;
            border-radius: 60px;
            font-weight: 700;
            font-size: 1rem;
            cursor: pointer;
            transition: 0.05s;
            background: #2a4457;
            color: #d2e7f0;
            box-shadow: 0 4px 0 #10212b;
            min-width: 100px;
        }
        .reset-btn:active { transform: translateY(3px); box-shadow: 0 1px 0 #10212b; }
        .reset-btn.rebirth {
            background: #4a2f5a;
            box-shadow: 0 4px 0 #2a1a35;
        }
        .reset-btn.rebirth.disabled {
            opacity: 0.4;
            pointer-events: none;
            filter: grayscale(0.5);
        }
        .rebirth-condition {
            color: #b3d9ee;
            font-size: 0.85rem;
            background: #0f1e28;
            padding: 8px 16px;
            border-radius: 40px;
            flex: 1;
            min-width: 150px;
            text-align: center;
        }
        .rebirth-condition span { color: #6fc3ff; font-weight: 700; }
        .footer { text-align: right; color: #3f6478; font-size: 0.7rem; margin-top: 10px; }
        @media (max-width: 550px) { 
            .upgrade-grid { grid-template-columns: 1fr 1fr; }
            .reset-area { flex-direction: column; }
        }
    </style>
</head>
<body>
<div class="game">
    <h1>✅ РАБОЧАЯ ВЕРСИЯ</h1>
    <div class="stats">
        <div class="stat-item">💰 <span class="money-color" id="moneyDisplay">0</span></div>
        <div class="stat-item">👆 <span class="click-color" id="clicksDisplay">0</span></div>
        <div class="stat-item">⚡ <span class="income-color" id="incomeDisplay">5</span>/с</div>
        <div class="stat-item">🔴 <span class="multiplier-color" id="multiplierDisplay">1.0</span></div>
    </div>

    <button class="click-btn disabled" id="clickBtn">👆 КЛИК</button>
    <div class="subtext" id="clickHint">🔒 откроется после 7-го улучшения</div>

    <!-- Группа 1 -->
    <div class="upgrade-group" id="group1">
        <div class="group-title">🔥 Первое улучшение <small>×3 за уровень</small></div>
        <div class="upgrade-grid" id="group1Grid"></div>
    </div>

    <!-- Группа 2 -->
    <div class="upgrade-group" id="group2" style="display:none;">
        <div class="group-title">🌀 Второе улучшение <small>×1.5 за уровень</small></div>
        <div class="upgrade-grid" id="group2Grid"></div>
    </div>

    <!-- Группа 3 -->
    <div class="upgrade-group" id="group3" style="display:none;">
        <div class="group-title">⚡ Элитные улучшения</div>
        <div class="upgrade-grid" id="group3Grid"></div>
    </div>

    <!-- Группа 4 -->
    <div class="upgrade-group" id="group4" style="display:none;">
        <div class="group-title">🌟 Сверх-улучшения</div>
        <div class="upgrade-grid" id="group4Grid"></div>
    </div>

    <div class="reset-area">
        <button class="reset-btn" id="resetBtn">⟳ Сброс</button>
        <button class="reset-btn rebirth disabled" id="rebirthBtn">♻️ Ребёрт</button>
        <div class="rebirth-condition" id="rebirthCondition">
            👆 нужно <span id="rebirthNeed">0</span> кликов (есть <span id="rebirthHave">0</span>)
        </div>
    </div>
    <div class="footer">все кнопки работают ✅</div>
</div>

<script>
    (function() {
        // ===== СОСТОЯНИЕ =====
        let state = {
            money: 0,
            clicks: 0,
            income: 5,
            clickPower: 0,
            clickUnlocked: false,
            globalMultiplier: 1.0,

            g1: { level: 0, maxLevel: 4, baseCost: 15, multiplier: 4, power: 3 },
            g2: { level: 0, maxLevel: 6, baseCost: 60, multiplier: 2, power: 1.5 },
            g3: { 
                clicker: { level: 0, baseCost: 200, multiplier: 2.5, power: 5 },
                rebirth: { level: 0, baseCost: 100, multiplier: 2 }
            },
            g4: {
                power1: { level: 0, baseCost: 500, multiplier: 2.2, power: 10, name: '💪 Мощь' },
                power2: { level: 0, baseCost: 800, multiplier: 2.3, power: 15, name: '⚡ Ускорение' },
                power3: { level: 0, baseCost: 1200, multiplier: 2.5, power: 25, name: '🔥 Гипер' },
            }
        };

        // ===== DOM =====
        const moneyDisplay = document.getElementById('moneyDisplay');
        const clicksDisplay = document.getElementById('clicksDisplay');
        const incomeDisplay = document.getElementById('incomeDisplay');
        const multiplierDisplay = document.getElementById('multiplierDisplay');
        const clickBtn = document.getElementById('clickBtn');
        const clickHint = document.getElementById('clickHint');
        const group1Grid = document.getElementById('group1Grid');
        const group2Grid = document.getElementById('group2Grid');
        const group3Grid = document.getElementById('group3Grid');
        const group4Grid = document.getElementById('group4Grid');
        const group2Block = document.getElementById('group2');
        const group3Block = document.getElementById('group3');
        const group4Block = document.getElementById('group4');
        const resetBtn = document.getElementById('resetBtn');
        const rebirthBtn = document.getElementById('rebirthBtn');
        const rebirthNeed = document.getElementById('rebirthNeed');
        const rebirthHave = document.getElementById('rebirthHave');
        const rebirthCondition = document.getElementById('rebirthCondition');

        // ===== ФУНКЦИИ =====
        function getG1Cost() {
            return Math.floor(state.g1.baseCost * Math.pow(state.g1.multiplier, state.g1.level));
        }
        function getG2Cost() {
            return Math.floor(state.g2.baseCost * Math.pow(state.g2.multiplier, state.g2.level));
        }
        function getClickerCost() {
            return Math.floor(state.g3.clicker.baseCost * Math.pow(state.g3.clicker.multiplier, state.g3.clicker.level));
        }
        function getRebirthCost() {
            return Math.floor(state.g3.rebirth.baseCost * Math.pow(state.g3.rebirth.multiplier, state.g3.rebirth.level));
        }
        function getG4Cost(key) {
            let g = state.g4[key];
            return Math.floor(g.baseCost * Math.pow(g.multiplier, g.level));
        }

        function getTotalUpgrades() {
            return state.g1.level + state.g2.level + state.g3.clicker.level + 
                   state.g4.power1.level + state.g4.power2.level + state.g4.power3.level;
        }

        function getTrueIncome() {
            let base = state.income;
            let g1bonus = state.g1.level * state.g1.power;
            let g2bonus = Math.pow(state.g2.power, state.g2.level);
            let g4bonus = state.g4.power1.level * state.g4.power1.power + 
                          state.g4.power2.level * state.g4.power2.power +
                          state.g4.power3.level * state.g4.power3.power;
            return Math.floor((base + g1bonus + g4bonus) * g2bonus * state.globalMultiplier * 10) / 10;
        }

        function getClickPower() {
            if (!state.clickUnlocked) return 0;
            let base = 2;
            let g1bonus = state.g1.level * state.g1.power;
            let g2bonus = Math.pow(state.g2.power, state.g2.level);
            let clickerBonus = state.g3.clicker.level * state.g3.clicker.power;
            let g4bonus = state.g4.power1.level * state.g4.power1.power + 
                          state.g4.power2.level * state.g4.power2.power +
                          state.g4.power3.level * state.g4.power3.power;
            return Math.floor((base + g1bonus + clickerBonus + g4bonus) * g2bonus * state.globalMultiplier);
        }

        // ===== ОБРАБОТЧИКИ КНОПОК (исправлено!) =====
        function buyG1() {
            let cost = getG1Cost();
            if (state.g1.level < state.g1.maxLevel && state.money >= cost) {
                state.money -= cost;
                state.g1.level++;
                if (getTotalUpgrades() >= 7) state.clickUnlocked = true;
                render();
            }
        }

        function buyG2() {
            let cost = getG2Cost();
            if (state.g2.level < state.g2.maxLevel && state.money >= cost) {
                state.money -= cost;
                state.g2.level++;
                if (getTotalUpgrades() >= 7) state.clickUnlocked = true;
                render();
            }
        }

        function buyClicker() {
            let cost = getClickerCost();
            if (state.money >= cost) {
                state.money -= cost;
                state.g3.clicker.level++;
                if (getTotalUpgrades() >= 7) state.clickUnlocked = true;
                render();
            }
        }

        function buyRebirthLevel() {
            let cost = getRebirthCost();
            if (state.clicks >= cost) {
                state.clicks -= cost;
                state.g3.rebirth.level++;
                state.globalMultiplier += 0.2;
                render();
            }
        }

        function buyG4(key) {
            let cost = getG4Cost(key);
            if (state.money >= cost) {
                state.money -= cost;
                state.g4[key].level++;
                if (getTotalUpgrades() >= 7) state.clickUnlocked = true;
                render();
            }
        }

        // ===== РЕНДЕР =====
        function render() {
            let total = getTotalUpgrades();
            let cost = getRebirthCost();
            let canRebirth = state.clicks >= cost && state.clickUnlocked && cost > 0;
            let clickPow = getClickPower();

            moneyDisplay.textContent = Math.floor(state.money);
            clicksDisplay.textContent = Math.floor(state.clicks);
            incomeDisplay.textContent = getTrueIncome();
            multiplierDisplay.textContent = state.globalMultiplier.toFixed(1);

            // Главная кнопка клика
            if (state.clickUnlocked && clickPow > 0) {
                clickBtn.className = 'click-btn';
                clickHint.textContent = `👆 +${clickPow} клик-валюты за нажатие`;
            } else if (!state.clickUnlocked) {
                clickBtn.className = 'click-btn disabled';
                clickHint.textContent = `🔒 откроется после 7 улучшений (сейчас ${total}/7)`;
            } else {
                clickBtn.className = 'click-btn disabled';
                clickHint.textContent = '⚡ сила клика 0';
            }

            // Условие ребёрта
            rebirthNeed.textContent = cost;
            rebirthHave.textContent = Math.floor(state.clicks);
            if (canRebirth) {
                rebirthBtn.className = 'reset-btn rebirth';
                rebirthCondition.style.color = '#7ae0a0';
            } else {
                rebirthBtn.className = 'reset-btn rebirth disabled';
                rebirthCondition.style.color = '#b3d9ee';
            }

            renderGroup1();
            
            if (state.g1.level >= state.g1.maxLevel) {
                group2Block.style.display = 'block';
                renderGroup2();
            } else {
                group2Block.style.display = 'none';
            }

            if (total >= 9) {
                group3Block.style.display = 'block';
                renderGroup3();
            } else {
                group3Block.style.display = 'none';
            }

            if (total >= 12) {
                group4Block.style.display = 'block';
                renderGroup4();
            } else {
                group4Block.style.display = 'none';
            }
        }

        function renderGroup1() {
            let html = '';
            let lv = state.g1.level;
            let max = state.g1.maxLevel;
            let cost = getG1Cost();

            for (let i = 0; i < max; i++) {
                let isActive = (i === lv && state.money >= cost && lv < max);
                let isBought = i < lv;
                let priceText = isBought ? '✔️' : (i === lv ? `💎 ${cost}` : '🔒');
                let name = isBought ? '✅' : '🔥';
                let desc = isBought ? 'куплено' : (i === lv ? `цена ${cost}💰` : 'заблокировано');
                let levelText = isBought ? `ур.${i+1}` : (i === lv ? `след. ${i+1}/${max}` : '');
                let disabledClass = isActive ? '' : 'disabled';
                
                html += `<div class="upgrade-card ${disabledClass}" data-action="g1">
                    <div class="name">${name} ×3</div>
                    <div class="desc">${desc}</div>
                    <div class="cost">${priceText}</div>
                    <div class="level">${levelText}</div>
                </div>`;
            }
            group1Grid.innerHTML = html;
            group1Grid.querySelectorAll('.upgrade-card:not(.disabled)').forEach(el => {
                el.addEventListener('click', buyG1);
            });
        }

        function renderGroup2() {
            let html = '';
            let lv = state.g2.level;
            let max = state.g2.maxLevel;
            let cost = getG2Cost();

            for (let i = 0; i < max; i++) {
                let isActive = (i === lv && state.money >= cost && lv < max);
                let isBought = i < lv;
                let priceText = isBought ? '✔️' : (i === lv ? `💎 ${cost}` : '🔒');
                let name = isBought ? '✅' : '🌀';
                let desc = isBought ? 'куплено' : (i === lv ? `цена ${cost}💰` : 'заблокировано');
                let levelText = isBought ? `ур.${i+1}` : (i === lv ? `след. ${i+1}/${max}` : '');
                let disabledClass = isActive ? '' : 'disabled';
                
                html += `<div class="upgrade-card ${disabledClass}" data-action="g2">
                    <div class="name">${name} ×1.5</div>
                    <div class="desc">${desc}</div>
                    <div class="cost">${priceText}</div>
                    <div class="level">${levelText}</div>
                </div>`;
            }
            group2Grid.innerHTML = html;
            group2Grid.querySelectorAll('.upgrade-card:not(.disabled)').forEach(el => {
                el.addEventListener('click', buyG2);
            });
        }

        function renderGroup3() {
            let html = '';
            
            let clv = state.g3.clicker.level;
            let ccost = getClickerCost();
            let ccan = state.money >= ccost;
            html += `<div class="upgrade-card ${ccan ? '' : 'disabled'}" data-action="clicker">
                <div class="name">👆 Усиление клика</div>
                <div class="desc">+${state.g3.clicker.power} к силе клика</div>
                <div class="cost">💎 ${ccost}</div>
                <div class="level">ур. ${clv}</div>
            </div>`;
            
            let rlv = state.g3.rebirth.level;
            let rcost = getRebirthCost();
            let rcan = state.clicks >= rcost;
            html += `<div class="upgrade-card ${rcan ? '' : 'disabled'}" data-action="rebirth">
                <div class="name">♻️ Ребёрт-уровень</div>
                <div class="desc">+0.2 к множителю</div>
                <div class="cost click-cost">👆 ${rcost}</div>
                <div class="level">ур. ${rlv}</div>
            </div>`;
            
            group3Grid.innerHTML = html;
            
            group3Grid.querySelectorAll('.upgrade-card:not(.disabled)').forEach(el => {
                let action = el.dataset.action;
                if (action === 'clicker') el.addEventListener('click', buyClicker);
                else if (action === 'rebirth') el.addEventListener('click', buyRebirthLevel);
            });
        }

        function renderGroup4() {
            let html = '';
            const keys = ['power1', 'power2', 'power3'];
            const names = ['💪 Мощь', '⚡ Ускорение', '🔥 Гипер'];
            
            keys.forEach((key, idx) => {
                let g = state.g4[key];
                let cost = getG4Cost(key);
                let canAfford = state.money >= cost;
                html += `<div class="upgrade-card ${canAfford ? '' : 'disabled'}" data-action="g4" data-key="${key}">
                    <div class="name">${names[idx]}</div>
                    <div class="desc">+${g.power} к доходу/клику</div>
                    <div class="cost">💎 ${cost}</div>
                    <div class="level">ур. ${g.level}</div>
                </div>`;
            });
            
            group4Grid.innerHTML = html;
            group4Grid.querySelectorAll('.upgrade-card:not(.disabled)').forEach(el => {
                let key = el.dataset.key;
                el.addEventListener('click', function() { buyG4(key); });
            });
        }

        // ===== КЛИК =====
        function handleClick() {
            if (!state.clickUnlocked) return;
            let power = getClickPower();
            if (power <= 0) return;
            state.clicks += power;
            render();
        }

        // ===== РЕБЁРТ =====
        function doRebirth() {
            let cost = getRebirthCost();
            if (state.clicks < cost || !state.clickUnlocked) return;
            if (!confirm(`Ребёрт за ${Math.floor(state.clicks)} 👆?\nВсё обнулится, множитель +0.2`)) return;
            
            state.clicks -= cost;
            state.globalMultiplier += 0.2;
            
            state.money = 0;
            state.income = 5;
            state.clickPower = 0;
            state.clickUnlocked = false;
            state.g1.level = 0;
            state.g2.level = 0;
            state.g3.clicker.level = 0;
            state.g3.rebirth.level = 0;
            state.g4.power1.level = 0;
            state.g4.power2.level = 0;
            state.g4.power3.level = 0;
            
            render();
        }

        // ===== СБРОС =====
        function resetGame() {
            if (!confirm('Сбросить прогресс? (множитель сохранится)')) return;
            state.money = 0;
            state.clicks = 0;
            state.income = 5;
            state.clickPower = 0;
            state.clickUnlocked = false;
            state.g1.level = 0;
            state.g2.level = 0;
            state.g3.clicker.level = 0;
            state.g3.rebirth.level = 0;
            state.g4.power1.level = 0;
            state.g4.power2.level = 0;
            state.g4.power3.level = 0;
            render();
        }

        // ===== ТИК =====
        function tick() {
            state.money += getTrueIncome();
            render();
        }

        // ===== СОБЫТИЯ =====
        clickBtn.addEventListener('click', handleClick);
        resetBtn.addEventListener('click', resetGame);
        rebirthBtn.addEventListener('click', doRebirth);

        // ===== СТАРТ =====
        render();
        setInterval(tick, 1000);
    })();
</script>
</body>
</html>

Game Source: Ребёрт — РАБОЧИЙ

Creator: AtomicScout38

Libraries: none

Complexity: complex (621 lines, 24.3 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: game-atomicscout38" to link back to the original. Then publish at arcadelab.ai/publish.