Ребёрт — РАБОЧИЙ
by AtomicScout38621 lines24.3 KB
<!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.