Загрузка данных


<!DOCTYPE html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <title>Эндуро Горы STM X6</title>
    <style>
        body { margin: 0; background: #111; display: flex; justify-content: center; align-items: center; height: 100vh; font-family: sans-serif; color: white; overflow: hidden; }
        canvas { background: #222; border: 4px solid #ff6600; box-shadow: 0 0 20px #ff6600; }
        #info { position: absolute; top: 20px; font-size: 20px; text-transform: uppercase; letter-spacing: 2px; }
        #controls { position: absolute; bottom: 20px; font-size: 14px; color: #888; }
    </style>
</head>
<body>
    <div id="info">Обороты: <span id="rpm">3000</span> | Передача: <span id="gear">1</span></div>
    <canvas id="gameCanvas" width="800" height="400"></canvas>
    <div id="controls">Управление: Стрелка ВПРАВО — Газ | Стрелка ВЛЕВО — Тормоз | R — Сброс</div>

    <script>
        const canvas = document.getElementById("gameCanvas");
        const ctx = canvas.getContext("2d");

        // Мотоцикл (Игрок)
        let player = {
            x: 100,
            y: 200,
            width: 30,
            height: 20,
            vy: 0,
            gravity: 0.4,
            speed: 0,
            maxSpeed: 7,
            accel: 0.1,
            rpm: 1500,
            gear: 1,
            onGround: false
        };

        // Генерация холмистой трассы (Горы)
        let mapPoints = [];
        for (let i = 0; i < 3000; i += 5) {
            let height = 280 + Math.sin(i * 0.01) * 40 + Math.cos(i * 0.03) * 20;
            // Делаем крутой подъем в конце
            if (i > 1500) height -= (i - 1500) * 0.1;
            mapPoints.push({x: i, y: height});
        }

        let keys = {};
        window.addEventListener("keydown", (e) => { keys[e.code] = true; if(e.code === 'KeyR') reset(); });
        window.addEventListener("keyup", (e) => keys[e.code] = false);

        function getMapY(x) {
            let p = mapPoints.find(p => p.x >= x);
            return p ? p.y : 300;
        }

        function reset() {
            player.x = 100;
            player.y = 200;
            player.speed = 0;
            player.vy = 0;
            player.gear = 1;
            player.rpm = 1500;
        }

        function update() {
            // Физика движения и газа
            if (keys["ArrowRight"]) {
                if (player.speed < player.maxSpeed) player.speed += player.accel;
                player.rpm += 150;
                if (player.rpm > 9500) { // Отсечка!
                    player.rpm = 9500;
                    player.speed *= 0.95; // Падает скорость при перекруте
                }
            } else {
                if (player.speed > 0) player.speed -= 0.05;
                if (player.rpm > 1500) player.rpm -= 100;
            }

            if (keys["ArrowLeft"]) {
                if (player.speed > 0) player.speed -= 0.2;
                if (player.speed < 0) player.speed = 0;
            }

            // Коробка передач (автоматический симулятор под скорость)
            if (player.speed > 2 && player.gear === 1) { player.gear = 2; player.rpm = 4000; }
            if (player.speed > 5 && player.gear === 2) { player.gear = 3; player.rpm = 4500; }
            if (player.speed <= 5 && player.gear === 3) { player.gear = 2; player.rpm = 6000; }
            if (player.speed <= 2 && player.gear === 2) { player.gear = 1; player.rpm = 3000; }

            player.x += player.speed;

            // Гравитация и удержание на земле
            let groundY = getMapY(player.x) - player.height;
            if (player.y < groundY) {
                player.vy += player.gravity;
                player.onGround = false;
            } else {
                player.y = groundY;
                player.vy = 0;
                player.onGround = true;
            }
            player.y += player.vy;

            // Обновление приборов
            document.getElementById("rpm").innerText = Math.round(player.rpm);
            document.getElementById("gear").innerText = player.gear;

            // Проверка победы
            if (player.x >= 2800) {
                alert("ПОБЕДА! Ты заехал на крутую гору на STM X6!");
                reset();
            }
        }

        function draw() {
            ctx.clearRect(0, 0, canvas.width, canvas.height);

            ctx.save();
            // Камера следит за мотоциклом
            ctx.translate(-player.x + 150, 0);

            // Рисуем горы (землю)
            ctx.beginPath();
            ctx.moveTo(0, canvas.height);
            for (let p of mapPoints) {
                ctx.lineTo(p.x, p.y);
            }
            ctx.lineTo(3000, canvas.height);
            ctx.fillStyle = "#332211";
            ctx.fill();
            ctx.strokeStyle = "#00ff00";
            ctx.lineWidth = 3;
            ctx.stroke();

            // Рисуем финишный флаг
            ctx.fillStyle = "#ff0000";
            ctx.fillRect(2800, getMapY(2800) - 60, 40, 60);
            ctx.fillStyle = "white";
            ctx.font = "12px sans-serif";
            ctx.fillText("ФИНИШ", 2802, getMapY(2800) - 40);

            // Рисуем черно-оранжевый мотоцикл STM X6
            ctx.fillStyle = "#ff6600"; // Оранжевая рама
            ctx.fillRect(player.x, player.y, player.width, player.height);
            ctx.fillStyle = "#000000"; // Черный пластик и сидушка
            ctx.fillRect(player.x + 5, player.y - 5, 20, 8);
            
            // Колеса
            ctx.beginPath();
            ctx.arc(player.x, player.y + player.height, 8, 0, Math.PI * 2);
            ctx.arc(player.x + player.width, player.y + player.height, 8, 0, Math.PI * 2);
            ctx.fillStyle = "#111";
            ctx.fill();
            ctx.strokeStyle = "#555";
            ctx.stroke();

            ctx.restore();
        }

        function loop() {
            update();
            draw();
            requestAnimationFrame(loop);
        }

        loop();
    </script>
</body>
</html>