Hill climb Race Car Move Animation


 <!DOCTYPE html>

<html lang="en">

<head>

    <meta charset="UTF-8">

    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <title>Hill Climb Racing</title>

    <style>

        body {

            margin: 0;

            padding: 0;

            background-color: #87CEEB;

            font-family: Arial, sans-serif;

            overflow: hidden;

            user-select: none;

            touch-action: manipulation;

        }

        

        #game-container {

            position: relative;

            width: 800px;

            max-width: 100%;

            height: 400px;

            margin: 20px auto;

            border: 4px solid #333;

            border-radius: 10px;

            box-shadow: 0 0 20px rgba(0, 0, 0, 0.5);

            background-color: #7CFC00;

            overflow: hidden;

        }

        

        #game-canvas {

            background-color: #87CEEB;

            display: block;

            width: 100%;

            height: 100%;

        }

        

        #ui-container {

            position: absolute;

            top: 10px;

            left: 10px;

            color: white;

            text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.7);

            font-size: 18px;

            pointer-events: none;

        }

        

        #game-over {

            position: absolute;

            top: 0;

            left: 0;

            width: 100%;

            height: 100%;

            background-color: rgba(0, 0, 0, 0.7);

            display: none;

            flex-direction: column;

            justify-content: center;

            align-items: center;

            color: white;

            font-size: 36px;

        }

        

        #restart-btn {

            margin-top: 20px;

            padding: 10px 20px;

            font-size: 20px;

            background-color: #4CAF50;

            color: white;

            border: none;

            border-radius: 5px;

            cursor: pointer;

        }

        

        #restart-btn:hover {

            background-color: #45a049;

        }

        

        .controls {

            text-align: center;

            margin-top: 10px;

            font-size: 18px;

            color: #333;

        }

        

        /* On-screen controls */

        #touch-controls {

            display: flex;

            justify-content: space-between;

            position: absolute;

            bottom: 20px;

            width: 100%;

            padding: 0 20px;

            box-sizing: border-box;

        }

        

        .arrow-btn {

            width: 80px;

            height: 80px;

            background-color: rgba(0, 0, 0, 0.3);

            border-radius: 50%;

            display: flex;

            justify-content: center;

            align-items: center;

            font-size: 40px;

            color: white;

            user-select: none;

            -webkit-tap-highlight-color: transparent;

        }

        

        .arrow-btn:active {

            background-color: rgba(0, 0, 0, 0.5);

            transform: scale(0.95);

        }

        

        @media (max-width: 600px) {

            .arrow-btn {

                width: 60px;

                height: 60px;

                font-size: 30px;

            }

        }

    </style>

</head>

