Overall Concept:
“Save Polar Bears” is a game designed to raise awareness of the impacts of climate change on the ecosystem of polar bears. It is an interactive game yet educational in a sense that it teaches you the real ongoing situation for polar bears. The reason why I made this game is I’ve been super passionate about climate change and I love polar bears since I was a child. I have been doing research about climate change since high school and I found out that polar bears are struggling with hunting due to the melting icebergs. Thus, I incorporated this situation as a main theme of this game: polar bears need to eat as many fish as possible to survive while running away from melting icebergs.
How my project works:
My game is simple. The user’s mission is to collect as many fish as possible without falling into the ocean. The field is made of a 10 X 10 grid representing icebergs. One of the icebergs is randomly chosen every 3 seconds to melt. But here is the tricky part that I’m proud of: every 2 seconds, the temperature increases, as shown in the top-left corner by the temperature parameter. The higher the temperature becomes, the faster the icebergs melt. However, there is also a power-up that appears every 7 seconds. If you pick it up, two icebergs will be restored. So, users have to figure out how to collect as many fish as possible while also restoring icebergs at the same time.
Users can also learn about why we need to save polar bears from climate change by selecting the “Why Save Polar Bears?” button. I wanted to include this feature to educate people about the real situation affecting polar bears and their ecosystem due to the impacts of climate change.
The part of the game design I am proud of:
The part of the game design I’m most proud of is the gimmick where, as the temperature rises, more icebergs start to melt. I wanted to create a feature that reflects the real effects of climate change on the ecosystem of polar bears, and the idea of rising temperatures causing ice to melt felt the most meaningful and engaging to me. It represents what is happening in the Arctic Ocean, where polar bears are struggling to hunt their prey due to the rapid melting of icebergs.
The problems I ran into & Future improvements:
The most challenging problem I ran into during the production of this game was definitely adjusting everything to full-screen mode. Since I am using 10 X 10 grids, it is not very suitable for a full-screen game, especially if you are using a laptop with varying screen sizes. Therefore, I had to calculate everything to make it fit properly in full-screen mode. For instance, I had to make the polar bear slightly larger when using full-screen mode by including fullscreen() in the if statement and multiplying the polar bear’s size by 1.4. I also had to resize each button depending on if users are in fullscreen mode or not using a ternary operator. But, I was able to learn how to use a ternary operator instead of using if statements again and again, so it was a good learning experience for me to make the code more readable.
In terms of future improvements, I would like to add more interactive features to the game. For example, I was planning to include a feature where polluted garbage is scattered around the field, and if the polar bear collects three pieces of garbage, it dies. However, since I didn’t have enough time to implement it this time, I would like to add that feature later to incorporate more elements related to climate change. Furthermore, in terms of implementation details, since I had to manually calculate the sizes of the polar bear, fish, power-ups, etc., to match the full screen, I would like to adjust them more precisely next time to improve the user experience. Currently, if you touch the tip of a melted iceberg, it immediately results in a game over. I want to modify this so that players can slightly touch the edge of melted icebergs without immediately losing, as it can be confusing when they feel they didn’t actually fall into the ocean but still lose the game.
The part of code I’m most proud of:
The part of the code that I’m most proud of is the GameManager class. This is the core of how the game works. It contains the addFish() function, which makes fish appear at random locations and adds them to the fish array for display. It also includes the addPowerups() function, which works similarly to addFish(). Furthermore, the fillWithIcebergs() function creates 10 X 10 grids by precisely calculating the position of each iceberg using the nested loops we learned in class.
I also spent a lot of time designing the isOver() function, which is the core mechanic of the game. It checks whether the polar bear has stepped on a melted iceberg. To determine whether an iceberg has melted, I created a Boolean variable called melted to indicate which ones are completely melted. In the isOver() function, I used an if statement to only check the melted icebergs and added a condition where, if the distance between the polar bear and the iceberg becomes shorter than half the size of either, the game ends. I still need to fine-tune this logic so that small touches on the melted icebergs are allowed, making the game a bit more forgiving.
class GameManager { constructor() { this.score = 0; //score starts with 0 this.icebergs = []; this.fish = []; this.powerUps = []; } //function to fill up the canvas with 15 X 15 grids fillWithIcebergs() { let cols = 10; let rows = 10; let x_width = width / cols; //how wide each grid is let y_height = height / rows; //how tall each grid is this.icebergs = []; //create 15 X 15 grids for (let i = 0; i < cols; i++) { for (let j = 0; j < rows; j++) { //push all the icebergs into an array called icebergs to display them this.icebergs.push( new Iceberg( i * x_width + x_width / 2, j * y_height + y_height / 2, x_width, y_height ) ); } } } //function to restore 3 icebergs addIcebergs(num) { let restored = 0; for (let iceberg of this.icebergs) { if (iceberg.melted && restored < num) { iceberg.restore(); restored++; } } } //function to add more fish addFish(num) { for (let i = 0; i < num; i++) { let x = random(width); let y = random(height); this.fish.push(new Fish(x, y, fishSprites)); } } //function to add more powerups addPowerUp(num = 1) { for (let i = 0; i < num; i++) { let x = random(width); let y = random(height); this.powerUps.push(new PowerUp(x, y)); } } //function to check if bear went into melted icebergs IsOver(bear) { //adjust the size of polar bear accordingly let bearSize = width * bear.baseScale; if (fullscreen()) { bearSize *= 1.6; } //don't make polar bear too big or too small bearSize = constrain(bearSize, 90, 300); const bearHitbox = bearSize * 0.5; const bearHalf = bearHitbox / 2; for (let iceberg of this.icebergs) { if (iceberg.melted) { const overlapX = abs(bear.x - iceberg.x) < bearHalf + iceberg.w / 2; const overlapY = abs(bear.y - iceberg.y) < bearHalf + iceberg.h / 2; if (overlapX && overlapY) { return true; } } } return false; } }
This is the final production of my project: