// Constants and Variables
const scoreElement = document.querySelector('.score');
const startScreen = document.querySelector('.startScreen');
const gameArea = document.querySelector('.gameArea');
const levelElement = document.querySelector('.level');
const levelSpeed = { easy: 7, moderate: 10, difficult: 14 };
const player = { speed: 7, score: 0, x: 0, y: 0, start: false };
let keys = {
ArrowUp: false,
ArrowDown: false,
ArrowLeft: false,
ArrowRight: false
};
// Audio Files
const gameStartAudio = new Audio("assets/audio/game_theme.mp3");
const gameOverAudio = new Audio("assets/audio/gameOver_theme.mp3");
// Event Listeners
levelElement.addEventListener('click', setPlayerSpeed);
startScreen.addEventListener('click', startGame);
document.addEventListener('keydown', (e) => {
e.preventDefault();
keys[e.key] = true;
});
document.addEventListener('keyup', (e) => {
e.preventDefault();
keys[e.key] = false;
});
// Functions
function setPlayerSpeed(e) {
player.speed = levelSpeed[e.target.id];
}
function startGame() {
startScreen.classList.add('hide');
gameArea.innerHTML = "";
player.start = true;
player.score = 0;
gameStartAudio.loop = true;
gameStartAudio.play();
window.requestAnimationFrame(gamePlay);
createRoadLines();
createPlayerCar();
createEnemyCars();
}
function createRoadLines() {
for (let i = 0; i < 5; i++) {
const roadLine = document.createElement('div');
roadLine.classList.add('roadLines');
roadLine.y = (i * 150);
roadLine.style.top = `${roadLine.y}px`;
gameArea.appendChild(roadLine);
}
}
function createPlayerCar() {
const carElement = document.createElement('div');
carElement.classList.add('car');
gameArea.appendChild(carElement);
player.x = carElement.offsetLeft;
player.y = carElement.offsetTop;
}
function createEnemyCars() {
for (let i = 0; i < 3; i++) {
const enemyCar = document.createElement('div');
enemyCar.classList.add('enemyCar');
enemyCar.y = ((i + 1) * 350) * -1;
enemyCar.style.top = `${enemyCar.y}px`;
enemyCar.style.backgroundColor = getRandomColor();
enemyCar.style.left = `${Math.floor(Math.random() * 350)}px`;
gameArea.appendChild(enemyCar);
}
}
function getRandomColor() {
const randomHex = () => Math.floor(Math.random() * 256).toString(16).padStart(2, '0');
return `#${randomHex()}${randomHex()}${randomHex()}`;
}
function onCollision(a, b) {
const aRect = a.getBoundingClientRect();
const bRect = b.getBoundingClientRect();
return !((aRect.top > bRect.bottom) || (aRect.bottom < bRect.top) ||
(aRect.right < bRect.left) || (aRect.left > bRect.right));
}
function onGameOver() {
player.start = false;
gameStartAudio.pause();
gameOverAudio.play();
startScreen.classList.remove('hide');
startScreen.innerHTML = `Game Over
Your final score is ${player.score}
Press here to restart the game.`;
}
function moveRoadLines() {
const roadLines = document.querySelectorAll('.roadLines');
roadLines.forEach((line) => {
line.y += player.speed;
if (line.y >= 700) {
line.y -= 750;
}
line.style.top = `${line.y}px`;
});
}
function moveEnemyCars(carElement) {
const enemyCars = document.querySelectorAll('.enemyCar');
enemyCars.forEach((enemyCar) => {
if (onCollision(carElement, enemyCar)) {
onGameOver();
}
enemyCar.y += player.speed;
if (enemyCar.y >= 750) {
enemyCar.y = -300;
enemyCar.style.left = `${Math.floor(Math.random() * 350)}px`;
}
enemyCar.style.top = `${enemyCar.y}px`;
});
}
function gamePlay() {
const carElement = document.querySelector('.car');
const road = gameArea.getBoundingClientRect();
if (player.start) {
moveRoadLines();
moveEnemyCars(carElement);
if (keys.ArrowUp && player.y > (road.top + 70)) player.y -= player.speed;
if (keys.ArrowDown && player.y < (road.bottom - 85)) player.y += player.speed;
if (keys.ArrowLeft && player.x > 0) player.x -= player.speed;
if (keys.ArrowRight && player.x < (road.width - 70)) player.x += player.speed;
carElement.style.top = `${player.y}px`;
carElement.style.left = `${player.x}px`;
player.score++;
scoreElement.innerHTML = `Score: ${player.score - 1}`;
window.requestAnimationFrame(gamePlay);
}
}