Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions examples/javascript_game/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# JavaScript-Game
# Survive the Horde 🧟‍♂️

A simple JavaScript + p5.js survival shooter game where you must defend yourself from endless waves of enemies approaching from all directions. Use your reflexes to shoot and survive as long as possible!

---

## 🎮 How to Play

- Use **Arrow Keys** to move the player.
- Press **Spacebar** to shoot bullets in all four directions.
- Each enemy (zombie) destroyed increases your **score**.
- The game ends when an enemy touches you.
- Your final score will be displayed when the game is over.

---

## 🧠 Game Logic Overview

- The player (blue square) stays within the play area.
- Enemies (green squares) continuously spawn and move toward the player.
- Bullets (yellow dots) move outward when you press the Spacebar.
- The game tracks:
- Active enemies
- Bullets fired
- Collision detection (bullet–enemy and enemy–player)
- Score updates and game-over logic

---

## 🧩 Technologies Used

- **HTML5** — structure of the game page
- **CSS3** — simple dark theme and game layout
- **JavaScript (ES6)** — game logic, movement, and collisions
- **[p5.js](https://p5js.org/)** — for rendering and animation loop

---

## 🚀 How to Run Locally

### Option 1 — Run with VS Code (Recommended)
1. Open this folder in VS Code
2. Right-click `index.html`
3. Choose **“Open with Live Server”**
4. Play at `http://127.0.0.1:5500/examples/javascript_game/`

### Option 2 — Run with Node.js
```bash
cd examples/javascript_game
npx serve

34 changes: 34 additions & 0 deletions examples/javascript_game/game.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}

body {
background: black;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
overflow: hidden;
}

#gameContainer {
position: relative;
}

canvas {
background: #222;
display: block;
border: 2px solid white;
}

#score {
position: absolute;
top: 10px;
left: 50%;
transform: translateX(-50%);
font-size: 20px;
color: white;
}

229 changes: 229 additions & 0 deletions examples/javascript_game/game.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,229 @@
const canvas = document.getElementById("gameCanvas");
const ctx = canvas.getContext("2d");

canvas.width = 800;
canvas.height = 600;

class Player {
constructor() {
this.reset();
}

reset() {
this.x = canvas.width / 2;
this.y = canvas.height / 2;
this.size = 30;
this.color = "cyan";
this.speed = 5;
}

draw() {
ctx.fillStyle = this.color;
ctx.fillRect(this.x, this.y, this.size, this.size);
}

move(dirX, dirY) {
if (this.x + dirX >= 0 && this.x + this.size + dirX <= canvas.width) {
this.x += dirX;
}
if (this.y + dirY >= 0 && this.y + this.size + dirY <= canvas.height) {
this.y += dirY;
}
}
}

class Bullet {
constructor(x, y, dirX, dirY) {
this.x = x;
this.y = y;
this.size = 8;
this.color = "yellow";
this.speed = 15; // ✅ Increased bullet speed
this.dirX = dirX;
this.dirY = dirY;
}

update() {
this.x += this.dirX * this.speed;
this.y += this.dirY * this.speed;
}

draw() {
ctx.fillStyle = this.color;
ctx.fillRect(this.x, this.y, this.size, this.size);
}
}

class Zombie {
constructor(x, y) {
this.x = x;
this.y = y;
this.size = 35;
this.color = "green";
this.speed = 1.5;
}

update(targetX, targetY) {
let dx = targetX - this.x;
let dy = targetY - this.y;
let distance = Math.sqrt(dx * dx + dy * dy);

if (distance > 0) {
this.x += (dx / distance) * this.speed;
this.y += (dy / distance) * this.speed;
}
}

draw() {
ctx.fillStyle = this.color;
ctx.fillRect(this.x, this.y, this.size, this.size);
}
}

let player = new Player();
let bullets = [];
let zombies = [];
let score = 0;
let keys = {};
let gameRunning = true;
let zombieSpawnInterval;

function spawnZombie() {
let side = Math.floor(Math.random() * 4);
let x, y;

if (side === 0) {
x = Math.random() * canvas.width;
y = 0;
} else if (side === 1) {
x = Math.random() * canvas.width;
y = canvas.height;
} else if (side === 2) {
x = 0;
y = Math.random() * canvas.height;
} else {
x = canvas.width;
y = Math.random() * canvas.height;
}

zombies.push(new Zombie(x, y));
}

function startZombieSpawn() {
clearInterval(zombieSpawnInterval);
zombieSpawnInterval = setInterval(spawnZombie, 1000);
}

function update() {
if (!gameRunning) return;

ctx.clearRect(0, 0, canvas.width, canvas.height);

if (keys["ArrowLeft"]) player.move(-player.speed, 0);
if (keys["ArrowRight"]) player.move(player.speed, 0);
if (keys["ArrowUp"]) player.move(0, -player.speed);
if (keys["ArrowDown"]) player.move(0, player.speed);

player.draw();

bullets.forEach((bullet, bulletIndex) => {
bullet.update();
bullet.draw();

if (bullet.x < 0 || bullet.x > canvas.width || bullet.y < 0 || bullet.y > canvas.height) {
bullets.splice(bulletIndex, 1);
}
});

zombies.forEach((zombie, zombieIndex) => {
zombie.update(player.x, player.y);
zombie.draw();

if (
player.x < zombie.x + zombie.size &&
player.x + player.size > zombie.x &&
player.y < zombie.y + zombie.size &&
player.y + player.size > zombie.y
) {
gameOver();
}

bullets.forEach((bullet, bulletIndex) => {
if (
bullet.x < zombie.x + zombie.size &&
bullet.x + bullet.size > zombie.x &&
bullet.y < zombie.y + zombie.size &&
bullet.y + bullet.size > zombie.y
) {
zombies.splice(zombieIndex, 1);
bullets.splice(bulletIndex, 1);
score += 10;
updateScoreboard();
}
});
});

requestAnimationFrame(update);
}

function gameOver() {
gameRunning = false;
clearInterval(zombieSpawnInterval);
setTimeout(() => {
alert("Game Over! Your Final Score: " + score);
restartGame();
}, 100);
}

function restartGame() {
player = new Player();
bullets = [];
zombies = [];
score = 0;
updateScoreboard();
keys = {};
gameRunning = true;
startZombieSpawn();
update();
}

function updateScoreboard() {
document.getElementById("score").innerText = "Score: " + score;
}

// Remove old event listeners before adding new ones
document.removeEventListener("keydown", handleKeyDown);
document.removeEventListener("keyup", handleKeyUp);

function handleKeyDown(e) {
keys[e.key] = true;

if (e.key === " ") {
fireBullets(); // ✅ Fires multiple bullets
}
}

function handleKeyUp(e) {
keys[e.key] = false;
}

// ✅ Shoots 3 bullets in different directions
function fireBullets() {
let directions = [
{ dx: 1, dy: 0 }, // Right
{ dx: 0, dy: -1 }, // Up
{ dx: -1, dy: 0 }, // Left
{ dx: 0, dy: 1 } // Down
];

directions.forEach(dir => {
bullets.push(new Bullet(player.x + player.size / 2, player.y + player.size / 2, dir.dx, dir.dy));
});
}


document.addEventListener("keydown", handleKeyDown);
document.addEventListener("keyup", handleKeyUp);

startZombieSpawn();
update();
42 changes: 42 additions & 0 deletions examples/javascript_game/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Survive the Horde</title>
<link rel="stylesheet" href="game.css">
<style>
#instructions {
width: 300px;
padding: 15px;
background-color: rgba(0, 0, 0, 0.8);
color: white;
border-radius: 10px;
position: absolute;
top: 20px;
left: 20px;
font-family: Arial, sans-serif;
}
</style>
</head>
<body>
<div id="gameContainer">
<canvas id="gameCanvas"></canvas>
<div id="score">Score: 0</div>
</div>
<div id="instructions">
<h2>How to Play</h2>
<ul>
<li>Use <strong>Arrow Keys</strong> to move the player.</li>
<li>Press <strong>Space</strong> to shoot in four directions.</li>
<li>Survive as long as possible against incoming zombies.</li>
<li>Shooting zombies increases your score.</li>
<li>Getting touched by a zombie ends the game.</li>
</ul>
</div>
<script src="game.js"></script>
</body>
</html>