<body>

    <div id="game-container">

        <canvas id="game-canvas"></canvas>

        <div id="ui-container">

            <div>Distance: <span id="distance">0</span>m</div>

            <div>Fuel: <span id="fuel">100</span>%</div>

        </div>

        <div id="game-over">

            <div>Game Over!</div>

            <div>Your score: <span id="final-score">0</span>m</div>

            <button id="restart-btn">Play Again</button>

        </div>

        

        <!-- On-screen controls -->

        <div id="touch-controls">

            <div class="arrow-btn" id="left-btn">←</div>

            <div class="arrow-btn" id="right-btn">→</div>

        </div>

    </div>

    <div class="controls">

        Use <strong>arrow keys</strong> or <strong>on-screen buttons</strong> to drive

    </div>


    <script>

        // Game variables

        const canvas = document.getElementById('game-canvas');

        const ctx = canvas.getContext('2d');

        

        // Set canvas size

        function resizeCanvas() {

            const container = document.getElementById('game-container');

            canvas.width = container.clientWidth;

            canvas.height = container.clientHeight;

        }

        

        window.addEventListener('resize', resizeCanvas);

        resizeCanvas();

        

        let playerX = 100;

        let playerY = 300;

        let velocityX = 0;

        let velocityY = 0;

        let terrain = [];

        let score = 0;

        let fuel = 100;

        let gameRunning = true;

        let leftPressed = false;

        let rightPressed = false;

        

        // UI elements

        const distanceElement = document.getElementById('distance');

        const fuelElement = document.getElementById('fuel');

        const gameOverElement = document.getElementById('game-over');

        const finalScoreElement = document.getElementById('final-score');

        const restartBtn = document.getElementById('restart-btn');

        const leftBtn = document.getElementById('left-btn');

        const rightBtn = document.getElementById('right-btn');

        

        // Initialize game

        function initGame() {

            playerX = 100;

            playerY = canvas.height * 0.75;

            velocityX = 0;

            velocityY = 0;

            score = 0;

            fuel = 100;

            gameRunning = true;

            

            generateTerrain();

            gameOverElement.style.display = 'none';

            

            // Start game loop

            requestAnimationFrame(gameLoop);

        }

        

        // Generate terrain

        function generateTerrain() {

            terrain = [];

            let y = canvas.height * 0.75; // Starting height

            for(let x = 0; x < canvas.width * 2; x += 10) {

                y += Math.random() * 20 - 10; // Random height changes

                terrain.push({x, y});

            }

        }

        

        // Get terrain height at x position

        function getTerrainY(x) {

            x = Math.max(0, Math.min(x, canvas.width * 2 - 10));

            const index = Math.floor(x / 10);

            const segment = x % 10 / 10;

            

            if (index >= terrain.length - 1) {

                return terrain[terrain.length - 1].y;

            }

            

            // Linear interpolation between terrain points

            return terrain[index].y + (terrain[index + 1].y - terrain[index].y) * segment;

        }

        

        // Draw terrain

        function drawTerrain() {

            ctx.fillStyle = '#7CFC00';

            ctx.beginPath();

            ctx.moveTo(0, canvas.height);

            

            for(let i = 0; i < terrain.length; i++) {

                ctx.lineTo(terrain[i].x, terrain[i].y);

            }

            

            ctx.lineTo(canvas.width * 2, canvas.height);

            ctx.closePath();

            ctx.fill();

            

            // Add some dirt/ground texture

            ctx.strokeStyle = '#8B4513';

            ctx.lineWidth = 2;

            ctx.beginPath();

            for(let i = 0; i < terrain.length; i++) {

                if (i === 0) {

                    ctx.moveTo(terrain[i].x, terrain[i].y);

                } else {

                    ctx.lineTo(terrain[i].x, terrain[i].y);

                }

            }

            ctx.stroke();

        }

        

        // Draw player vehicle

        function drawPlayer() {

            // Car body

            ctx.fillStyle = '#FF0000';

            ctx.fillRect(playerX - 20, playerY - 15, 40, 10);

            ctx.fillRect(playerX - 15, playerY - 25, 30, 10);

            

            // Windows

            ctx.fillStyle = '#ADD8E6';

            ctx.fillRect(playerX - 10, playerY - 20, 20, 5);

            

            // Wheels

            ctx.fillStyle = '#000000';

            ctx.beginPath();

            ctx.arc(playerX - 15, playerY, 5, 0, Math.PI * 2);

            ctx.arc(playerX + 15, playerY, 5, 0, Math.PI * 2);

            ctx.fill();

        }

        

        // Update physics

        function updatePhysics() {

            // Handle controls

            if (leftPressed && fuel > 0) {

                velocityX -= 0.5;

            }

            if (rightPressed && fuel > 0) {

                velocityX += 0.5;

            }

            

            // Gravity

            velocityY += 0.2;

            

            // Apply velocity

            playerX += velocityX;

            playerY += velocityY;

            

            // Check terrain collision

            let terrainY = getTerrainY(playerX);

            if(playerY > terrainY - 10) {

                playerY = terrainY - 10;

                velocityY = 0;

            }

            

            // Fuel consumption

            if((leftPressed || rightPressed) && Math.abs(velocityX) > 0) {

                fuel -= 0.05;

                fuel = Math.max(0, fuel);

            }

            

            // Friction

            velocityX *= 0.98;

            

            // Camera follow (move terrain when player reaches middle of screen)

            if(playerX > canvas.width / 2) {

                const diff = playerX - canvas.width / 2;

                playerX = canvas.width / 2;

                

                // Shift terrain left

                for(let i = 0; i < terrain.length; i++) {

                    terrain[i].x -= diff;

                }

                

                // Generate new terrain segments on the right

                while(terrain[terrain.length - 1].x < canvas.width * 2) {

                    const last = terrain[terrain.length - 1];

                    const newX = last.x + 10;

                    const newY = last.y + Math.random() * 20 - 10;

                    terrain.push({x: newX, y: newY});

                }

                

                // Remove segments that are off-screen left

                while(terrain.length > 0 && terrain[0].x < 0) {

                    terrain.shift();

                }

                

                // Add to score based on distance moved

                score += diff;

            }

        }

        

        // Draw UI

        function drawUI() {

            distanceElement.textContent = Math.floor(score);

            fuelElement.textContent = Math.floor(fuel);

            

            // Fuel warning

            if(fuel < 30) {

                fuelElement.style.color = fuel < 15 ? '#FF0000' : '#FFA500';

            } else {

                fuelElement.style.color = 'white';

            }

        }

        

        // Game over

        function gameOver() {

            gameRunning = false;

            finalScoreElement.textContent = Math.floor(score);

            gameOverElement.style.display = 'flex';

        }

        

        // Game loop

        function gameLoop() {

            if(!gameRunning) return;

            

            // Clear canvas

            ctx.clearRect(0, 0, canvas.width, canvas.height);

            

            // Update game state

            updatePhysics();

            

            // Draw terrain

            drawTerrain();

            

            // Draw player

            drawPlayer();

            

            // Draw UI

            drawUI();

            

            // Check game over conditions

            if(fuel <= 0 || playerY > canvas.height) {

                gameOver();

                return;

            }

            

            requestAnimationFrame(gameLoop);

        }

        

        // Keyboard controls

        document.addEventListener('keydown', (e) => {

            if(!gameRunning) return;

            

            if(e.key === 'ArrowRight') {

                rightPressed = true;

            }

            if(e.key === 'ArrowLeft') {

                leftPressed = true;

            }

        });

        

        document.addEventListener('keyup', (e) => {

            if(e.key === 'ArrowRight') {

                rightPressed = false;

            }

            if(e.key === 'ArrowLeft') {

                leftPressed = false;

            }

        });

        

        // Touch controls

        leftBtn.addEventListener('touchstart', (e) => {

            e.preventDefault();

            leftPressed = true;

        });

        

        leftBtn.addEventListener('touchend', (e) => {

            e.preventDefault();

            leftPressed = false;

        });

        

        leftBtn.addEventListener('mousedown', () => {

            leftPressed = true;

        });

        

        leftBtn.addEventListener('mouseup', () => {

            leftPressed = false;

        });

        

        leftBtn.addEventListener('mouseleave', () => {

            leftPressed = false;

        });

        

        rightBtn.addEventListener('touchstart', (e) => {

            e.preventDefault();

            rightPressed = true;

        });

        

        rightBtn.addEventListener('touchend', (e) => {

            e.preventDefault();

            rightPressed = false;

        });

        

        rightBtn.addEventListener('mousedown', () => {

            rightPressed = true;

        });

        

        rightBtn.addEventListener('mouseup', () => {

            rightPressed = false;

        });

        

        rightBtn.addEventListener('mouseleave', () => {

            rightPressed = false;

        });

        

        restartBtn.addEventListener('click', initGame);

        

        // Start the game

        initGame();

    </script>

</body>

</html>

Comments

Popular posts from this blog

cc app code button match with size return with Try Again Button

AS2 in JavaScript add score 1 press button A and B clicked id null

ClaudieAi Pair Game WITHOUT JS DOM OBJECT Direct access by ID ✅ ✔✔🌹🌹🎉