Final Project:
Idea Refinement:
Since my Midterm Progress report, these were the things I mentioned I still had to do
- Create the food items and their specific data
- I have to animate Luffy’s movements
- I have to work on collision detection with Luffy and the Food objects and the Platform objects.
- Add a time countdown
- Create an ending screen (depending on whether the user wins/loses)
- Allow the user to restart or go back to the Main Menu.
Initially, my game idea was to have a 1 min timer and you had to feed Luffy by keeping his hunger bar above 0. If you fail to do so within that 1 min, you lose, if you can, then you win. However, I did not like this idea so much because it felt like you could easily defeat every difficulty of the game easily and then that’s it, you’re officially done with the game. No need to play anymore.
Hence, I decided to change the structure of my game from this idea to a High-score type game. So essentially in my new idea, there is no more time countdown. There’s still a depleting hunger bar and the goal is to keep feeding luffy by jumping around and eating different kinds of food. Depending on the food item, the more points you get and you gotta try and get the highest possible score you can. The same difficulty settings apply, the greater the difficulty, the faster the hunger bar depletes.
I thought this new idea for the game was so much better because then it brings that addictive nature of “I want to beat my high-score” and allows the user to actually feel rewarded after getting a better score, rather than simply feeding Luffy for 1 min.
Project Structure:
For my code, I decided to implement a screen state system. So, I would have variables for different screen states whether it was for the Main Menu, Instruction Screen, Difficulty Screen, Game Screen or End Screen. Depending on what the user clicks on, it will direct them to that particular screen. This way, my draw function is very simple to understand as it just calls one function depending on the screen state.
For my project structure, I organized all of my coding files in a very specific way. For instance, I have a .js file for:
- The main skecth.js = contains the setup() and draw() functions
- A screens.js = contains the functions to display all the types of screens depending on the screen state.
- A game.js = contains all the necessary functions related to the actual game (game settings)
- A classes.js = contains all the classes that are used in my code. This includes the Luffy class, Food class, Platform class.
Sections i’m proud of:
I would say i’m particularly very proud of Luffy’s animations because that was the part I worked the hardest on and looks the cleanest in my opinion.
So for Luffy’s movements, I had to get a sprite sheet from the internet, and I found one that I really liked:
However the challenge with this sprite sheet was that it wasn’t evenly divided, so I had to manually divide the sheet myself into four and load those into the code as 4 seperate sprite sheets. Then since they have different widths, I had to divide them equally depending on their width to which some of them weren’t, hence I had to resplit the frames and resize the sprites several times which was quite annoying but at the end I got it to work.
Eventually, I managed to create a test code which works based on the arrow keys. So if you were to press RIGHT_ARROW, then the Running Right sprites would start cycling and so on depending on the directions. Additionally, if no keys were pressed, I would cycle through Luffy’s standing movements which make it seem more realistic.
I also had to animate the jump feature which was quite tricky to think of. After watching certain videos, I realized I would have to incorporate a sort of “gravity”, hence:
jump_settings() {
this.velocity += this.gravity;
this.y += this.velocity;
//This ensures that Luffy is always above this.platform (including the ground which is what it is initialized to). Depending on what he's standing on, this.platform will change.
if(this.y > this.level) {
this.velocity = 0;
this.y = this.level;
if(keyIsDown(LEFT_ARROW) && keyIsDown(UP_ARROW)) {
this.velocity += this.boost;
Jump_Sound.play();
}
else if(keyIsDown(UP_ARROW) && keyIsDown(RIGHT_ARROW)) {
this.velocity += this.boost;
Jump_Sound.play();
}
else if(keyIsDown(UP_ARROW)) {
this.velocity += this.boost;
Jump_Sound.play();
}
}
}
This is specifically a function taken from Luffy’s jump class which monitors his jump settings. To essentially I have gravity set to some value (0.3). This will keep adding onto Luffy’s y coordinate to keep him grounded. If he goes beyond a certain y level (aka the ground), that will push him up.
Essentially, if any of the up arrow combinations are pressed, it would give Luffy a jump boost which is some value (10) and this is like how high luffy jumps. We add that to Luffy’s velocity which is essentially like the speed at which he is jumping and then at a certain peak point, since gravity is constantly pulling Luffy down, it will overcome the velocity value and drag him back down.
So overall, in my test code I was able to create this (controllable with the arrow keys):
Overall, i’m very happy with how Luffy’s animations turned out. It honestly feels like a real game which is so cool.
Other additions (Interactivity):
For the food class, I essentially added different 5 different foods, each of which having different “hunger points”:
- Bone Meat = 200hp (Luffy’s Favourite)
- Fried Rice = 150hp
- Cake = 100hp
- Vegetables = 50hp
- Devil Fruit = -50hp.
I thought it would be cool to add a food item that would deplete his hunger even further to make it more challenging. Plus it adds to the theme of the show because Devil Fruits make you weaker in the water.
So the food items would spawn only on platforms so I had to make sure that they interact with the Platform class by retrieving its coordinates and spawning them on it. I would spawn them at different rates depending on the difficulty, so if it’s harder, more food should spawn quickly to keep up with the depleting hunger bar.
For the platform class, this was the most challenging because I had to make sure the collision detection for all platforms worked for Luffy and honestly this was the most challenging part.
Challenging Bits and Improvements:
So for the Platform class, I added several platforms onto the screen and I also decided to add a moving platform to make it more interesting. Some of the problems I ran into were with regards to Luffy landing on the platform or his head hiting the platform. It was tricky because as Luffy moved, his coordinates did not exactly match with the coordinates of the platform. Since the platform coordinates are in integers and Luffy’s are in floating points, it never equaled each other.
This was quite challenging, so to fix this, I added a range. So, if Luffy’s coordinates were somewhere in the very small range of the platforms coordinates, then he should be able to stand on it.
It was also difficult to know which platform Luffy was standing on because although Luffy would be in the specific range of being above a platform, it’s difficult to know which platform exactly because the for loop is cycling through all platforms. Hence, to fix this, I saved the x coordinate of the platform Luffy is currently standing on and kept checking, if he left that platform, then make gravity act on him to the Ground.
The moving platform was the most annoying to deal with because its x coordinates constantly moved, so I had to create another if statement for that independently to check if Luffy was on it or not.
Here’s the collision function for that:
//This function checks the collision of Luffy with all of the platforms. It checks if his head hits the platforms that he stays under it. If his feet touch the platform, he will stay on it.
platform_collide(platform, moving_p) {
//Checks if Luffy's head hits a platform.
if(this.y-this.height/2 >= platform.y && this.y-this.height/2 <= platform.y+platform.h && this.x >= platform.x && this.x <= platform.x+platform.w) {
this.y = (platform.y+platform.h) + this.height/2;
}
//Checks if Luffy's feet are on the platform.
if(this.x >= platform.x && this.x <= platform.x+platform.w && this.y+this.height/2 >= platform.y && this.y+this.height/2 <= platform.y+platform.h) {
this.level = platform.y - this.height/2; //this makes platform y coordinate the new ground
this.platform_x = platform.x;
this.platform_w = platform.w;
}
//This gets the saved platform that Luffy is currently on's x coordinate and width and checks if he is outside the range of the width of the platform. If so, then he will fall to the ground.
else if(this.x <= this.platform_x || this.x >= this.platform_x+this.platform_w) {
this.level = Ground;
}
//This is specifically for the moving platform, since it has constantly changing x coordinates, it has a seperate if statement check. If Luffy is outside the range of its level, he will fall.
if((this.x <= moving_p.x || this.x >= moving_p.x+moving_p.w) && this.y+this.height/2 == moving_p.y){
this.level = Ground;
}
}
I honestly think there is much room for improvement in this function. Because although it works, it doesn’t seem very elegant to me. Additionally, I haven’t included any collision in terms of Luffy’s sides with any of the platforms, only his head and feet because they were the main ones. Hence, this can definitely be an improvement.
Overall Thoughts:
This was a very long blog post but honestly it’s because I had so much to say. To be honest I don’t even feel like i’ve said everything because there are so many fine details with every single function and class in this game. I felt like I was proud of so many aspects of my code but I only put a few because this would be extremely long then XD.
I think that’s enough to say that I genuinely enjoyed making this code. Gaming has always been a passion of mine and game development is a field i’d love to get in so this entire project was amazing. It’s also why I put so much effort into every little tiny component.
I think the execution of everything is really well organized and the game is very fun and addictive (trust me i’ve played it several times) so I would say that i’m very happy with my midterm project.