Inspiration
The idea is creating a top-down shooter game. I was inspired by Nuclear Throne, where players control a character in a confined space and must shoot incoming enemies. The thrill of dodging enemies while strategically shooting at them creates an engaging and fast-paced gameplay experience. The goal was to recreate this immersive feeling while keeping the implementation simple and beginner-friendly using p5.js.
Concept and User Interaction
The game concept revolves around a player-controlled character that moves around the screen and shoots at enemy units that spawn randomly and chase the player. The user can interact with the game in the following ways:
- Movement: The player uses the arrow keys or WASD to move in different directions.
- Shooting: The player shoots bullets towards the mouse cursor by pressing the spacebar.
- Enemies: Randomly spawned enemies move towards the player and can be destroyed by bullets.
- Survival Challenge: The player must continuously avoid enemies while shooting them down.
This simple yet engaging mechanic ensures a dynamic game experience where quick reflexes and strategic positioning are key to survival.
Designing the Code Structure
Before diving into the code, I designed a modular approach to keep the project manageable and scalable. The core elements of the game were broken down into:
- Player Class: Handles movement, shooting, and rendering.
- Bullet Class: Manages bullet behavior, movement, and collision detection.
- Enemy Class: Controls enemy spawning, movement, and interaction with bullets.
- Game Loop: Updates and renders all game elements in each frame.
- Collision Handling: Detects when bullets hit enemies and removes them from the game.
- Enemy Spawning System: Ensures a steady challenge for the player.
By structuring the game this way, each component is easy to manage and modify.
Example – Player Class:
class Player { constructor() { this.pos = createVector(width / 2, height / 2); this.speed = 4; } update() { if (keyIsDown(UP_ARROW) || keyIsDown(87)) this.pos.y -= this.speed; if (keyIsDown(DOWN_ARROW) || keyIsDown(83)) this.pos.y += this.speed; if (keyIsDown(LEFT_ARROW) || keyIsDown(65)) this.pos.x -= this.speed; if (keyIsDown(RIGHT_ARROW) || keyIsDown(68)) this.pos.x += this.speed; this.pos.x = constrain(this.pos.x, 0, width); this.pos.y = constrain(this.pos.y, 0, height); } show() { fill(0, 255, 0); ellipse(this.pos.x, this.pos.y, 30, 30); } shoot() { if (millis() - lastShotTime > 200) { bullets.push(new Bullet(this.pos.x, this.pos.y)); lastShotTime = millis(); } } }
Identifying and Addressing Key Challenges
One of the most challenging parts of the project is collision detection between bullets and enemies. Ensuring that fast-moving bullets accurately register hits on enemies can be tricky, especially in a game with rapid movement and frequent object interactions. Also, I wanted to add a multiplayer gameplay experience, so 2 players could play in the same session. However, I do not think it is possible without the use of socket.io.
Next Steps
Moving forward, possible improvements could include:
- Adding different enemy types with unique behaviors.
- Implementing a score system to track progress.
- Introducing power-ups to enhance gameplay variety.
- Multiplayer Mode: Implementing real-time multiplayer gameplay using Socket.IO so that two players can play together from different machines. This would involve syncing player movement, bullets, and enemies across connected clients through a Node.js server.
By integrating multiplayer functionality, the game could become even more engaging and interactive. Using real-time communication, players could strategize together, compete for the highest score, or even introduce cooperative play against waves of enemies. Setting up server-side logic to handle multiple players efficiently is a challenge but would greatly enhance the gaming experience.