Midterm Project – Goalkeeper Challenge

Concept
As a kid, I admired strikers for scoring beautiful goals, but now I understand what a difficult and beautiful job goalkeepers have in saving their team. My admiration for goalkeeping grew, especially after watching the incredible 2022 World Cup Final between Argentina and France in Qatar.

In the game I’ve made, the player moves the goalkeeper’s gloves with a mouse or trackpad to save penalties. Each player starts with three lives and loses one for every goal conceded. Players can unlock new skins for their gloves. Making 10 saves in a single game unlocks the first skin, and reaching 15 saves in one session unlocks a second one.

The game also saves each player’s personal best record, allowing multiple users to compete and track their high scores. There is also a special golden ball: saving it grants an extra life (+1), but conceding a goal from it costs two lives instead of the usual one. The controls are simple: press ‘F’ for fullscreen and ‘S’ to view and select skins. There is also a hidden ‘R’ key to reset the game and clear all data.

Highlight of the code

function saveUserData() {
  let userData = {
    highScore: highScoreSaves,
    unlockedSkins: unlockedSkins
  };
  localStorage.setItem(currentUser, JSON.stringify(userData));
}

One smart technical decision I learned in my Intro to CS class was to automatically save each player’s progress and unlocked skins. This ensures that players don’t lose their scores and achievements when they close or reload the game. It definitely adds to the experience, making it feel like a real game that saves user accounts and their rewards.

if (dist(ball.x, ball.y, keeper.x, keeper.y) < keeper.size / 2) {
  saveSound.play();
  saves++;
  ball.reset();
}

Another important feature is collision detection, which I implemented using the mathematical dist() function. The method of checking for an overlap between two circles, which was also taught in my Intro to CS class, is a much easier way to calculate collisions in a simple game. When a collision is detected, the code plays the ‘save’ sound, increments the save counter, and resets the ball to its starting position. I think this approach is very simple, short, and super-efficient.

Sketch
https://editor.p5js.org/da3490/sketches/e03ZtWqpi

Reflection
I drew on my previous experience creating a Jetpack Joyride duplicate in my Intro to CS class to build this game’s features, including the login and menu pages, score tracking, user record saving, collision detection, and skins. While developing the UI took some time, it wasn’t logically difficult.

I would say that making the game adaptive to different screen sizes took the most effort. Instead of using fixed pixel values, I had to use percentages and mathematical relationships, such as width * 0.5 and height * 0.3. This approach was tricky but ensures the game looks and works properly on any device. I also added glow and glass effects to enhance the UI aesthetics. Using drawingContext and shadowBlur, I created transparent rectangles that produced a modern ‘glass’ look. While this style may be less popular now, it was a prominent trend in 2023-2024.

Future improvements
For future improvements, I would love to replicate FIFA-style penalties with a two-player mode: one player aims and shoots while the other plays as the goalkeeper.

To achieve a more realistic, front-facing perspective instead of the current view, I would need to implement 3D-like mechanics. This would involve angle calculations and scaling the ball’s size to create a sense of depth. The goalkeeper would use keyboard buttons to move in all eight directions (left, right, up, down, and diagonals) and would have a jump mechanic to make saves. For the shooter, the mouse would control the aim, while holding down the spacebar would determine the power of the shot.

Leave a Reply