Concept
What happens when you are swamped with work and all you can think about is the upcoming deadlines? You code your way out of it of course! For this assignment, I was fueled by the fascination I have always had with shooting games. And the enforced time during my injury allowed me to subtly “elevate” my game. I played with the underlying phenomenon of something that we go through on a daily basis and that is getting work done, be it creative or otherwise. And even though the task came with its fair share of challenges, the end result was a sweet surprise.
Here it is,
Workings of the Game
The game primarily consists of three main characters-the player (worker), the bullets (finished work), and the enemies (deadlines). These at first glance seemed like bland soup (even to me), but they got polished as I played around with my concept and the game progressed. I started off simply by placing basic shapes on the screen and tweaking their movements. The player was initially an ellipse tracing the cursor and was changed into a loaded gif. Similarly, images were loaded and adjusted in the place of bullets and enemies that were circles and rectangles respectively.
Picking up from there, for each character, I initially coded functions. like this bullet and its draw function.
let bullets = []; function setup() { createCanvas(400, 400); } function draw() { noCursor(); background(220); rectMode(CENTER); let xc = constrain(mouseX, 15, 385); // player position let player = { x: constrain(mouseX, 15, 385), y: height - 50 }; circle(player.x, player.y, 25); drawBullet(); } // function to draw bullets function drawBullet() { for (let bullet of bullets) { bullet.y -= 10; // bullet moves up circle(bullet.x, bullet.y, 10); } } function mousePressed() { let bullet = { x: constrain(mouseX, 15, 385), y: 350, }; bullets.push(bullet); }
But later on, it seemed like a better choice to transform the program into an OOP as it allowed me to have a fixed set of operations on things, and as the code evolved I could add new things and attributes. I also went through a couple of resources to get a gist of how shooting games work wherein Dan Shiffman’s coding challenge on space invaders provided me with a broad idea about the concept that was being implemented in my code. The idea of loading various classes as separate p5js files in the main sketch was something remarkable that I picked up from this video that helped me to efficiently visualize and tidy my code.
Challenges
One of the portions of the code that took me some time to figure out was how to prevent the objects from trailing off of the screen. Finally, I added the constrain function as shown in the code below to fix the movement of my player as well as the bullets.
class Bullet { constructor() { let xc = constrain(mouseX, 45, 335) this.x = xc this.y = 350; }
class Player { constructor () { this.x = width/2; this.y = height - 50; } display() { imageMode(CENTER); image(gif_player, this.x, this.y, 170, 170); } move (){ let xc = constrain(mouseX, 45, 335) this.x = xc this.x = xc + 5; } }
Secondly, creating a single object within OOP was relatively easy but I had to go back and forth while figuring out how to place an array of objects within OOP. The basic reference list on the main p5js website helped me in implementing it.
Moreover, this bit was among the bigger challenges that I encountered. After I had added the collision between my bullet and the enemy through splice to remove the abovementioned objects from their arrays, the enemies just stopped appearing on the screen. A setInterval function for spawning new enemies had to be added to fix this.
function setup() { createCanvas(400, 400); // loop for player myPlayer = new Player(); // spawning new enemies setInterval(() => { enemies.push(new Enemy()); }, random(500, 1000)); } // end of setup function
Lastly, it took me a while to place my entire game within game states. I initially began by assigning the game state as a variable and then added different values so that every time the game is played the game state functions get smoothly called. In a way, the entire game became a combination of functions and OOP wherein different object classes interacted with the game states within the code. And the entire draw function was just primarily coded to call the game states. But as the game ended, the start screen was not becoming visible without refreshing the page. By referring to the p5js code samples provided in the lecture notes I realized that I had to add a separate restart function to make it work.
function restartGame() { // Reset character position, lives, etc gameState = 0; enemies = []; bullets = []; score = 0; } function draw() { background(210); // game gtates and their functions defined and called if (gameState == 0) { startGame(); } else if (gameState == 1) { playGame(); } else if (gameState == 2) { finishGame(); } } // end of draw function
Reflections
In the future, I would also like to work with sound and loading different backgrounds for each screen. I am also a bit worried that after a certain point the generation of new enemies that are being pushed may become uncontrollable, especially when the program keeps running on the page, and for that, I would have to further think and code in functions such as framerate and millis. Nonetheless, this assignment genuinely gave me a chance to tap into the academic as well as the creative side of interactive media. It feels like a win-win.