Наверх

Архивная

Mentos

Я СОЗДАЛ СВОЮ ИГРУ | by Mentos

Какая-то нездоровая тематика с вашим программированием и играми пошла..так почему бы к нему не присоединиться?

Mentos present'a..

★ Я СОЗДАЛ СВОЮ ИГРУ ★

Да. Такое резкое заявление не может остаться не замеченным и грубо так говоря неоставленным без вашего внимания. Good day to all and take it easy, as they say! By Mentos!

Под этим спойлером ниже, скрывается HTML-код (открытый браузерный код, который самый простой в освоении на данный момент). НЕ ОТКРЫВАЙТЕ ЭТОТ КОД, ПРОСТО ТАК, ЧТОБЫ НЕ ЛИСТАТЬ ВНИЗ ОЧЕНЬ МНОГО ТЕКСТА. 

КОД: 

<!DOCTYPE html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes, maximum-scale=1.5">
    <title>Formula Manager 2026 – F1 & Formula E</title>
    <style>
        * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; }
        body { background: linear-gradient(135deg, #0a0f1e 0%, #1a1f2e 100%); min-height: 100vh; display: flex; justify-content: center; align-items: center; padding: 20px; }
        .app-container { max-width: 960px; width: 100%; }
        .main-menu, .game-container { background: rgba(20, 25, 40, 0.95); backdrop-filter: blur(20px); border-radius: 32px; padding: 24px; box-shadow: 0 25px 50px -12px rgba(0,0,0,0.8); color: #e0e0e0; margin-bottom: 20px; }
        .main-menu h2 { text-align: center; margin-bottom: 24px; font-size: 2rem; }
        .menu-buttons { display: flex; gap: 16px; justify-content: center; flex-wrap: wrap; }
        .menu-btn { border: none; color: white; padding: 20px 30px; border-radius: 24px; font-size: 1.5rem; font-weight: 700; cursor: pointer; transition: 0.2s; width: 280px; text-align: center; }
        .menu-btn.f1 { background: #e10600; } .menu-btn.f1:hover { background: #ff1a1a; }
        .menu-btn.fe { background: #0066cc; } .menu-btn.fe:hover { background: #0080ff; }
        .game-wrapper { display: none; }
        .game-wrapper.active { display: block; }
        .back-btn { border: none; color: white; padding: 10px 18px; border-radius: 30px; font-weight: 600; cursor: pointer; margin-bottom: 16px; }
        .back-btn.f1 { background: #e10600; } .back-btn.fe { background: #0066cc; }

        .game-container h1 { font-size: 2rem; font-weight: 700; text-align: center; margin-bottom: 8px; }
        .game-container .subtitle { text-align: center; font-size: 0.9rem; color: #8a8f9a; margin-bottom: 20px; border-bottom: 1px solid #2a2f3a; padding-bottom: 16px; }
        .single-video { text-align: center; margin-bottom: 20px; }
        .single-video iframe { border-radius: 16px; max-width: 100%; display: none; }
        .video-link { display: inline-flex; align-items: center; justify-content: center; gap: 8px; background: #e10600; color: white; text-decoration: none; font-weight: 600; padding: 10px 24px; border-radius: 30px; font-size: 0.95rem; transition: background 0.2s; }
        .video-link:hover { background: #ff1a1a; }
        .team-selector { background: #0d1117; border-radius: 20px; padding: 20px; margin-bottom: 20px; border: 1px solid #2a2f3a; }
        select { width: 100%; padding: 12px; background: #161b25; border: 1px solid #2a2f3a; color: white; border-radius: 12px; font-size: 1rem; margin-bottom: 10px; }
        .team-preview { background: #161b25; border-radius: 16px; padding: 16px; margin-top: 12px; border: 1px solid #2a2f3a; display: none; }
        .team-preview.active { display: block; }
        .stats-panel { display: flex; justify-content: space-between; background: #0d1117; border-radius: 20px; padding: 16px 20px; margin-bottom: 20px; border: 1px solid #2a2f3a; flex-wrap: wrap; }
        .stat { text-align: center; min-width: 80px; }
        .stat-value { font-size: 1.8rem; font-weight: 700; color: #fff; }
        .stat-label { font-size: 0.75rem; text-transform: uppercase; letter-spacing: 0.5px; color: #8a8f9a; }
        .money { color: #f0b90b; } .money.negative { color: #ff6b6b; }
        .tabs { display: flex; gap: 8px; margin-bottom: 20px; flex-wrap: wrap; }
        .tab { flex: 1; background: #161b25; border: 1px solid #2a2f3a; color: #8a8f9a; padding: 12px 8px; border-radius: 16px; font-weight: 600; font-size: 0.9rem; cursor: pointer; transition: all 0.2s; text-align: center; min-width: 70px; }
        .tab.active { color: white; }
        .view { display: none; animation: fade 0.2s ease; } .view.active { display: block; }
        @keyframes fade { from { opacity: 0.3; } to { opacity: 1; } }
        .card { background: #161b25; border-radius: 20px; padding: 18px; margin-bottom: 16px; border: 1px solid #2a2f3a; }
        .card h3 { font-size: 1.1rem; margin-bottom: 14px; display: flex; align-items: center; gap: 8px; }
        .pilot-row, .upgrade-row { display: flex; justify-content: space-between; align-items: center; margin-bottom: 14px; }
        .pilot-name { font-weight: 700; } .pilot-skill { font-size: 0.85rem; color: #a0a5b0; }
        button { background: #2a2f3a; border: none; color: white; padding: 10px 18px; border-radius: 30px; font-weight: 600; font-size: 0.85rem; cursor: pointer; transition: 0.2s; border: 1px solid #3a3f4a; }
        button:hover { background: #3a3f4a; } button.primary { font-weight: 700; } button:disabled { opacity: 0.4; pointer-events: none; }
        .progress-bg { height: 8px; background: #0d1117; border-radius: 10px; margin: 6px 0 12px; overflow: hidden; }
        .progress-fill { height: 100%; width: 0%; border-radius: 10px; transition: width 0.3s; }
        .race-log { background: #0d1117; border-radius: 16px; padding: 12px; max-height: 250px; overflow-y: auto; font-size: 0.85rem; color: #b0b5c0; margin: 12px 0; }
        table { width: 100%; border-collapse: collapse; margin: 10px 0; font-size: 0.85rem; }
        th, td { padding: 6px 8px; border-bottom: 1px solid #2a2f3a; text-align: left; } th { color: #8a8f9a; font-weight: 600; }
        .race-info { font-size: 0.9rem; color: #a0a5b0; margin-top: 6px; }
        .button-group { display: flex; gap: 10px; margin-top: 12px; } .button-group button { flex: 1; }
        .modal { display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.7); justify-content: center; align-items: center; z-index: 100; }
        .modal.active { display: flex; }
        .modal-content { background: #1a1f2e; border-radius: 24px; padding: 20px; max-width: 700px; width: 90%; max-height: 80vh; overflow-y: auto; color: #e0e0e0; border: 1px solid #2a2f3a; }
        .modal-content h2 { margin-bottom: 12px; }
        .modal-content button { margin-top: 12px; }

        .f1-theme .tab.active { background: #e10600; border-color: #e10600; }
        .f1-theme button.primary { background: #e10600; border-color: #e10600; }
        .f1-theme .progress-fill { background: #e10600; }
        .f1-theme h1 { background: linear-gradient(to right, #e10600, #ff6b6b); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; }

        .fe-theme .tab.active { background: #0066cc; border-color: #0066cc; }
        .fe-theme button.primary { background: #0066cc; border-color: #0066cc; }
        .fe-theme .progress-fill { background: #0066cc; }
        .fe-theme h1 { background: linear-gradient(to right, #0066cc, #00aaff); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; }
    </style>
</head>
<body>
<div class="app-container" id="appContainer">
    <div id="mainMenu" class="main-menu">
        <h2>🏁 Formula Manager 2026</h2>
        <div class="menu-buttons">
            <button class="menu-btn f1" id="playF1Btn">🏎️ F1 Manager 2026</button>
            <button class="menu-btn fe" id="playFEBtn">⚡ Formula E 2025/26</button>
        </div>
    </div>

    <div id="f1Container" class="game-wrapper">
        <button class="back-btn f1" id="backFromF1">↩️ Главное меню</button>
        <div id="f1Root" class="f1-theme game-container"></div>
    </div>

    <div id="feContainer" class="game-wrapper">
        <button class="back-btn fe" id="backFromFE">↩️ Главное меню</button>
        <div id="feRoot" class="fe-theme game-container"></div>
    </div>
</div>

<script>
    (function() {
        function hideAllGames() {
            document.getElementById('f1Container').classList.remove('active');
            document.getElementById('feContainer').classList.remove('active');
            document.getElementById('mainMenu').style.display = 'block';
        }

        class RacingGame {
            constructor(rootId, theme, data) {
                this.root = document.getElementById(rootId);
                this.theme = theme;
                this.data = data;
                this.state = {
                    playerTeamIndex: -1,
                    isSpectator: true,
                    teams: JSON.parse(JSON.stringify(data.teams)),
                    budget: 0,
                    points: 0,
                    currentRace: 1,
                    upgradeCost: 8,
                    raceInProgress: false,
                    standings: [],
                    driverStandings: [],
                    raceHistory: [],
                    qualifyingGrid: []
                };
                this.init();
            }

            init() {
                this.renderStaticHTML();
                this.attachEvents();
                this.resetStandings();
                this.updateUI();
            }

            renderStaticHTML() {
                this.root.innerHTML = `
                    <h1>${this.data.title}</h1>
                    <div class="subtitle">${this.data.subtitle}</div>
                    ${this.theme === 'f1' ? `
                    <div class="single-video">
                        <iframe src="https://vkvideo.ru/video_ext.php?oid=-90428826&id=456246874&hd=2" width="100%" height="300" frameborder="0" allow="autoplay; encrypted-media; fullscreen; picture-in-picture" allowfullscreen onload="this.style.display='block'; this.nextElementSibling.style.display='none';" onerror="this.style.display='none'; this.nextElementSibling.style.display='inline-flex';"></iframe>
                        <a class="video-link" href="https://vkvideo.ru/video-90428826_456246874" target="_blank" style="display: inline-flex;">▶️ Открыть видео ВК</a>
                    </div>` : ''}
                    <div class="team-selector" id="teamSelectPanel">
                        <label style="color:#a0a5b0; margin-bottom:6px; display:block;">Выберите команду или режим наблюдателя:</label>
                        <select id="teamSelect"><option value="">-- Выберите команду --</option></select>
                        <div id="teamPreview" class="team-preview">
                            <h3 style="margin:0 0 12px; font-size:1rem;" id="previewConstructor"></h3>
                            <div class="pilot-row"><span class="pilot-name" id="previewPilot1"></span><span class="pilot-skill" id="previewPilot1Skill"></span></div>
                            <div class="pilot-row"><span class="pilot-name" id="previewPilot2"></span><span class="pilot-skill" id="previewPilot2Skill"></span></div>
                            <div id="previewCarStats" style="margin: 10px 0;"></div>
                            <div style="font-weight:600; margin-top:8px;">Бюджет: <span id="previewBudget" class="money"></span> млн $</div>
                        </div>
                        <div class="button-group">
                            <button id="startCareerBtn" class="primary">🚀 Начать карьеру</button>
                            <button id="spectatorBtn" class="primary" style="background:#4a4f5a; border-color:#4a4f5a;">👁️ Режим наблюдателя</button>
                        </div>
                    </div>
                    <div id="gameUI" style="display:none;">
                        <div class="stats-panel" id="spectatorPanel" style="display: flex;">
                            <div class="stat"><span class="stat-value" id="raceDisplay">1/${this.data.totalRaces}</span><div class="stat-label">Этап</div></div>
                            <div class="stat"><span class="stat-value" style="color:${this.theme === 'f1' ? '#e10600' : '#0066cc'};">👁️</span><div class="stat-label">Наблюдатель</div></div>
                        </div>
                        <div class="stats-panel" id="managerPanel" style="display: none;">
                            <div class="stat"><span class="stat-value money" id="budgetDisplay">0</span><div class="stat-label">Млн $</div></div>
                            <div class="stat"><span class="stat-value" id="pointsDisplay">0</span><div class="stat-label">Очки команды</div></div>
                            <div class="stat"><span class="stat-value" id="raceDisplay2">1/${this.data.totalRaces}</span><div class="stat-label">Этап</div></div>
                            <div class="stat"><span class="stat-value" id="teamNameDisplay">-</span><div class="stat-label">Команда</div></div>
                        </div>
                        <div class="tabs" id="tabsContainer"></div>
                        <div id="teamView" class="view">
                            <div class="card"><h3>🏆 Пилоты</h3><div id="pilot1Info" class="pilot-row"></div><div id="pilot2Info" class="pilot-row"></div><div style="margin-top:12px; font-size:0.85rem; color:#8a8f9a;">Свободные агенты (3 млн за контракт)</div></div>
                            <div class="card"><h3>⚙️ Характеристики машины</h3><div id="carStats"></div></div>
                        </div>
                        <div id="upgradesView" class="view">
                            <div class="card"><h3>📈 Улучшения (8 млн $)</h3><div id="upgradeList"></div></div>
                        </div>
                        <div id="raceView" class="view">
                            <div class="card">
                                <h3>📍 <span id="grandPrixName"></span></h3>
                                <div class="race-info"><div>🏟️ <span id="trackName"></span></div><div>📅 <span id="raceDate"></span></div><div>🔄 Кругов: <span id="raceLaps"></span></div></div>
                                <button id="startRaceBtn" class="primary" style="width:100%; margin-top:16px;">🚦 Старт уик-энда</button>
                                <div id="raceProgress" style="display:none; margin-top:16px;"><div class="progress-bg"><div id="raceProgressBar" class="progress-fill" style="width:0%"></div></div><div id="raceStatusText" class="stat-label" style="text-align:center;">Квалификация...</div></div>
                                <div id="raceLog" class="race-log" style="display:none;"></div>
                                <div id="raceResult" style="margin-top:12px;"></div>
                            </div>
                        </div>
                        <div id="standingsView" class="view"><div class="card"><h3>🏆 Кубок конструкторов</h3><div id="standingsTable"></div></div></div>
                        <div id="driversView" class="view"><div class="card"><h3>👤 Личный зачёт пилотов</h3><div id="driversTable"></div></div></div>
                        <div id="historyView" class="view">
                            <div class="card"><h3>📋 Результаты гонок</h3><select id="historySelect" style="margin-bottom:15px;"><option value="">-- Выберите этап --</option></select><div id="historyTable"></div></div>
                        </div>
                        <div id="newsView" class="view">
                            <div class="card">
                                <h3>📰 Новости</h3>
                                <button id="refreshNewsBtn" class="primary" style="margin-bottom:12px;">🔄 Обновить новости</button>
                                <div id="newsFeed"></div>
                            </div>
                        </div>
                    </div>
                    <div id="statsModal" class="modal">
                        <div class="modal-content">
                            <h2>🏁 <span id="modalRaceName"></span></h2>
                            <div id="modalTable"></div>
                            <button id="closeModalBtn" class="primary">Закрыть</button>
                        </div>
                    </div>
                `;
                const select = this.root.querySelector('#teamSelect');
                this.data.teams.forEach((team, idx) => {
                    const opt = document.createElement('option');
                    opt.value = idx; opt.textContent = team.name;
                    select.appendChild(opt);
                });
            }

            attachEvents() {
                const root = this.root;
                root.querySelector('#teamSelect').addEventListener('change', (e) => this.showTeamPreview(parseInt(e.target.value)));
                root.querySelector('#startCareerBtn').addEventListener('click', () => {
                    const idx = parseInt(root.querySelector('#teamSelect').value);
                    if (isNaN(idx) || idx < 0) { alert('Выберите команду!'); return; }
                    this.setMode(true, idx);
                });
                root.querySelector('#spectatorBtn').addEventListener('click', () => this.setMode(false));
                root.querySelector('#startRaceBtn').addEventListener('click', () => this.simulateRace());
                root.querySelector('#closeModalBtn').addEventListener('click', () => root.querySelector('#statsModal').classList.remove('active'));
                root.querySelector('#historySelect').addEventListener('change', (e) => this.showHistoryTable(e.target.value));
                root.querySelector('#refreshNewsBtn').addEventListener('click', () => this.generateNews());
                root.addEventListener('click', (e) => {
                    if (e.target.classList.contains('hire-btn')) this.hirePilot(parseInt(e.target.dataset.pilotIndex));
                    if (e.target.classList.contains('upgrade-btn')) this.applyUpgrade(e.target.dataset.key);
                });
                window.addEventListener('click', (e) => {
                    if (e.target === root.querySelector('#statsModal')) root.querySelector('#statsModal').classList.remove('active');
                });
            }

            generateNews() {
                const newsDiv = this.root.querySelector('#newsFeed');
                const templates = [
                    "{driver} из команды {team} одержал победу в последнем Гран-при!",
                    "Слухи: {driver} может перейти в {team2} в следующем сезоне.",
                    "Обзор: {team} представила обновлённую аэродинамику на этапе в {location}.",
                    "Контракт: {driver} продлил соглашение с {team} на 2 года.",
                    "Технический сбой: у {driver} отказал двигатель на прогревочном круге.",
                    "Погода внесла коррективы: гонка в {location} прошла под дождём.",
                    "Интервью: {driver} заявил, что машина стала быстрее после обновлений.",
                    "{team} объявила о партнёрстве с новым спонсором.",
                    "Столкновение: {driver} и {driver2} сошли с трассы на первом круге.",
                    "Квалификация: {driver} завоевал поул-позицию в {grandPrix}."
                ];
                const drivers = this.state.teams.flatMap(t => t.drivers.map(d => d.name));
                const teams = this.state.teams.map(t => t.name);
                const locations = this.data.schedule.map(s => s.location);

                let html = '';
                for (let i = 0; i < 5; i++) {
                    const template = templates[Math.floor(Math.random() * templates.length)];
                    let news = template
                        .replace(/{driver}/g, () => drivers[Math.floor(Math.random() * drivers.length)])
                        .replace(/{driver2}/g, () => drivers[Math.floor(Math.random() * drivers.length)])
                        .replace(/{team}/g, () => teams[Math.floor(Math.random() * teams.length)])
                        .replace(/{team2}/g, () => teams[Math.floor(Math.random() * teams.length)])
                        .replace(/{location}/g, () => locations[Math.floor(Math.random() * locations.length)])
                        .replace(/{grandPrix}/g, () => this.data.schedule[Math.floor(Math.random() * this.data.schedule.length)].grandPrix);
                    html += `<div class="card" style="margin-bottom:8px; padding:10px;">${news}</div>`;
                }
                newsDiv.innerHTML = html;
            }

            showTeamPreview(index) {
                const previewDiv = this.root.querySelector('#teamPreview');
                if (isNaN(index) || index < 0) { previewDiv.classList.remove('active'); return; }
                const team = this.data.teams[index];
                this.root.querySelector('#previewConstructor').textContent = team.constructor;
                this.root.querySelector('#previewPilot1').textContent = team.drivers[0].name;
                this.root.querySelector('#previewPilot1Skill').textContent = `Мастерство: ${team.drivers[0].skill}`;
                this.root.querySelector('#previewPilot2').textContent = team.drivers[1].name;
                this.root.querySelector('#previewPilot2Skill').textContent = `Мастерство: ${team.drivers[1].skill}`;
                const carDiv = this.root.querySelector('#previewCarStats');
                carDiv.innerHTML = '';
                ['Аэродинамика','Двигатель','Шасси','Надёжность'].forEach((label,i) => {
                    const keys = ['aero','engine','chassis','reliability'];
                    const val = team.car[keys[i]];
                    carDiv.innerHTML += `<div style="margin-bottom:6px;"><div style="display:flex;justify-content:space-between;"><span>${label}</span><span>${val}</span></div><div class="progress-bg"><div class="progress-fill" style="width:${val}%;"></div></div></div>`;
                });
                this.root.querySelector('#previewBudget').textContent = team.budget;
                previewDiv.classList.add('active');
            }

            resetStandings() {
                this.state.standings = this.state.teams.map(t => ({ teamName: t.name, points: 0 }));
                this.state.driverStandings = [];
                this.state.teams.forEach(t => t.drivers.forEach(d => this.state.driverStandings.push({ name: d.name, teamName: t.name, points: 0 })));
                this.state.raceHistory = [];
                this.state.qualifyingGrid = [];
            }

            setMode(careerMode, teamIndex = -1) {
                this.state.isSpectator = !careerMode;
                this.state.playerTeamIndex = careerMode ? teamIndex : -1;
                this.state.budget = careerMode ? this.data.teams[teamIndex].budget : 0;
                this.state.points = 0;
                this.state.currentRace = 1;
                this.resetStandings();
                this.root.querySelector('#teamSelectPanel').style.display = 'none';
                this.root.querySelector('#gameUI').style.display = 'block';

                if (careerMode) {
                    this.root.querySelector('#managerPanel').style.display = 'flex';
                    this.root.querySelector('#spectatorPanel').style.display = 'none';
                    this.root.querySelector('#teamNameDisplay').textContent = this.data.teams[teamIndex].constructor;
                    this.root.querySelector('#tabsContainer').innerHTML = `
                        <div class="tab active" data-view="team">👥 Команда</div>
                        <div class="tab" data-view="upgrades">🔧 Разработка</div>
                        <div class="tab" data-view="race">🏁 Гонка</div>
                        <div class="tab" data-view="standings">📊 Команды</div>
                        <div class="tab" data-view="drivers">👤 Пилоты</div>
                        <div class="tab" data-view="history">📋 Гонки</div>
                        <div class="tab" data-view="news">📰 Новости</div>
                    `;
                    this.showView('team');
                } else {
                    this.root.querySelector('#managerPanel').style.display = 'none';
                    this.root.querySelector('#spectatorPanel').style.display = 'flex';
                    this.root.querySelector('#teamView').style.display = 'none';
                    this.root.querySelector('#upgradesView').style.display = 'none';
                    this.root.querySelector('#tabsContainer').innerHTML = `
                        <div class="tab active" data-view="race">🏁 Гонка</div>
                        <div class="tab" data-view="standings">📊 Команды</div>
                        <div class="tab" data-view="drivers">👤 Пилоты</div>
                        <div class="tab" data-view="history">📋 Гонки</div>
                        <div class="tab" data-view="news">📰 Новости</div>
                    `;
                    this.showView('race');
                }
                this.attachTabEvents();
                this.updateUI();
            }

            attachTabEvents() {
                this.root.querySelectorAll('.tab').forEach(tab => {
                    tab.addEventListener('click', () => {
                        this.root.querySelectorAll('.tab').forEach(t => t.classList.remove('active'));
                        tab.classList.add('active');
                        this.showView(tab.dataset.view);
                    });
                });
            }

            showView(viewName) {
                const views = this.root.querySelectorAll('.view');
                views.forEach(v => v.classList.remove('active'));
                const target = this.root.querySelector(`#${viewName}View`);
                if (target) {
                    target.classList.add('active');
                    if (viewName === 'history') this.updateHistoryView();
                    if (viewName === 'news') this.generateNews();
                }
            }

            updateUI() {
                const root = this.root;
                root.querySelector('#raceDisplay').textContent = `${this.state.currentRace}/${this.data.totalRaces}`;
                const rd2 = root.querySelector('#raceDisplay2');
                if (rd2) rd2.textContent = `${this.state.currentRace}/${this.data.totalRaces}`;
                if (this.state.currentRace <= this.data.totalRaces) {
                    const gp = this.data.schedule[this.state.currentRace-1];
                    root.querySelector('#grandPrixName').textContent = gp.grandPrix;
                    root.querySelector('#trackName').textContent = gp.track ? `${gp.track} (${gp.location})` : gp.location;
                    root.querySelector('#raceDate').textContent = gp.date || '';
                    root.querySelector('#raceLaps').textContent = gp.laps;
                }
                if (!this.state.isSpectator && this.state.playerTeamIndex !== -1) {
                    const team = this.state.teams[this.state.playerTeamIndex];
                    root.querySelector('#budgetDisplay').textContent = this.state.budget;
                    root.querySelector('#pointsDisplay').textContent = this.state.points;
                    this.renderPilot('pilot1Info', team.drivers[0], 0);
                    this.renderPilot('pilot2Info', team.drivers[1], 1);
                    const carDiv = root.querySelector('#carStats');
                    carDiv.innerHTML = '';
                    ['Аэродинамика','Двигатель','Шасси','Надёжность'].forEach((label,i) => {
                        const keys = ['aero','engine','chassis','reliability'];
                        const val = team.car[keys[i]];
                        carDiv.innerHTML += `<div style="margin-bottom:10px;"><div style="display:flex;justify-content:space-between;"><span>${label}</span><span>${val}</span></div><div class="progress-bg"><div class="progress-fill" style="width:${val}%;"></div></div></div>`;
                    });
                    const upDiv = root.querySelector('#upgradeList');
                    upDiv.innerHTML = '';
                    ['Аэродинамика','Двигатель','Шасси','Надёжность'].forEach((label,i) => {
                        const keys = ['aero','engine','chassis','reliability'];
                        const cur = team.car[keys[i]];
                        const can = this.state.budget >= this.state.upgradeCost && cur < 99;
                        upDiv.innerHTML += `<div class="upgrade-row"><span>${label} <span class="upgrade-stat">${cur}</span> → ${Math.min(cur+7,99)}</span><button class="upgrade-btn" data-key="${keys[i]}" ${can?'':'disabled'}>+7 (8 млн)</button></div>`;
                    });
                }
                const btn = root.querySelector('#startRaceBtn');
                if (this.state.raceInProgress) { btn.disabled = true; btn.textContent = '🏎️ Гонка идёт...'; }
                else if (this.state.currentRace > this.data.totalRaces) { btn.disabled = true; btn.textContent = '🏆 Сезон завершён'; }
                else { btn.disabled = false; btn.textContent = '🚦 Старт уик-энда'; }
                this.renderStandings();
                this.renderDriverStandings();
                if (root.querySelector('#historyView').classList.contains('active')) this.updateHistoryView();
            }

            renderPilot(id, pilot, idx) {
                const el = this.root.querySelector(`#${id}`);
                if (!el) return;
                el.innerHTML = `<div><div class="pilot-name">${pilot.name}</div><div class="pilot-skill">Мастерство: ${pilot.skill}</div></div><button class="hire-btn" data-pilot-index="${idx}" ${this.state.budget<3?'disabled':''}>🔄 Нанять (3 млн)</button>`;
            }

            renderStandings() {
                const sorted = [...this.state.standings].sort((a,b) => b.points - a.points);
                let html = '<table><tr><th>#</th><th>Команда</th><th>Очки</th></tr>';
                sorted.forEach((s,i) => html += `<tr><td>${i+1}</td><td>${s.teamName}</td><td>${s.points}</td></tr>`);
                this.root.querySelector('#standingsTable').innerHTML = html + '</table>';
            }
            renderDriverStandings() {
                const sorted = [...this.state.driverStandings].sort((a,b) => b.points - a.points);
                let html = '<table><tr><th>#</th><th>Пилот</th><th>Команда</th><th>Очки</th></tr>';
                sorted.forEach((d,i) => html += `<tr><td>${i+1}</td><td>${d.name}</td><td>${d.teamName}</td><td>${d.points}</td></tr>`);
                this.root.querySelector('#driversTable').innerHTML = html + '</table>';
            }

            updateHistoryView() {
                const select = this.root.querySelector('#historySelect');
                const tableDiv = this.root.querySelector('#historyTable');
                select.innerHTML = '<option value="">-- Выберите этап --</option>';
                this.state.raceHistory.forEach((race, index) => {
                    const option = document.createElement('option');
                    option.value = index; option.textContent = race.grandPrix;
                    select.appendChild(option);
                });
                if (this.state.raceHistory.length > 0) {
                    select.value = this.state.raceHistory.length - 1;
                    this.showHistoryTable(this.state.raceHistory.length - 1);
                } else {
                    tableDiv.innerHTML = '<p style="color:#8a8f9a;">Нет завершённых гонок.</p>';
                }
            }

            showHistoryTable(index) {
                const tableDiv = this.root.querySelector('#historyTable');
                if (this.state.raceHistory[index]) {
                    const race = this.state.raceHistory[index];
                    let html = `<p style="margin-bottom:8px; font-weight:600;">🏁 ${race.grandPrix}</p>`;
                    html += `<table><tr><th>#</th><th>Пилот</th><th>Команда</th><th>Старт</th><th>Финиш</th></tr>`;
                    race.results.forEach((r, i) => {
                        const start = r.startPosition || '–';
                        const finish = r.dnf ? '💔 DNF' : `P${r.position}`;
                        html += `<tr><td>${i+1}</td><td>${r.name}</td><td>${r.team}</td><td>${start}</td><td>${finish}</td></tr>`;
                    });
                    html += '</table>';
                    tableDiv.innerHTML = html;
                }
            }

            runQualifying() {
                const drivers = [];
                this.state.teams.forEach(team => {
                    team.drivers.forEach(driver => {
                        drivers.push({ name: driver.name, skill: driver.skill, team: team.name, car: team.car });
                    });
                });
                const getPace = d => {
                    const carAvg = (d.car.aero + d.car.engine + d.car.chassis) / 3;
                    return d.skill * 0.65 + carAvg * 0.35;
                };
                const attempt = d => getPace(d) + (Math.random() * 1.2 - 0.6);
                const q1 = drivers.map(d => ({ ...d, time: attempt(d) })).sort((a,b) => b.time - a.time);
                const q1Eliminated = q1.slice(17);
                const q2Participants = q1.slice(0, 17);
                const q2 = q2Participants.map(d => ({ ...d, time: attempt(d) })).sort((a,b) => b.time - a.time);
                const q2Eliminated = q2.slice(11);
                const q3Participants = q2.slice(0, 11);
                const q3 = q3Participants.map(d => ({ ...d, time: attempt(d) })).sort((a,b) => b.time - a.time);
                const grid = [];
                q3.forEach((d, i) => grid.push({ name: d.name, team: d.team, gridPos: i+1 }));
                q2Eliminated.forEach((d, i) => grid.push({ name: d.name, team: d.team, gridPos: 12 + i }));
                q1Eliminated.forEach((d, i) => grid.push({ name: d.name, team: d.team, gridPos: 18 + i }));
                return grid;
            }

            simulateRace() {
                if (this.state.raceInProgress || this.state.currentRace > this.data.totalRaces) return;
                this.state.raceInProgress = true;
                this.updateUI();
                const root = this.root;
                const logEl = root.querySelector('#raceLog');
                const bar = root.querySelector('#raceProgressBar');
                const status = root.querySelector('#raceStatusText');
                root.querySelector('#raceProgress').style.display = 'block';
                logEl.style.display = 'block';
                logEl.innerHTML = '';
                root.querySelector('#raceResult').innerHTML = '';
                bar.style.width = '0%';
                status.textContent = 'Квалификация...';

                const log = msg => {
                    const div = document.createElement('div');
                    div.textContent = '🔹 ' + msg;
                    logEl.appendChild(div);
                    logEl.scrollTop = logEl.scrollHeight;
                };

                const grid = this.runQualifying();
                this.state.qualifyingGrid = grid;
                log('📋 Стартовая решётка:');
                grid.forEach(d => log(`${d.gridPos}. ${d.name} (${d.team})`));

                const allDrivers = grid.map(g => {
                    const team = this.state.teams.find(t => t.name === g.team);
                    const driver = team.drivers.find(d => d.name === g.name);
                    return {
                        name: g.name, skill: driver?.skill || 80,
                        teamName: g.team,
                        teamIdx: this.state.teams.findIndex(t => t.name === g.team),
                        car: team?.car,
                        startPosition: g.gridPos,
                        position: 0, dnf: false
                    };
                });
                allDrivers.forEach(d => d.power = d.skill * 0.55 + (d.car.aero + d.car.engine + d.car.chassis)/3 * 0.45);

                const totalLaps = this.data.schedule[this.state.currentRace-1].laps;
                let lap = 0;
                log(`🚥 ${this.data.schedule[this.state.currentRace-1].grandPrix} стартовал! (${totalLaps} кругов)`);

                const interval = setInterval(() => {
                    lap++;
                    bar.style.width = (lap/totalLaps*100)+'%';
                    status.textContent = `Круг ${lap}/${totalLaps}`;

                    allDrivers.forEach(d => {
                        if (d.dnf) return;
                        if (Math.random() < Math.max(0, (100 - d.car.reliability)/100) * 0.025) {
                            d.dnf = true;
                            log(`💥 ${d.name} (${d.teamName}) сошёл!`);
                        }
                    });

                    const active = allDrivers.filter(d => !d.dnf);
                    active.sort((a,b) => (b.power + Math.random()*10) - (a.power + Math.random()*10));
                    active.forEach((d, idx) => d.position = idx+1);

                    if (lap >= totalLaps) {
                        clearInterval(interval);
                        this.finishRace(allDrivers, log);
                    }
                }, 120);
            }

            finishRace(allDrivers, log) {
                this.state.raceInProgress = false;
                this.root.querySelector('#raceStatusText').textContent = '🏁 Финиш!';

                const raceResultData = allDrivers.map(d => ({
                    name: d.name, team: d.teamName,
                    startPosition: d.startPosition,
                    position: d.position, dnf: d.dnf
                })).sort((a,b) => a.position - b.position);

                this.state.raceHistory.push({
                    grandPrix: this.data.schedule[this.state.currentRace-1].grandPrix,
                    results: raceResultData
                });

                const pointsTable = [25,18,15,12,10,8,6,4,2,1];
                const teamPts = {};
                allDrivers.forEach(d => { if (!d.dnf && d.position <= 10) teamPts[d.teamIdx] = (teamPts[d.teamIdx]||0) + pointsTable[d.position-1]; });
                for (const [idx, pts] of Object.entries(teamPts)) {
                    const i = parseInt(idx);
                    const stand = this.state.standings.find(s => s.teamName === this.state.teams[i].name);
                    if (stand) stand.points += pts;
                    if (!this.state.isSpectator && i === this.state.playerTeamIndex) this.state.points += pts;
                }
                allDrivers.forEach(d => {
                    if (!d.dnf && d.position <= 10) {
                        const entry = this.state.driverStandings.find(ds => ds.name === d.name && ds.teamName === d.teamName);
                        if (entry) entry.points += pointsTable[d.position-1];
                        else this.state.driverStandings.push({ name: d.name, teamName: d.teamName, points: pointsTable[d.position-1] });
                    }
                });

                if (!this.state.isSpectator && this.state.playerTeamIndex !== -1) {
                    const myDrivers = allDrivers.filter(d => d.teamIdx === this.state.playerTeamIndex);
                    let prize = 5; myDrivers.forEach(d => { if (!d.dnf && d.position <= 10) prize += (11 - d.position); });
                    this.state.budget += prize; this.state.budget -= this.state.teams[this.state.playerTeamIndex].drivers.length * 1;
                    log(`💰 Призовые: +${prize} млн | Зарплаты: -${this.state.teams[this.state.playerTeamIndex].drivers.length} млн`);
                }

                this.state.currentRace++;
                this.updateUI();
                this.showStatsModal(this.state.qualifyingGrid, raceResultData);
            }

            showStatsModal(grid, raceResults) {
                const root = this.root;
                root.querySelector('#modalRaceName').textContent = this.data.schedule[this.state.currentRace-2]?.grandPrix || 'Последняя гонка';
                let html = '<h3>📋 Стартовая решётка</h3><table><tr><th>#</th><th>Пилот</th><th>Команда</th></tr>';
                grid.forEach(d => html += `<tr><td>${d.gridPos}</td><td>${d.name}</td><td>${d.team}</td></tr>`);
                html += '</table><br><h3>🏁 Результаты гонки</h3>';
                html += '<table><tr><th>#</th><th>Пилот</th><th>Команда</th><th>Старт</th><th>Финиш</th></tr>';
                raceResults.forEach((r, i) => {
                    const start = r.startPosition || '–';
                    const finish = r.dnf ? '💔 DNF' : `P${r.position}`;
                    html += `<tr><td>${i+1}</td><td>${r.name}</td><td>${r.team}</td><td>${start}</td><td>${finish}</td></tr>`;
                });
                html += '</table>';
                root.querySelector('#modalTable').innerHTML = html;
                root.querySelector('#statsModal').classList.add('active');
            }

            hirePilot(index) {
                if (this.state.raceInProgress || this.state.budget < 3 || this.state.playerTeamIndex === -1 || this.state.isSpectator) return;
                const newDriver = this.data.freeAgents[Math.floor(Math.random()*this.data.freeAgents.length)];
                this.state.budget -= 3;
                const team = this.state.teams[this.state.playerTeamIndex];
                const oldName = team.drivers[index].name;
                this.state.driverStandings = this.state.driverStandings.filter(d => !(d.name === oldName && d.teamName === team.name));
                this.state.driverStandings.push({ name: newDriver.name, teamName: team.name, points: 0 });
                team.drivers[index] = { name: newDriver.name, skill: newDriver.skill };
                this.updateUI();
            }

            applyUpgrade(key) {
                if (this.state.raceInProgress || this.state.budget < this.state.upgradeCost || this.state.playerTeamIndex === -1 || this.state.isSpectator) return;
                const team = this.state.teams[this.state.playerTeamIndex];
                if (team.car[key] >= 99) return;
                this.state.budget -= this.state.upgradeCost;
                team.car[key] = Math.min(99, team.car[key]+7);
                this.updateUI();
            }
        }

        const f1Data = {
            title: '🏎️ F1 MANAGER 2026',
            subtitle: 'Классическая симуляция · Gucci Lamborghini · Календарь 2026',
            totalRaces: 24,
            teams: [
                { name: "BWT Alpine F1 Team", constructor: "Alpine", drivers: [{ name: "Пьер Гасли", skill: 87 }, { name: "Франко Колапинто", skill: 84 }], car: { aero: 80, engine: 78, chassis: 77, reliability: 80 }, budget: 52 },
                { name: "Aston Martin Aramco Honda", constructor: "Aston Martin", drivers: [{ name: "Фернандо Алонсо", skill: 88 }, { name: "Лэнс Стролл", skill: 79 }], car: { aero: 70, engine: 72, chassis: 70, reliability: 72 }, budget: 45 },
                { name: "Audi Revolut F1 Team", constructor: "Audi", drivers: [{ name: "Габриэль Бортолето", skill: 83 }, { name: "Нико Хюлькенберг", skill: 86 }], car: { aero: 72, engine: 70, chassis: 70, reliability: 74 }, budget: 46 },
                { name: "Cadillac Formula 1 Team", constructor: "Cadillac", drivers: [{ name: "Серхио Перес", skill: 84 }, { name: "Валттери Боттас", skill: 86 }], car: { aero: 71, engine: 73, chassis: 70, reliability: 73 }, budget: 44 },
                { name: "Scuderia Ferrari HP", constructor: "Ferrari", drivers: [{ name: "Шарль Леклер", skill: 91 }, { name: "Льюис Хэмилтон", skill: 94 }], car: { aero: 93, engine: 92, chassis: 91, reliability: 88 }, budget: 65 },
                { name: "TGR Haas F1 Team", constructor: "Haas", drivers: [{ name: "Эстебан Окон", skill: 81 }, { name: "Оливер Берман", skill: 79 }], car: { aero: 70, engine: 72, chassis: 68, reliability: 73 }, budget: 42 },
                { name: "McLaren Mastercard Formula 1 Team", constructor: "McLaren", drivers: [{ name: "Ландо Норрис", skill: 92 }, { name: "Оскар Пиастри", skill: 90 }], car: { aero: 91, engine: 90, chassis: 90, reliability: 86 }, budget: 62 },
                { name: "Mercedes-AMG Petronas F1 Team", constructor: "Mercedes", drivers: [{ name: "Джордж Расселл", skill: 93 }, { name: "Кими Антонелли", skill: 90 }], car: { aero: 94, engine: 94, chassis: 93, reliability: 90 }, budget: 68 },
                { name: "Gucci Lamborghini F1 Team", constructor: "Lamborghini", drivers: [{ name: "Лиам Лоусон", skill: 85 }, { name: "Никола Цолов", skill: 81 }], car: { aero: 79, engine: 77, chassis: 76, reliability: 79 }, budget: 50 },
                { name: "Oracle Red Bull Racing", constructor: "Red Bull Racing", drivers: [{ name: "Макс Ферстаппен", skill: 95 }, { name: "Изак Хаджар", skill: 88 }], car: { aero: 90, engine: 91, chassis: 89, reliability: 87 }, budget: 64 },
                { name: "Atlassian Williams F1 Team", constructor: "Williams", drivers: [{ name: "Александр Албон", skill: 82 }, { name: "Карлос Сайнс-мл.", skill: 83 }], car: { aero: 73, engine: 74, chassis: 72, reliability: 75 }, budget: 44 }
            ],
            schedule: [
                { country: "🇦🇺", grandPrix: "Гран-при Австралии", location: "Мельбурн", track: "Альберт-Парк", date: "16 марта", laps: 58 },
                { country: "🇨🇳", grandPrix: "Гран-при Китая", location: "Шанхай", track: "Международный автодром Шанхая", date: "23 марта", laps: 56 },
                { country: "🇯🇵", grandPrix: "Гран-при Японии", location: "Судзука", track: "Судзука", date: "6 апреля", laps: 53 },
                { country: "🇧🇭", grandPrix: "Гран-при Бахрейна", location: "Сахир", track: "Международный автодром Бахрейна", date: "13 апреля", laps: 57 },
                { country: "🇸🇦", grandPrix: "Гран-при Саудовской Аравии", location: "Джидда", track: "Городская трасса Джидда", date: "20 апреля", laps: 50 },
                { country: "🇺🇸", grandPrix: "Гран-при Майами", location: "Майами", track: "Международный автодром Майами", date: "4 мая", laps: 57 },
                { country: "🇮🇹", grandPrix: "Гран-при Эмилии-Романьи", location: "Имола", track: "Автодром Энцо и Дино Феррари", date: "18 мая", laps: 63 },
                { country: "🇲🇨", grandPrix: "Гран-при Монако", location: "Монте-Карло", track: "Городская трасса Монте-Карло", date: "25 мая", laps: 78 },
                { country: "🇪🇸", grandPrix: "Гран-при Испании", location: "Монмело", track: "Барселона-Каталунья", date: "1 июня", laps: 66 },
                { country: "🇨🇦", grandPrix: "Гран-при Канады", location: "Монреаль", track: "Автодром имени Жиля Вильнёва", date: "15 июня", laps: 70 },
                { country: "🇦🇹", grandPrix: "Гран-при Австрии", location: "Шпильберг", track: "Ред Булл Ринг", date: "29 июня", laps: 71 },
                { country: "🇬🇧", grandPrix: "Гран-при Великобритании", location: "Силверстон", track: "Сильверстоун", date: "6 июля", laps: 52 },
                { country: "🇧🇪", grandPrix: "Гран-при Бельгии", location: "Спа", track: "Спа-Франкоршам", date: "27 июля", laps: 44 },
                { country: "🇭🇺", grandPrix: "Гран-при Венгрии", location: "Будапешт", track: "Хунгароринг", date: "3 августа", laps: 70 },
                { country: "🇳🇱", grandPrix: "Гран-при Нидерландов", location: "Зандворт", track: "Зандворт", date: "31 августа", laps: 72 },
                { country: "🇮🇹", grandPrix: "Гран-при Италии", location: "Монца", track: "Монца", date: "7 сентября", laps: 53 },
                { country: "🇦🇿", grandPrix: "Гран-при Азербайджана", location: "Баку", track: "Городская трасса Баку", date: "21 сентября", laps: 51 },
                { country: "🇸🇬", grandPrix: "Гран-при Сингапура", location: "Сингапур", track: "Марина-Бей", date: "5 октября", laps: 62 },
                { country: "🇺🇸", grandPrix: "Гран-при США", location: "Остин", track: "Трасса Америк", date: "19 октября", laps: 56 },
                { country: "🇲🇽", grandPrix: "Гран-при Мехико", location: "Мехико", track: "Автодром имени братьев Родригес", date: "26 октября", laps: 71 },
                { country: "🇧🇷", grandPrix: "Гран-при Сан-Паулу", location: "Сан-Паулу", track: "Интерлагос", date: "9 ноября", laps: 71 },
                { country: "🇺🇸", grandPrix: "Гран-при Лас-Вегаса", location: "Лас-Вегас", track: "Городская трасса Лас-Вегас", date: "22 ноября", laps: 50 },
                { country: "🇶🇦", grandPrix: "Гран-при Катара", location: "Лусаил", track: "Международный автодром Лусаил", date: "30 ноября", laps: 57 },
                { country: "🇦🇪", grandPrix: "Гран-при Абу-Даби", location: "Абу-Даби", track: "Яс Марина", date: "7 декабря", laps: 58 }
            ],
            freeAgents: [
                { name: "Даниэль Риккардо", skill: 80 }, { name: "Мик Шумахер", skill: 77 },
                { name: "Роберт Шварцман", skill: 76 }, { name: "Тео Пуршер", skill: 75 }, { name: "Джек Дуэн", skill: 74 }
            ]
        };

        const feData = {
            title: '⚡ FORMULA E MANAGER 2025/26',
            subtitle: 'Синие тона · Реальные команды и пилоты · 16 этапов',
            totalRaces: 16,
            teams: [
                { name: "Jaguar TCS Racing", constructor: "Jaguar", drivers: [{ name: "Митч Эванс", skill: 95 }, { name: "Антониу Феликс да Кошта", skill: 92 }], car: { aero: 90, engine: 92, chassis: 91, reliability: 88 }, budget: 58 },
                { name: "Porsche Formula E Team", constructor: "Porsche", drivers: [{ name: "Паскаль Верляйн", skill: 96 }, { name: "Нико Мюллер", skill: 90 }], car: { aero: 91, engine: 93, chassis: 92, reliability: 87 }, budget: 60 },
                { name: "Mahindra Racing", constructor: "Mahindra", drivers: [{ name: "Эдоардо Мортара", skill: 89 }, { name: "Ник де Врис", skill: 90 }], car: { aero: 88, engine: 87, chassis: 89, reliability: 86 }, budget: 55 },
                { name: "Andretti Formula E", constructor: "Andretti", drivers: [{ name: "Джейк Деннис", skill: 91 }, { name: "Фелипе Другович", skill: 89 }], car: { aero: 89, engine: 88, chassis: 88, reliability: 85 }, budget: 56 },
                { name: "Nissan Formula E Team", constructor: "Nissan", drivers: [{ name: "Оливер Роуленд", skill: 92 }, { name: "Норман Нато", skill: 78 }], car: { aero: 87, engine: 89, chassis: 86, reliability: 84 }, budget: 54 },
                { name: "Envision Racing", constructor: "Envision", drivers: [{ name: "Себастьен Буэми", skill: 86 }, { name: "Джоэль Эрикссон", skill: 82 }], car: { aero: 82, engine: 83, chassis: 81, reliability: 82 }, budget: 50 },
                { name: "Citroën Racing", constructor: "Citroën", drivers: [{ name: "Ник Кэссиди", skill: 84 }, { name: "Жан-Эрик Вернь", skill: 84 }], car: { aero: 84, engine: 85, chassis: 84, reliability: 83 }, budget: 52 },
                { name: "Cupra Kiro", constructor: "Cupra Kiro", drivers: [{ name: "Хосеп-Мария Марти", skill: 83 }, { name: "Дэн Тиктум", skill: 75 }], car: { aero: 79, engine: 80, chassis: 78, reliability: 79 }, budget: 48 },
                { name: "DS Penske", constructor: "DS Penske", drivers: [{ name: "Тейлор Барнард", skill: 75 }, { name: "Максимилиан Гюнтер", skill: 75 }], car: { aero: 75, engine: 76, chassis: 74, reliability: 77 }, budget: 46 },
                { name: "Lola Yamaha ABT Formula E Team", constructor: "Lola Yamaha ABT", drivers: [{ name: "Лукас ди Грасси", skill: 78 }, { name: "Зейн Мэлони", skill: 72 }], car: { aero: 74, engine: 78, chassis: 73, reliability: 76 }, budget: 45 }
            ],
            schedule: [
                { country: "🇲🇽", grandPrix: "Mexico City E-Prix", location: "Мехико", laps: 36 },
                { country: "🇸🇦", grandPrix: "Diriyah E-Prix", location: "Джидда", laps: 37 },
                { country: "🇧🇷", grandPrix: "São Paulo E-Prix", location: "Сан-Паулу", laps: 34 },
                { country: "🇩🇪", grandPrix: "Berlin E-Prix", location: "Берлин", laps: 40 },
                { country: "🇲🇨", grandPrix: "Monaco E-Prix", location: "Монте-Карло", laps: 29 },
                { country: "🇨🇳", grandPrix: "Shanghai E-Prix", location: "Шанхай", laps: 32 },
                { country: "🇮🇹", grandPrix: "Rome E-Prix", location: "Рим", laps: 27 },
                { country: "🇬🇧", grandPrix: "London E-Prix", location: "Лондон", laps: 35 },
                { country: "🇺🇸", grandPrix: "New York E-Prix", location: "Нью-Йорк", laps: 38 },
                { country: "🇫🇷", grandPrix: "Paris E-Prix", location: "Париж", laps: 31 },
                { country: "🇰🇷", grandPrix: "Seoul E-Prix", location: "Сеул", laps: 33 },
                { country: "🇮🇩", grandPrix: "Jakarta E-Prix", location: "Джакарта", laps: 30 },
                { country: "🇿🇦", grandPrix: "Cape Town E-Prix", location: "Кейптаун", laps: 32 },
                { country: "🇦🇷", grandPrix: "Buenos Aires E-Prix", location: "Буэнос-Айрес", laps: 34 },
                { country: "🇯🇵", grandPrix: "Tokyo E-Prix", location: "Токио", laps: 35 },
                { country: "🇦🇺", grandPrix: "Sydney E-Prix", location: "Сидней", laps: 33 }
            ],
            freeAgents: [
                { name: "Стоффель Вандорн", skill: 82 }, { name: "Робин Фряйнс", skill: 79 },
                { name: "Андре Лоттерер", skill: 77 }
            ]
        };

        let f1Game, feGame;
        document.getElementById('playF1Btn').addEventListener('click', () => {
            document.getElementById('mainMenu').style.display = 'none';
            document.getElementById('f1Container').classList.add('active');
            if (!f1Game) f1Game = new RacingGame('f1Root', 'f1', f1Data);
        });
        document.getElementById('playFEBtn').addEventListener('click', () => {
            document.getElementById('mainMenu').style.display = 'none';
            document.getElementById('feContainer').classList.add('active');
            if (!feGame) feGame = new RacingGame('feRoot', 'fe', feData);
        });
        document.getElementById('backFromF1').addEventListener('click', hideAllGames);
        document.getElementById('backFromFE').addEventListener('click', hideAllGames);
    })();
</script>
</body>
</html>

Инструкция по открытию игры:

  • Игра доступна лишь на ПеКарне. Так что тем у кого нет ПК, могу сказать только Press F
  • Напишите любому из ИИ этот код и напишите по типу такого:
Я СОЗДАЛ СВОЮ ИГРУ | by Mentos
  • Небольшой совет. Если у вас есть ПК, но не имеете сейчас к нему доступа, дождитесь его. Потому что, если вы, будете копировать код с телефона, то вам придется это делать частями и согласитесь: это довольно не удобно. 
  • ИИ перепишет этот код и автоматически у вас появится кнопочка ОТКРЫТЬ или СКАЧАТЬ(желательно скачать, для удобства, много она не весит - всего 55,7 КБ(!) )
  • Играть!

Также я жду фидбека по поводу самой игры и возможным предложениям по самой игре. Буду рад услышать.

Десяток скриншотов по самой игре: 

Я СОЗДАЛ СВОЮ ИГРУ | by Mentos Я СОЗДАЛ СВОЮ ИГРУ | by Mentos Я СОЗДАЛ СВОЮ ИГРУ | by Mentos Я СОЗДАЛ СВОЮ ИГРУ | by Mentos Я СОЗДАЛ СВОЮ ИГРУ | by Mentos Я СОЗДАЛ СВОЮ ИГРУ | by Mentos Я СОЗДАЛ СВОЮ ИГРУ | by Mentos Я СОЗДАЛ СВОЮ ИГРУ | by Mentos Я СОЗДАЛ СВОЮ ИГРУ | by Mentos

Ţĥē Éŋđ

Теги:Видео-игрыАвто-спорт играMentos
0
15
15
17комментариев
188просмотров

Оставить комментарий

Для добавления комментария необходимо авторизоваться.

Лучшиекомментарии (17)

Mentos

Это пока сырая БЕТА-версия, сделанная за 2 дня, так что строго не судите) P.s Надеюсь, никто просто так спойлер не открывал?

Ответы (1)
3

Koteechka🍁

Очень классно, Я тоже когда-то пыталась что-то программировать.

1
Показать все комментарии

Похожие посты

Неделю играл в игры из 90-х и 00-х. Я стал счастливее?

Ради написания данного поста, я на протяжении около недели играл в ретро игры из 90-х и 00-х. Возможно жизнь стала круче после этого 😎

Bioware теперь всё

Впрочем, я не удивлён подобному исходу событий. И сегодня мне ещё хочется высказать непопулярное мнение насчёт творчества этой студии.

Пять игр с самой проработанной системой выживания

Игры, где голод, холод и болезни сделаны как система, а не как полоски в углу экрана. Вот топ 5 таких по

Мне надоел хайп по GTA VI

Мне просто надоело, как интернет постоянно крутит хайп по этой "игре десятилетия". И почему я отношусь к её релизу с огромной долей скепсиса.

Игровой год 2026: Часть 7 (Resident Evil: Requiem & Terminator: Resistance)

С начала 2026 года я прошел некоторое кол-во игр, и я решил писать небольшие отзывы по ним. В серии своих рассказов я буду брать по 2 игры (в том порядке, что я их проходил) и кратенько писать отзывы

Как Andrero пытается мод сделать, часть 2

Рассказываю что я успел сделать

Как Andrero пытался мод сделать

Я пытался сделать мод и вот что вышло

Игровой год 2026: Часть 6 (Robocop: Unfinished Business & Crysis 2)

С начала 2026 года я прошел некоторое кол-во игр, и я решил писать небольшие отзывы по ним. В серии своих рассказов я буду брать по 2 игры (в том порядке, что я их проходил) и кратенько писать отзывы

КОНЕЦ НАЧАЛА\/ СЕРВЕРНЫЕ ПОСИДЕЛКИ👾👾👾

Все знают игру Minecraft и самособой знают что там есть сервера. И я решил зайти на один из них. Щас поясню за кубики!

Обязательное к прохождению от Пикукерсов | Pikuco

В этом посте будут игры, которые пользователи Пикуко советуют к обязательному прохождению. От маленьких инди игр до ААА гигантов.