From a212b9751ac6bba0fb8b617b08b1af034c4cb437 Mon Sep 17 00:00:00 2001 From: Karthikeya1500 Date: Mon, 10 Nov 2025 21:52:55 +0530 Subject: [PATCH] Add new p5.js example: Survive the Horde --- examples/javascript_game/README.md | 52 +++++++ examples/javascript_game/game.css | 34 +++++ examples/javascript_game/game.js | 229 ++++++++++++++++++++++++++++ examples/javascript_game/index.html | 42 +++++ 4 files changed, 357 insertions(+) create mode 100644 examples/javascript_game/README.md create mode 100644 examples/javascript_game/game.css create mode 100644 examples/javascript_game/game.js create mode 100644 examples/javascript_game/index.html diff --git a/examples/javascript_game/README.md b/examples/javascript_game/README.md new file mode 100644 index 0000000000..c95a8eaca9 --- /dev/null +++ b/examples/javascript_game/README.md @@ -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 + diff --git a/examples/javascript_game/game.css b/examples/javascript_game/game.css new file mode 100644 index 0000000000..efc84be694 --- /dev/null +++ b/examples/javascript_game/game.css @@ -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; +} + diff --git a/examples/javascript_game/game.js b/examples/javascript_game/game.js new file mode 100644 index 0000000000..2a475054fe --- /dev/null +++ b/examples/javascript_game/game.js @@ -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(); diff --git a/examples/javascript_game/index.html b/examples/javascript_game/index.html new file mode 100644 index 0000000000..e1acb049db --- /dev/null +++ b/examples/javascript_game/index.html @@ -0,0 +1,42 @@ + + + + + + Survive the Horde + + + + +
+ +
Score: 0
+
+
+

How to Play

+ +
+ + + + + +