Skip to content

Commit

Permalink
Added Shadow Runner game
Browse files Browse the repository at this point in the history
  • Loading branch information
kosuri-indu committed Jul 28, 2024
1 parent f64e004 commit 3b1ac75
Show file tree
Hide file tree
Showing 6 changed files with 463 additions and 1 deletion.
60 changes: 60 additions & 0 deletions Games/Shadow_Runner/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# Shadow Runner

Shadow Runner is a simple browser-based game where the player must navigate through obstacles and collect power-ups to score points. The game area scrolls continuously, and the player must avoid obstacles while collecting power-ups to increase their score.

## Table of Contents

- [Gameplay](#gameplay)
- [Usage](#usage)
- [Controls](#controls)
- [Code Structure](#code-structure)

## Gameplay

- **Objective**: Avoid obstacles and collect power-ups to score points.
- **Scoring**:
- Yellow Squares: -5 points
- Green Triangles: +10 points
- Red Balls: +15 points
- Double points in darker areas

## Usage

1. Open `index.html` in your web browser to start the game.

## Controls

- Use the **Arrow** keys to move the player.

## Code Structure

- **HTML**: [index.html](index.html)
- Defines the game layout and elements.
- **CSS**: [style.css](style.css)
- Styles the game elements and animations.
- **JavaScript**: [script.js](script.js)
- Implements the game logic and interactions.

### Key JavaScript Functions and Variables

- **Variables**:
- `gameArea`: The main game area element.
- `player`: The player element.
- `startButton`: The button to start the game.
- `scoreDisplay`: The element displaying the score.
- `timeDisplay`: The element displaying the remaining time.
- `gameInterval`: The interval for the game loop.
- `lights`, `obstacles`, `powerUps`: Arrays to hold game elements.
- `isGameRunning`: Boolean indicating if the game is running.
- `score`: The player's score.
- `time`: The remaining time.

- **Functions**:
- `startGame()`: Starts the game.
- `resetGame()`: Resets the game state.
- `updateHUD()`: Updates the HUD with the current score and time.
- `moveElements()`: Moves game elements (lights, obstacles, power-ups).
- `updateGame()`: Updates the game state.
- `checkCollisions()`: Checks for collisions between the player and game elements.
- `gameOver(win)`: Ends the game and displays the win/lose message.
- `createLights()`, `createObstacles()`, `createPowerUps()`: Creates game elements.
35 changes: 35 additions & 0 deletions Games/Shadow_Runner/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Shadow Runner</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="game-container">
<div class="game-area" id="game-area">
<div class="background" id="background"></div>
<div class="player" id="player"></div>
<div class="win-message" id="win-message">Game Over</div>
<div class="lose-message" id="lose-message">Game Over</div>
</div>
<div class="hud">
<div class="score" id="score">Score: 0</div>
<div class="time" id="time">Time: 60</div>
</div>
<div class="controls">
<button id="start-button">Start Game</button>
</div>
<div class="instructions">
<h2>How to Play</h2>
<ul>
<li>Use <strong>Arrow</strong> keys to move the player.</li>
<li>Yellow Squares: -5 points, Green Triangles: +10 points, Red Balls: +15 points</li>
<li>Double points in darker areas</li>
</ul>
</div>
</div>
<script src="script.js"></script>
</body>
</html>
227 changes: 227 additions & 0 deletions Games/Shadow_Runner/script.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,227 @@
const gameArea = document.getElementById('game-area');
const player = document.getElementById('player');
const startButton = document.getElementById('start-button');
const background = document.getElementById('background');
const scoreDisplay = document.getElementById('score');
const timeDisplay = document.getElementById('time');
const winMessage = document.getElementById('win-message');
const loseMessage = document.getElementById('lose-message');

let gameInterval;
let lights = [];
let obstacles = [];
let powerUps = [];
let isGameRunning = false;
let score = 0;
let time = 60;

startButton.addEventListener('click', startGame);

function startGame() {
resetGame();
isGameRunning = true;
gameInterval = setInterval(updateGame, 20);
}

function resetGame() {
isGameRunning = false;
clearInterval(gameInterval);
lights.forEach(light => gameArea.removeChild(light));
obstacles.forEach(obstacle => gameArea.removeChild(obstacle));
powerUps.forEach(powerUp => gameArea.removeChild(powerUp));
lights = [];
obstacles = [];
powerUps = [];
score = 0;
time = 60;
updateHUD();
winMessage.style.display = 'none';
loseMessage.style.display = 'none';
player.style.top = '50%';
player.style.left = '50%';
createLights();
createObstacles();
createPowerUps();
}

function updateHUD() {
scoreDisplay.textContent = `Score: ${score}`;
timeDisplay.textContent = `Time: ${time}`;
}

function moveElements() {
lights.forEach((light, index) => {
const top = parseFloat(light.style.top);
if (top > gameArea.offsetHeight) {
gameArea.removeChild(light);
lights.splice(index, 1);
createLights();
} else {
light.style.top = `${top + 2}px`;
}
});

obstacles.forEach((obstacle, index) => {
const top = parseFloat(obstacle.style.top);
if (top > gameArea.offsetHeight) {
gameArea.removeChild(obstacle);
obstacles.splice(index, 1);
createObstacles();
} else {
obstacle.style.top = `${top + 2}px`;
}
});

powerUps.forEach((powerUp, index) => {
const top = parseFloat(powerUp.style.top);
if (top > gameArea.offsetHeight) {
gameArea.removeChild(powerUp);
powerUps.splice(index, 1);
createPowerUps();
} else {
powerUp.style.top = `${top + 2}px`;
}
});
}

function updateGame() {
moveElements();
checkCollisions();
updatePlayerPosition();
updateHUD();
}

function checkCollisions() {
const isShadowPresent = document.getElementById('background').classList.contains('shadow');
const player = document.getElementById('player');
const gameArea = document.getElementById('game-area');
const scoreElement = document.getElementById('score');

lights.forEach((light, index) => {
if (isColliding(player, light)) {
if (isShadowPresent) {
light.style.width = `${parseFloat(light.style.width) * 2}px`;
light.style.height = `${parseFloat(light.style.height) * 2}px`;
score -= 10;
} else {
score -= 5;
}
gameArea.removeChild(light);
lights.splice(index, 1);
createLights();
}
});

obstacles.forEach((obstacle, index) => {
if (isColliding(player, obstacle)) {
if (isShadowPresent) {
obstacle.style.width = `${parseFloat(obstacle.style.width) * 2}px`;
obstacle.style.height = `${parseFloat(obstacle.style.height) * 2}px`;
score += 30;
} else {
score += 15;
}
gameArea.removeChild(obstacle);
obstacles.splice(index, 1);
createObstacles();
}
});

powerUps.forEach((powerUp, index) => {
if (isColliding(player, powerUp)) {
if (isShadowPresent) {
powerUp.style.width = `${parseFloat(powerUp.style.width) * 2}px`;
powerUp.style.height = `${parseFloat(powerUp.style.height) * 2}px`;
score += 20; // Double score if shadow is present
} else {
score += 10;
}
gameArea.removeChild(powerUp);
powerUps.splice(index, 1);
createPowerUps();
}
});

scoreElement.textContent = `Score: ${score}`;
}

function isColliding(element1, element2) {
const rect1 = element1.getBoundingClientRect();
const rect2 = element2.getBoundingClientRect();

return !(
rect1.top > rect2.bottom ||
rect1.bottom < rect2.top ||
rect1.right < rect2.left ||
rect1.left > rect2.right
);
}

function updatePlayerPosition() {
if (keysPressed['ArrowUp']) {
player.style.top = `${Math.max(0, player.offsetTop - 5)}px`;
}
if (keysPressed['ArrowDown']) {
player.style.top = `${Math.min(gameArea.offsetHeight - player.offsetHeight, player.offsetTop + 5)}px`;
}
if (keysPressed['ArrowLeft']) {
player.style.left = `${Math.max(0, player.offsetLeft - 5)}px`;
}
if (keysPressed['ArrowRight']) {
player.style.left = `${Math.min(gameArea.offsetWidth - player.offsetWidth, player.offsetLeft + 5)}px`;
}
}

const keysPressed = {};
window.addEventListener('keydown', event => {
keysPressed[event.key] = true;
});
window.addEventListener('keyup', event => {
delete keysPressed[event.key];
});

function gameOver(win) {
isGameRunning = false;
clearInterval(gameInterval);
if (win) {
winMessage.style.display = 'block';
} else {
loseMessage.style.display = 'block';
}
}

setInterval(() => {
if (isGameRunning && time > 0) {
time--;
updateHUD();
} else if (isGameRunning && time <= 0) {
gameOver(true);
}
}, 1000);

function createLights() {
const light = document.createElement('div');
light.className = 'light';
light.style.top = '0px';
light.style.left = `${Math.random() * (gameArea.offsetWidth - 100)}px`;
gameArea.appendChild(light);
lights.push(light);
}

function createObstacles() {
const obstacle = document.createElement('div');
obstacle.className = 'obstacle';
obstacle.style.top = '0px';
obstacle.style.left = `${Math.random() * (gameArea.offsetWidth - 30)}px`;
gameArea.appendChild(obstacle);
obstacles.push(obstacle);
}

function createPowerUps() {
const powerUp = document.createElement('div');
powerUp.className = 'power-up';
powerUp.style.top = '0px';
powerUp.style.left = `${Math.random() * (gameArea.offsetWidth - 40)}px`;
gameArea.appendChild(powerUp);
powerUps.push(powerUp);
}
Loading

0 comments on commit 3b1ac75

Please sign in to comment.