🎮ArcadeLab

2D Car Game

by BraveBuilder54
303 lines8.2 KB
▶ Play
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>2D Car Game</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        body {
            background-color: #222;
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            height: 100vh;
            font-family: Arial, sans-serif;
            color: #fff;
            overflow: hidden;
        }

        #game-container {
            position: relative;
            width: 320px;
            height: 500px;
            background-color: #444;
            border-left: 8px dashed #fff;
            border-right: 8px dashed #fff;
            overflow: hidden;
            box-shadow: 0 0 20px rgba(0,0,0,0.8);
        }

        /* Moving Road Lines */
        .line {
            position: absolute;
            width: 8px;
            height: 80px;
            background-color: #fff;
            left: 50%;
            transform: translateX(-50%);
        }

        /* Cars styling */
        .car {
            position: absolute;
            width: 40px;
            height: 70px;
            border-radius: 8px;
            box-shadow: 0 4px 8px rgba(0,0,0,0.3);
        }

        /* Player Car */
        #player {
            background-color: #e74c3c;
            bottom: 20px;
            left: 140px;
            z-index: 2;
        }

        /* Windows for details */
        .car::before {
            content: '';
            position: absolute;
            top: 12px;
            left: 5px;
            width: 30px;
            height: 15px;
            background-color: #333;
            border-radius: 3px;
        }

        /* Enemy Car */
        .enemy {
            background-color: #f1c40f;
            top: -100px;
            z-index: 1;
        }

        /* UI elements */
        #score-board {
            position: absolute;
            top: 10px;
            left: 10px;
            background: rgba(0, 0, 0, 0.6);
            padding: 6px 12px;
            border-radius: 5px;
            font-size: 16px;
            font-weight: bold;
            z-index: 10;
        }

        #game-over {
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background: rgba(0, 0, 0, 0.85);
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            z-index: 20;
        }

        #game-over h1 {
            color: #e74c3c;
            margin-bottom: 10px;
        }

        #game-over button {
            margin-top: 15px;
            padding: 10px 20px;
            font-size: 16px;
            font-weight: bold;
            color: #fff;
            background-color: #2ecc71;
            border: none;
            border-radius: 5px;
            cursor: pointer;
        }

        #game-over button:hover {
            background-color: #27ae60;
        }

        .controls-hint {
            margin-top: 15px;
            color: #aaa;
            font-size: 14px;
        }

        .hide {
            display: none !important;
        }
    </style>
</head>
<body>

    <div id="game-container">
        <div id="score-board">Score: <span id="score">0</span></div>
        
        <!-- Road Lines -->
        <div class="line" style="top: 0px;"></div>
        <div class="line" style="top: 150px;"></div>
        <div class="line" style="top: 300px;"></div>
        <div class="line" style="top: 450px;"></div>

        <!-- Player Car -->
        <div id="player" class="car"></div>

        <!-- Enemy Car -->
        <div id="enemy" class="car enemy"></div>

        <!-- Game Over Screen -->
        <div id="game-over" class="hide">
            <h1>GAME OVER</h1>
            <p>Final Score: <span id="final-score">0</span></p>
            <button onclick="restartGame()">Play Again</button>
        </div>
    </div>

    <div class="controls-hint">Controls: Arrow Keys (Left / Right / Up / Down)</div>

    <script>
        const container = document.getElementById('game-container');
        const player = document.getElementById('player');
        const enemy = document.getElementById('enemy');
        const scoreElement = document.getElementById('score');
        const finalScoreElement = document.getElementById('final-score');
        const gameOverScreen = document.getElementById('game-over');
        const lines = document.querySelectorAll('.line');

        // Game Configuration & State
        const playerSpeed = 5;
        const gameSpeed = 5;
        let score = 0;
        let isGameOver = false;
        let animationId;

        const playerPos = {
            x: 140,
            y: 410
        };

        const enemyPos = {
            x: Math.floor(Math.random() * 260),
            y: -100
        };

        const keys = {
            ArrowLeft: false,
            ArrowRight: false,
            ArrowUp: false,
            ArrowDown: false
        };

        // Event Listeners for Keyboard
        document.addEventListener('keydown', (e) => {
            if (keys.hasOwnProperty(e.key)) {
                keys[e.key] = true;
            }
        });

        document.addEventListener('keyup', (e) => {
            if (keys.hasOwnProperty(e.key)) {
                keys[e.key] = false;
            }
        });

        // Collision Detection Logic
        function isCollide(rect1, rect2) {
            return !(
                rect1.bottom < rect2.top ||
                rect1.top > rect2.bottom ||
                rect1.right < rect2.left ||
                rect1.left > rect2.right
            );
        }

        // Main Game Loop
        function gameLoop() {
            if (isGameOver) return;

            // Move Road Lines
            lines.forEach((line) => {
                let top = parseInt(line.style.top);
                if (top >= 500) {
                    top = -100;
                }
                line.style.top = (top + gameSpeed) + 'px';
            });

            // Player Movement & Boundaries
            if (keys.ArrowLeft && playerPos.x > 0) {
                playerPos.x -= playerSpeed;
            }
            if (keys.ArrowRight && playerPos.x < (container.clientWidth - player.clientWidth)) {
                playerPos.x += playerSpeed;
            }
            if (keys.ArrowUp && playerPos.y > 0) {
                playerPos.y -= playerSpeed;
            }
            if (keys.ArrowDown && playerPos.y < (container.clientHeight - player.clientHeight)) {
                playerPos.y += playerSpeed;
            }

            player.style.left = playerPos.x + 'px';
            player.style.top = playerPos.y + 'px';

            // Enemy Movement & Reset
            enemyPos.y += gameSpeed;
            if (enemyPos.y > 500) {
                enemyPos.y = -100;
                enemyPos.x = Math.floor(Math.random() * (container.clientWidth - enemy.clientWidth));
                score += 10;
                scoreElement.innerText = score;
            }

            enemy.style.left = enemyPos.x + 'px';
            enemy.style.top = enemyPos.y + 'px';

            // Check Collision
            if (isCollide(player.getBoundingClientRect(), enemy.getBoundingClientRect())) {
                endGame();
                return;
            }

            animationId = requestAnimationFrame(gameLoop);
        }

        // End Game Function
        function endGame() {
            isGameOver = true;
            cancelAnimationFrame(animationId);
            finalScoreElement.innerText = score;
            gameOverScreen.classList.remove('hide');
        }

        // Restart Game Function
        function restartGame() {
            isGameOver = false;
            score = 0;
            scoreElement.innerText = score;

            playerPos.x = 140;
            playerPos.y = 410;
            enemyPos.x = Math.floor(Math.random() * (container.clientWidth - enemy.clientWidth));
            enemyPos.y = -100;

            gameOverScreen.classList.add('hide');
            gameLoop();
        }

        // Start Game
        gameLoop();
    </script>
</body>
</html>

Game Source: 2D Car Game

Creator: BraveBuilder54

Libraries: none

Complexity: complex (303 lines, 8.2 KB)

The full source code is displayed above on this page.

Remix Instructions

To remix this game, copy the source code above and modify it. Add a ARCADELAB header at the top with "remix_of: 2d-car-game-bravebuilder54" to link back to the original. Then publish at arcadelab.ai/publish.