import React, { useState, useEffect, useRef } from 'react'; import { ArrowLeft, ArrowRight } from 'lucide-react'; export default function CarRacingGame() { const [gameStarted, setGameStarted] = useState(false); const [gameOver, setGameOver] = useState(false); const [score, setScore] = useState(0); const [highScore, setHighScore] = useState(0); const [carPosition, setCarPosition] = useState(50); const [obstacles, setObstacles] = useState([]); const [speed, setSpeed] = useState(5); const gameAreaRef = useRef(null); const animationFrameRef = useRef(null); const lastObstacleTimeRef = useRef(0); // Game dimensions const carWidth = 10; const carHeight = 15; const obstacleWidth = 10; const obstacleHeight = 15; const roadWidth = 100; // Start the game const startGame = () => { setGameStarted(true); setGameOver(false); setScore(0); setCarPosition(50); setObstacles([]); setSpeed(5); lastObstacleTimeRef.current = Date.now(); gameLoop(); }; // Game loop const gameLoop = () => { if (gameAreaRef.current) { updateGameState(); animationFrameRef.current = requestAnimationFrame(gameLoop); } }; // Update game state const updateGameState = () => { // Increase score setScore(prevScore => { const newScore = prevScore + 1; if (newScore > highScore) { setHighScore(newScore); } return newScore; }); // Increase speed gradually if (score > 0 && score % 500 === 0) { setSpeed(prevSpeed => Math.min(prevSpeed + 1, 15)); } // Generate new obstacles const now = Date.now(); if (now - lastObstacleTimeRef.current > 1500 - speed * 50) { const newObstacleX = Math.random() * (roadWidth - obstacleWidth); setObstacles(prevObstacles => [ ...prevObstacles, { x: newObstacleX, y: -obstacleHeight } ]); lastObstacleTimeRef.current = now; } // Move obstacles setObstacles(prevObstacles => { const updatedObstacles = prevObstacles .map(obstacle => ({ ...obstacle, y: obstacle.y + speed })) .filter(obstacle => obstacle.y < 100); // Check for collisions const collision = updatedObstacles.some(obstacle => obstacle.y + obstacleHeight > 80 && obstacle.y < 80 + carHeight && obstacle.x + obstacleWidth > carPosition && obstacle.x < carPosition + carWidth ); if (collision) { setGameOver(true); cancelAnimationFrame(animationFrameRef.current); } return updatedObstacles; }); }; // Move car left const moveLeft = () => { if (!gameOver && gameStarted) { setCarPosition(prevPos => Math.max(0, prevPos - 10)); } }; // Move car right const moveRight = () => { if (!gameOver && gameStarted) { setCarPosition(prevPos => Math.min(roadWidth - carWidth, prevPos + 10)); } }; // Clean up animation frame on unmount useEffect(() => { return () => { if (animationFrameRef.current) { cancelAnimationFrame(animationFrameRef.current); } }; }, []); // Handle keyboard controls useEffect(() => { const handleKeyDown = (e) => { if (e.key === 'ArrowLeft') { moveLeft(); } else if (e.key === 'ArrowRight') { moveRight(); } else if (e.key === ' ' || e.key === 'Enter') { if (gameOver || !gameStarted) { startGame(); } } }; window.addEventListener('keydown', handleKeyDown); return () => { window.removeEventListener('keydown', handleKeyDown); }; }, [gameOver, gameStarted]); return (
Avoid obstacles by moving left and right. How far can you go?
Score: {score}
High Score: {highScore}
Tip: You can also use keyboard arrow keys to control the car