2D Car Game
by BraveBuilder54303 lines8.2 KB
<!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.