DEV Community

Cover image for Aliens and Me!!
Jotty John
Jotty John

Posted on

Aliens and Me!!

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>
Enter fullscreen mode Exit fullscreen mode

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;
}
Enter fullscreen mode Exit fullscreen mode

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);
Enter fullscreen mode Exit fullscreen mode

img/alien.png
Image description

img/blood-splash.png
Image description

img/bullet.png
Image description

img/player.png
Image description

img/star.jpg
Image description

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)

Collapse
 
tanay_joseph_3089b98cb360 profile image
Tanay Joseph

wow!

Collapse
 
johan_rosesunil_a078d554 profile image
Johan Rose Sunil

Superb

Collapse
 
r_5b14fc53c9ffcc999c28fa5 profile image
R

👏

Collapse
 
tate profile image
tantess

interesting