const canvas = document.getElementById("gameCanvas"); const ctx = canvas.getContext("2d"); let car = { x: 400, y: 300, width: 40, height: 20, speed: 0, angle: 0, maxSpeed: 5, accel: 0.2, friction: 0.05, turnSpeed: 0.04 }; let keys = {}; document.addEventListener("keydown", (e) => keys[e.key] = true); document.addEventListener("keyup", (e) => keys[e.key] = false); function update() { if (keys["ArrowUp"]) car.speed += car.accel; if (keys["ArrowDown"]) car.speed -= car.accel; car.speed *= (1 - car.friction); car.speed = Math.max(Math.min(car.speed, car.maxSpeed), -car.maxSpeed); if (keys["ArrowLeft"]) car.angle -= car.turnSpeed * car.speed; if (keys["ArrowRight"]) car.angle += car.turnSpeed * car.speed; car.x += Math.cos(car.angle) * car.speed; car.y += Math.sin(car.angle) * car.speed; } function drawCar() { ctx.save(); ctx.translate(car.x, car.y); ctx.rotate(car.angle); ctx.fillStyle = "red"; ctx.fillRect(-car.width / 2, -car.height / 2, car.width, car.height); ctx.restore(); } function gameLoop() { ctx.clearRect(0, 0, canvas.width, canvas.height); update(); drawCar(); requestAnimationFrame(gameLoop); } gameLoop(); let lap = 0; let currentCheckpoint = 0; const checkpoints = [ { x: 200, y: 100 }, { x: 600, y: 100 }, { x: 600, y: 500 }, { x: 200, y: 500 } ]; function checkLapProgress() { const cp = checkpoints[currentCheckpoint]; const dx = car.x - cp.x; const dy = car.y - cp.y; const distance = Math.sqrt(dx * dx + dy * dy); if (distance < 30) { currentCheckpoint++; if (currentCheckpoint >= checkpoints.length) { lap++; currentCheckpoint = 0; console.log("Lap completed! Total laps:", lap); } } } checkLapProgress(); drawCheckpoints(); drawLapCounter(); function drawCheckpoints() { for (let i = 0; i < checkpoints.length; i++) { ctx.fillStyle = (i === currentCheckpoint) ? "lime" : "yellow"; ctx.beginPath(); ctx.arc(checkpoints[i].x, checkpoints[i].y, 10, 0, Math.PI * 2); ctx.fill(); } } function drawLapCounter() { ctx.fillStyle = "white"; ctx.font = "20px Arial"; ctx.fillText("Lap: " + lap, 10, 30); } const walls = [ { x: 100, y: 100, width: 20, height: 400 }, // Left wall { x: 100, y: 100, width: 600, height: 20 }, // Top wall { x: 680, y: 100, width: 20, height: 400 }, // Right wall { x: 100, y: 480, width: 600, height: 20 } // Bottom wall ]; function checkWallCollision() { for (let wall of walls) { if ( car.x > wall.x && car.x < wall.x + wall.width && car.y > wall.y && car.y < wall.y + wall.height ) { car.speed = 0; } } } function drawWalls() { ctx.fillStyle = "gray"; for (let wall of walls) { ctx.fillRect(wall.x, wall.y, wall.width, wall.height); } } drawWalls(); checkWallCollision(); if (keys["Shift"]) { car.speed += 0.5; car.speed = Math.min(car.speed, car.maxSpeed * 2); // Nitro limit } let aiCar = { x: 420, y: 320, width: 40, height: 20, speed: 0, angle: 0, maxSpeed: 2.5, targetCheckpoint: 0 }; function updateAICar() { const target = checkpoints[aiCar.targetCheckpoint]; const dx = target.x - aiCar.x; const dy = target.y - aiCar.y; const targetAngle = Math.atan2(dy, dx); let angleDiff = targetAngle - aiCar.angle; angleDiff = Math.atan2(Math.sin(angleDiff), Math.cos(angleDiff)); // Normalize if (angleDiff > 0.05) aiCar.angle += 0.03; else if (angleDiff < -0.05) aiCar.angle -= 0.03; aiCar.speed = aiCar.maxSpeed; aiCar.x += Math.cos(aiCar.angle) * aiCar.speed; aiCar.y += Math.sin(aiCar.angle) * aiCar.speed; const distance = Math.sqrt(dx * dx + dy * dy); if (distance < 30) { aiCar.targetCheckpoint++; if (aiCar.targetCheckpoint >= checkpoints.length) { aiCar.targetCheckpoint = 0; } } } function drawAICar() { ctx.save(); ctx.translate(aiCar.x, aiCar.y); ctx.rotate(aiCar.angle); ctx.fillStyle = "blue"; ctx.fillRect(-aiCar.width / 2, -aiCar.height / 2, aiCar.width, aiCar.height); ctx.restore(); } updateAICar(); drawAICar();