Загрузка данных
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Bank Tycoon: Империя Капитала</title>
<style>
@import url('https://fonts.googleapis.com/css2?family=Montserrat:wght@400;600;800&display=swap');
:root {
--bg-color: #0f172a;
--panel-bg: #1e293b;
--text-color: #f8fafc;
--text-muted: #94a3b8;
--primary: #3b82f6; /* Изменяется при выборе банка */
--primary-hover: #2563eb;
--danger: #ef4444;
--success: #10b981;
}
* {
box-sizing: border-box;
margin: 0;
padding: 0;
user-select: none;
}
body {
font-family: 'Montserrat', sans-serif;
background-color: var(--bg-color);
color: var(--text-color);
min-height: 100vh;
display: flex;
flex-direction: column;
overflow-x: hidden;
}
/* Экран выбора банка */
#setup-screen {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100vh;
text-align: center;
}
.bank-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 20px;
margin-top: 40px;
}
.bank-card {
background: var(--panel-bg);
padding: 30px;
border-radius: 16px;
cursor: pointer;
transition: transform 0.2s, box-shadow 0.2s;
border: 2px solid transparent;
}
.bank-card:hover {
transform: translateY(-5px);
}
.bank-sber { border-color: #10b981; }
.bank-tbank { border-color: #eab308; }
.bank-alfa { border-color: #ef4444; }
.bank-vtb { border-color: #3b82f6; }
.bank-sber:hover { box-shadow: 0 10px 20px rgba(16, 185, 129, 0.2); }
.bank-tbank:hover { box-shadow: 0 10px 20px rgba(234, 179, 8, 0.2); }
.bank-alfa:hover { box-shadow: 0 10px 20px rgba(239, 68, 68, 0.2); }
.bank-vtb:hover { box-shadow: 0 10px 20px rgba(59, 130, 246, 0.2); }
/* Игровой экран */
#game-screen {
display: none;
flex-direction: column;
height: 100vh;
}
header {
background: var(--panel-bg);
padding: 20px 40px;
display: flex;
justify-content: space-between;
align-items: center;
border-bottom: 3px solid var(--primary);
box-shadow: 0 4px 15px rgba(0,0,0,0.3);
z-index: 10;
}
.stats .balance {
font-size: 2.5rem;
font-weight: 800;
color: var(--primary);
text-shadow: 0 0 10px rgba(255,255,255,0.1);
}
.stats .income {
font-size: 1.2rem;
color: var(--text-muted);
}
main {
display: flex;
flex: 1;
overflow: hidden;
}
/* Левая панель - кликер */
.clicker-panel {
flex: 1;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
border-right: 1px solid #334155;
padding: 20px;
}
.click-btn {
background: var(--primary);
color: white;
border: none;
width: 250px;
height: 250px;
border-radius: 50%;
font-size: 1.8rem;
font-weight: 800;
cursor: pointer;
box-shadow: 0 10px 30px rgba(0,0,0,0.5), inset 0 -5px 15px rgba(0,0,0,0.2);
transition: transform 0.1s, box-shadow 0.1s;
}
.click-btn:active {
transform: scale(0.95);
box-shadow: 0 5px 15px rgba(0,0,0,0.5), inset 0 -2px 5px rgba(0,0,0,0.2);
}
/* Правая панель - инвестиции */
.investments-panel {
flex: 1.5;
padding: 30px;
overflow-y: auto;
background: #0b1120;
}
.investments-panel h2 {
margin-bottom: 20px;
font-size: 1.8rem;
}
.inv-card {
background: var(--panel-bg);
border-radius: 12px;
padding: 20px;
margin-bottom: 15px;
display: flex;
justify-content: space-between;
align-items: center;
transition: background 0.3s;
border-left: 4px solid #334155;
}
.inv-card.affordable {
border-left-color: var(--primary);
}
.inv-card.affordable:hover {
background: #273549;
}
.inv-info h3 {
font-size: 1.2rem;
margin-bottom: 5px;
}
.inv-info p {
font-size: 0.9rem;
color: var(--text-muted);
}
.inv-stats {
text-align: right;
display: flex;
align-items: center;
gap: 20px;
}
.inv-count {
font-size: 2rem;
font-weight: 800;
color: var(--primary);
opacity: 0.5;
}
.buy-btn {
background: transparent;
color: var(--text-color);
border: 2px solid #334155;
padding: 10px 20px;
border-radius: 8px;
font-weight: 600;
cursor: not-allowed;
transition: all 0.3s;
}
.inv-card.affordable .buy-btn {
border-color: var(--primary);
color: var(--primary);
cursor: pointer;
}
.inv-card.affordable .buy-btn:hover {
background: var(--primary);
color: white;
}
/* Скроллбар */
::-webkit-scrollbar { width: 8px; }
::-webkit-scrollbar-track { background: var(--bg-color); }
::-webkit-scrollbar-thumb { background: #334155; border-radius: 4px; }
::-webkit-scrollbar-thumb:hover { background: var(--primary); }
</style>
</head>
<body>
<!-- ЭКРАН ВЫБОРА БАНКА -->
<div id="setup-screen">
<h1>Выберите свой банк</h1>
<p style="color: var(--text-muted); margin-top: 10px;">С этого начнется ваша финансовая империя</p>
<div class="bank-grid">
<div class="bank-card bank-sber" onclick="startGame('Сбер', '#10b981')">
<h2 style="color: #10b981;">Сбер</h2>
<p>Надежно. Традиционно.</p>
</div>
<div class="bank-card bank-tbank" onclick="startGame('Т-Банк', '#eab308')">
<h2 style="color: #eab308;">Т-Банк</h2>
<p>Технологично. Быстро.</p>
</div>
<div class="bank-card bank-alfa" onclick="startGame('Альфа', '#ef4444')">
<h2 style="color: #ef4444;">Альфа</h2>
<p>Дерзко. Прибыльно.</p>
</div>
<div class="bank-card bank-vtb" onclick="startGame('ВТБ', '#3b82f6')">
<h2 style="color: #3b82f6;">ВТБ</h2>
<p>Масштабно. Глобально.</p>
</div>
</div>
</div>
<!-- ИГРОВОЙ ЭКРАН -->
<div id="game-screen">
<header>
<div class="bank-identity">
<h2 id="ui-bank-name">Банк</h2>
<p style="color: var(--text-muted); font-size: 0.8rem;">Управляющий директор</p>
</div>
<div class="stats" style="text-align: right;">
<div class="balance"><span id="ui-balance">0</span> ₽</div>
<div class="income">+<span id="ui-income">0</span> ₽ / сек</div>
</div>
</header>
<main>
<div class="clicker-panel">
<button class="click-btn" id="work-btn" onclick="manualClick()">
Выдать<br>кредит
</button>
<p style="margin-top: 20px; color: var(--text-muted);">Клик: +<span id="ui-click-power">1</span> ₽</p>
</div>
<div class="investments-panel">
<h2>Инвестиционный портфель</h2>
<div id="investments-container">
<!-- Карточки инвестиций генерируются через JS -->
</div>
</div>
</main>
</div>
<script>
// Состояние игры
const game = {
bankName: '',
balance: 0,
incomePerSec: 0,
clickPower: 1,
lastTick: Date.now()
};
// База данных инвестиций
const investments = [
{ id: 0, name: "Вклады физ. лиц", desc: "Привлекаем депозиты населения.", baseCost: 15, baseIncome: 1, count: 0 },
{ id: 1, name: "Кредитные карты", desc: "Высокий процент, скрытые комиссии.", baseCost: 100, baseIncome: 5, count: 0 },
{ id: 2, name: "ОФЗ (Облигации)", desc: "Надежные государственные бумаги.", baseCost: 1100, baseIncome: 45, count: 0 },
{ id: 3, name: "IT-Стартапы", desc: "Рискованно, но с огромным потенциалом.", baseCost: 12000, baseIncome: 400, count: 0 },
{ id: 4, name: "Коммерческая недвижимость", desc: "Сдача элитных офисов в Москве.", baseCost: 130000, baseIncome: 3500, count: 0 },
{ id: 5, name: "Госконтракты", desc: "Крупные тендеры и монополии.", baseCost: 1400000, baseIncome: 25000, count: 0 },
{ id: 6, name: "Поглощение конкурентов", desc: "Скупаем другие банки целиком.", baseCost: 20000000, baseIncome: 250000, count: 0 }
];
const COST_MULTIPLIER = 1.15; // Насколько дорожает покупка с каждым разом
// Форматирование чисел (например: 1 000 000)
function formatNumber(num) {
return Math.floor(num).toString().replace(/\B(?=(\d{3})+(?!\d))/g, " ");
}
// Вычисление текущей цены апгрейда
function getCost(inv) {
return Math.floor(inv.baseCost * Math.pow(COST_MULTIPLIER, inv.count));
}
// Инициализация игры
function startGame(name, color) {
game.bankName = name;
// Устанавливаем цвета
document.documentElement.style.setProperty('--primary', color);
// Скрываем меню, показываем игру
document.getElementById('setup-screen').style.display = 'none';
document.getElementById('game-screen').style.display = 'flex';
document.getElementById('ui-bank-name').innerText = name;
renderInvestments();
// Запускаем игровой цикл (30 кадров в секунду для плавности)
setInterval(gameLoop, 1000 / 30);
// Отдельный цикл для обновления интерфейса кнопок
setInterval(updateUI, 100);
}
// Ручной клик
function manualClick() {
game.balance += game.clickPower;
updateHeader();
}
// Покупка инвестиции
function buy(id) {
const inv = investments[id];
const cost = getCost(inv);
if (game.balance >= cost) {
game.balance -= cost;
inv.count++;
// Пересчет общего дохода
recalculateIncome();
// Клик становится сильнее с ростом дохода (1% от пассивного дохода)
game.clickPower = 1 + Math.floor(game.incomePerSec * 0.01);
renderInvestments(); // Перерисовываем список
updateHeader();
}
}
// Пересчет дохода
function recalculateIncome() {
let total = 0;
investments.forEach(inv => {
total += inv.count * inv.baseIncome;
});
game.incomePerSec = total;
}
// Главный цикл (начисление денег)
function gameLoop() {
const now = Date.now();
const dt = (now - game.lastTick) / 1000; // Прошедшее время в секундах
game.lastTick = now;
if (game.incomePerSec > 0) {
game.balance += game.incomePerSec * dt;
updateHeader();
}
}
// Обновление шапки
function updateHeader() {
document.getElementById('ui-balance').innerText = formatNumber(game.balance);
document.getElementById('ui-income').innerText = formatNumber(game.incomePerSec);
document.getElementById('ui-click-power').innerText = formatNumber(game.clickPower);
}
// Проверка доступности кнопок
function updateUI() {
investments.forEach(inv => {
const card = document.getElementById(`inv-card-${inv.id}`);
const btn = document.getElementById(`inv-btn-${inv.id}`);
if (!card || !btn) return;
const cost = getCost(inv);
if (game.balance >= cost) {
card.classList.add('affordable');
btn.innerText = `Купить: ${formatNumber(cost)} ₽`;
} else {
card.classList.remove('affordable');
btn.innerText = `${formatNumber(cost)} ₽`;
}
});
}
// Отрисовка карточек
function renderInvestments() {
const container = document.getElementById('investments-container');
container.innerHTML = '';
investments.forEach(inv => {
const cost = getCost(inv);
const html = `
<div class="inv-card" id="inv-card-${inv.id}">
<div class="inv-info">
<h3>${inv.name}</h3>
<p>${inv.desc}</p>
<p style="color: var(--success); margin-top: 5px;">+${formatNumber(inv.baseIncome)} ₽/сек</p>
</div>
<div class="inv-stats">
<div class="inv-count">${inv.count}</div>
<button class="buy-btn" id="inv-btn-${inv.id}" onclick="buy(${inv.id})">
${formatNumber(cost)} ₽
</button>
</div>
</div>
`;
container.innerHTML += html;
});
updateUI();
}
</script>
</body>
</html>