Загрузка данных
<!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>