Midterm Report
Link to Project: https://editor.p5js.org/corbanvilla/full/nXKMcC8T7
Overall Concept
My project is created as a project after an article I wrote for The Gazelle newspaper a couple of years ago, commenting on the often toxic hustle cultured exhibited by NYUAD students. For instance, students often carry around their various responsibilities, commitments, and academic struggles as “badges” that provide social status. In other words, the busier you appear to be, and the less sleep you are getting, the more you are seen as “successful” in our hustle culture. While this type of problem is obviously cannot be generalized to all students, it is certainly applicable to a sizable subset, in my experience. Looking back through my time at NYUAD, there are definitely times where I see myself falling into this trap of quantity over quality.
My project, “Drowning @ NYUAD,” brings this phenomena to life, exaggerating the absurdity of students drowning in commitments. The scoring system of the game is measured in negative hours of sleep–the longer you play, the more sleep you miss. Better scores are proportional to less sleep.
Project Architecture
The architecture of the project was important to me, to ensure that all parts of the code are modular and easily reusable. To that end, all screens of the game are split into different JavaScript files, under the “/screens” subdirectory. They are then imported into the global context under the “index.html” file, and registered into the screen controller in “sketch.js.” Speaking of which, the screen controller (ScreenController class) provides a screen rendering management interface, equipped with a transition animation feature and a “nextScreen” callback function.
To utilize this modularity, screens are “registered” in the order that they should be used in “sketch.js.” Each screen receives a callback function, exposed by the screen controller, that allows any screen to trigger a transition to the next screen at any time. This allowed me to focus on each screen in isolation, without worrying about how screens may overlap or interfere with each other. Furthermore, each screen class then exposes it’s own “draw” method, that is only called when the screen is active. Otherwise, resources are not wasted rendering a background screen. An example of this is shown below:
screenController = new ScreenController();
let nextScreenCallback = screenController.nextScreen.bind(screenController);
screenController.registerScreen(new SplashScreen(nextScreenCallback, gameConfig));
screenController.registerScreen(new CharacterSelectScreen(nextScreenCallback, gameConfig));
screenController.registerScreen(new WeaponSelectScreen(nextScreenCallback, gameConfig));
screenController.registerScreen(new GameScreen(nextScreenCallback, gameConfig));
screenController.registerScreen(new GameOverScreen(nextScreenCallback, gameConfig));
screenController = new ScreenController();
let nextScreenCallback = screenController.nextScreen.bind(screenController);
screenController.registerScreen(new SplashScreen(nextScreenCallback, gameConfig));
screenController.registerScreen(new CharacterSelectScreen(nextScreenCallback, gameConfig));
screenController.registerScreen(new WeaponSelectScreen(nextScreenCallback, gameConfig));
screenController.registerScreen(new GameScreen(nextScreenCallback, gameConfig));
screenController.registerScreen(new GameOverScreen(nextScreenCallback, gameConfig));
screenController = new ScreenController();
let nextScreenCallback = screenController.nextScreen.bind(screenController);
screenController.registerScreen(new SplashScreen(nextScreenCallback, gameConfig));
screenController.registerScreen(new CharacterSelectScreen(nextScreenCallback, gameConfig));
screenController.registerScreen(new WeaponSelectScreen(nextScreenCallback, gameConfig));
screenController.registerScreen(new GameScreen(nextScreenCallback, gameConfig));
screenController.registerScreen(new GameOverScreen(nextScreenCallback, gameConfig));
A new JavaScript feature I stumbled upon whilst creating this feature is the “.bind” method. It appeared as an autocomplete suggestion from GitHub copilot while I was writing the code itself. I did not know what “.bind” did, so I asked ChatGPT how it works. It explained that it creates a version of the function, which binds internal references to “.this” to the object it belongs to. Thus, called “.bind” allows me to pass this screen transition function to the various screens. Then, when they call the transition, it will successfully refer to the ScreenController class instance.
Areas for Improvement
One area for improvement that I have identified is a desire to improve the artwork in the game. For instance, while one character is animated, I want to enable the rest of the characters to be animated. Furthermore, I want to animate some of the weapons, such as the triangle ruler, to make it spin as it flies through the air.
I would also like to work on the difficulty of the game. While monsters do begin to spawn faster as time goes on, I want the player’s speed and ammunition speed to also increase, allowing the player to more successfully reach longer stages of the game. Furthermore, I think that power-up abilities, such as those in Mariokart, could be interesting to make the game a bit more balanced.
Screenshots
Here are a few screenshots from the available game screens:
