This is a submission for the Web Game Challenge, Build a Game: Alien Edition
What I Built
The player will start on the left side of the game area and can move up and down using up and down arrow keys, while shooting bullets to the right using the space bar. This allows for different strategies when avoiding aliens. When a bullet hits an alien, score will increase by 5 points, a blood splash will appear at the alien's position for a short time before fading out. This gives a visual cue for the hit, enhancing the game's feel.
If an Alien hits a player, he will lose one life. Max 3 lives a player and 100 bullets.
Lets play!!!
Demo
index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Alien Shooting Game</title> <link rel="stylesheet" href="style.css"> </head> <body> <div id="game-container"> <div id="lives">Lives: 3</div> <div id="score">Score: 0</div> <div id="bullet-count">Bullets Remaining: 100</div> <div id="game-over" style="display: none;">Game Over! Press R to Restart</div> <div id="player"></div> <div id="aliens"></div> </div> <script src="script.js"></script> </body> </html>
style.css
body { margin: 0; overflow: hidden; font-family: 'Arial', sans-serif; background: linear-gradient(to bottom, #1c1c1c, #2c2c2c); color: white; background: url('img/star.jpg') no-repeat center center fixed; background-size: cover; } #game-container { position: relative; width: 100vw; height: 100vh; overflow: hidden; } @keyframes fade-out { 0% { opacity: 1; } 100% { opacity: 0; } } #score, #bullet-count, #game-over, #lives{ position: absolute; left: 10px; color: white; font-size: 20px; z-index: 10; } #score { top: 10px; } #lives { top: 40px; } #bullet-count { top: 80px; } #game-over { top: 50%; left: 50%; transform: translate(-50%, -50%); font-size: 36px; text-align: center; background: rgba(0, 0, 0, 0.7); padding: 20px; border-radius: 10px; } .blood-splash { position: absolute; width: 50px; /* Adjust according to your blood splash image size */ height: 50px; /* Adjust according to your blood splash image size */ background: url('img/blood-splash.png') no-repeat center center; background-size: cover; animation: fade-out 0.5s forwards; /* Fade out animation */ } @keyframes fade-out { 0% { opacity: 1; } 100% { opacity: 0; } } #player { position: absolute; left: 30px; /* Fixed position on the left */ bottom: 50%; /* Center vertically (can adjust as needed) */ width: 30px; /* Adjust according to your player image size */ height: 50px; /* Adjust according to your player image size */ background: url('img/player.png') no-repeat center center; background-size: cover; /* Make sure the image covers the element */ } .alien { position: absolute; width: 25px; /* Adjust according to your image size */ height: 35px; /* Adjust according to your image size */ background: url('img/alien.png') no-repeat center center; background-size: cover; /* Make sure the image covers the element */ } .bullet { position: absolute; width: 10px; height: 3px; background: url('img/bullet.png') no-repeat center center; background-size: cover; /* Make sure the image covers the element */ border-radius: 2px; }
script.js
let score = 0; const player = document.getElementById('player'); const aliensContainer = document.getElementById('aliens'); const scoreDisplay = document.getElementById('score'); const bulletCountDisplay = document.getElementById('bullet-count'); const gameOverDisplay = document.getElementById('game-over'); // Game Over message const livesDisplay = document.getElementById('lives'); // Lives display const gameWidth = window.innerWidth; const gameHeight = window.innerHeight; let playerPositionY = (gameHeight / 2) - 25; // Center the player vertically let bullets = []; let aliens = []; const MAX_BULLETS = 20; // Maximum number of bullets let gameInterval; // To store the game interval let isGameOver = false; // To check if the game is over let playerLives = 3; // Player lives // Set the initial position of the player player.style.bottom = playerPositionY + 'px'; livesDisplay.innerText = "Lives: " + playerLives; // Display initial lives document.addEventListener('keydown', (event) => { if (isGameOver) { if (event.key === 'r' || event.key === 'R') { restartGame(); } return; // Do not allow movement or shooting if game is over } // Move the player up and down if (event.key === 'ArrowUp' && playerPositionY < gameHeight - 50) { playerPositionY += 15; // Move up } if (event.key === 'ArrowDown' && playerPositionY > 0) { playerPositionY -= 15; // Move down } if (event.key === ' ' && bullets.length < MAX_BULLETS) { // Check bullet limit shoot(); } player.style.bottom = playerPositionY + 'px'; // Update player position }); function shoot() { const bullet = document.createElement('div'); bullet.classList.add('bullet'); bullet.style.left = '40px'; // Set starting position of the bullet (right of player) bullet.style.bottom = (playerPositionY + 15) + 'px'; // Center bullet vertically with respect to the player bullets.push(bullet); aliensContainer.appendChild(bullet); updateBulletCount(); // Update bullet count when a bullet is shot } function updateBulletCount() { bulletCountDisplay.innerText = "Bullets Remaining: " + (MAX_BULLETS - bullets.length); if (bullets.length === MAX_BULLETS) { stopGame(); // Stop the game if bullets are used up } } function createAlien() { const alien = document.createElement('div'); alien.classList.add('alien'); const xPosition = Math.random() * (gameWidth - 50); alien.style.left = xPosition + 'px'; alien.style.top = '0px'; aliens.push(alien); aliensContainer.appendChild(alien); } function moveAliens() { for (let i = 0; i < aliens.length; i++) { const alien = aliens[i]; let alienTop = parseInt(alien.style.top); if (alienTop < gameHeight) { alien.style.top = (alienTop + 2) + 'px'; } else { aliensContainer.removeChild(alien); aliens.splice(i, 1); i--; } } } function moveBullets() { for (let i = 0; i < bullets.length; i++) { const bullet = bullets[i]; let bulletLeft = parseInt(bullet.style.left); if (bulletLeft < gameWidth) { bullet.style.left = (bulletLeft + 10) + 'px'; // Move bullet to the right } else { aliensContainer.removeChild(bullet); bullets.splice(i, 1); i--; updateBulletCount(); // Update bullet count when a bullet is removed } } } function checkCollision() { for (let i = 0; i < bullets.length; i++) { const bullet = bullets[i]; const bulletRect = bullet.getBoundingClientRect(); for (let j = 0; j < aliens.length; j++) { const alien = aliens[j]; const alienRect = alien.getBoundingClientRect(); if ( bulletRect.x < alienRect.x + alienRect.width && bulletRect.x + bulletRect.width > alienRect.x && bulletRect.y < alienRect.y + alienRect.height && bulletRect.y + bulletRect.height > alienRect.y ) { // Show blood splash effect at alien position showBloodSplashAtAlien(alien); score+=5; // Increment score scoreDisplay.innerText = "Score: " + score; // Remove the bullet and the alien from the DOM aliensContainer.removeChild(bullet); aliensContainer.removeChild(alien); bullets.splice(i, 1); // Remove bullet from array aliens.splice(j, 1); // Remove alien from array updateBulletCount(); // Update bullet count after hit i--; // Adjust index after removal break; } } } checkPlayerCollision(); // Check collision with player } function showBloodSplashAtAlien(alien) { const bloodSplash = document.createElement('div'); bloodSplash.classList.add('blood-splash'); bloodSplash.style.left = (alien.getBoundingClientRect().x + 'px'); // Position the splash at the alien's X position bloodSplash.style.top = (alien.getBoundingClientRect().y + 'px'); // Position the splash at the alien's Y position document.body.appendChild(bloodSplash); // Remove the blood splash after the animation ends setTimeout(() => { document.body.removeChild(bloodSplash); }, 500); // Adjust timing to match animation duration } function checkPlayerCollision() { const playerRect = player.getBoundingClientRect(); // Get player dimensions for (let alien of aliens) { const alienRect = alien.getBoundingClientRect(); // Get alien dimensions if ( playerRect.x < alienRect.x + alienRect.width && playerRect.x + playerRect.width > alienRect.x && playerRect.y < alienRect.y + alienRect.height && playerRect.y + playerRect.height > alienRect.y ) { playerLives--; // Reduce player life livesDisplay.innerText = "Lives: " + playerLives; // Update lives display showBloodSplash(); // Show blood splash effect // If player has no lives left, stop the game if (playerLives <= 0) { stopGame(); // Stop the game if the alien touches the player } break; } } } function showBloodSplash() { const bloodSplash = document.createElement('div'); bloodSplash.classList.add('blood-splash'); bloodSplash.style.left = (player.getBoundingClientRect().x + 10) + 'px'; // Position it near the player bloodSplash.style.top = (player.getBoundingClientRect().y + 10) + 'px'; // Position it near the player document.body.appendChild(bloodSplash); // Remove the blood splash after animation ends setTimeout(() => { document.body.removeChild(bloodSplash); }, 500); // Adjust timing according to the duration of your animation } function stopGame() { clearInterval(gameInterval); // Stop the game loop isGameOver = true; // Set game over flag gameOverDisplay.style.display = "block"; // Show game over message } function restartGame() { // Reset variables and clear game state score = 0; playerPositionY = (gameHeight / 2) - 25; // Reset player position bullets = []; aliens = []; playerLives = 3; // Reset player lives isGameOver = false; scoreDisplay.innerText = "Score: 0"; bulletCountDisplay.innerText = "Bullets Remaining: 20"; livesDisplay.innerText = "Lives: " + playerLives; // Reset lives display gameOverDisplay.style.display = "none"; // Hide game over message aliensContainer.innerHTML = ""; // Clear aliens and bullets gameInterval = setInterval(() => { if (Math.random() < 0.1) { createAlien(); } moveAliens(); moveBullets(); checkCollision(); }, 100); } gameInterval = setInterval(() => { if (Math.random() < 0.1) { createAlien(); } moveAliens(); moveBullets(); checkCollision(); }, 100);
Journey
I started with with plain rectangle and circle shapes for aliens and player. Then I used images to make the page more attractive.
Top comments (4)
Superb
wow!
👏
interesting