Midterm Project: “Football Obstacle Game”

Concept:

The idea behind this project was to create an interactive football shooting game that combines skill, strategy, and dynamic difficulty. The player must shoot goals while avoiding defenders and a moving goalkeeper. The game incorporates increasing challenge as the player scores, adding both excitement and replay value.

I wanted the game to be simple enough for beginners to play, yet engaging enough to demonstrate programming concepts like collision detection, movement logic, and audio-visual feedback in p5.js

Design and features of the game:

  • Player Controls: Use the arrow keys to move and mouse click to shoot.

  • Dynamic Defenders: Start with 3 defenders; a new defender is added every time the player scores.

  • Goalkeeper: Moves horizontally across the goal area and tries to block shots.

  • Score Tracking: Displays the player’s score at the top left.

  • Audio Feedback: Crowd cheers when the player scores, and a whistle plays when the player loses.

  • Background Image: I used a football pitch background image to visually represent the field.

  • Collision Detection: The game detects collisions between the player, ball, defenders, and goalkeeper to determine goals or game overs.

Code Highlight:

One of my favorite code snippets is the restart logic. Instead of refreshing the entire page, pressing “R” instantly resets the player, ball, defenders, and score to allow for a smooth restart.

Another code snippet I’m proud of is the collision detection function. This function checks whether the player or the ball collides with any of the defenders using the distance formula. It calculates the distance between two objects and compares it to their combined radii — if they overlap, the game ends.

// Restart after lose
  if (gameState === "lose" && (key === "r" || key === "R")) {
      Ball1.reset(Player1);
      Player1.reset();
      score = 0;

      // Reset defenders
      defenders = [];
      for (let i = 0; i < 3; i++) {
          let defenderX = random(width / 4, (3 * width) / 4);
          let defenderY = random(height / 6 + 50, (5 * height) / 6 - 50); // release below goal
          defenders.push(new Defender(defenderX, defenderY, 3));
      }
function checkDefenderCollision() {
  for (let defender of defenders) {
    // Player collision
    let dPlayer = dist(Player1.x, Player1.y, defender.x, defender.y);
    if (dPlayer < 20 + 15) {
      loseGame();
      return;
    }

    // Ball collision
    if (Ball1.isMoving) {
      let dBall = dist(Ball1.x, Ball1.y, defender.x, defender.y);
      if (dBall < Ball1.radius + 15) {
        loseGame();
        return;
      }
    }
  }
}

Embedded Sketch:

This is a link to the sketch: https://editor.p5js.org/Jayden_Akpalu/sketches/_4tt_i0oG

Reflections & Future Improvements:

Through this project, I learned how to manage game states, implement collision detection, and integrate audio and visuals for a more immersive experience. I also improved my debugging and problem-solving skills — especially when aligning the goalkeeper, handling full-screen scaling, and ensuring the game reset logic worked correctly.

If I had more time, I would like to improve the game in several ways. First, I’d like to replace the simple circles used for the players and defenders with animated sprite characters. This will make the movement and shooting feel more realistic and visually engaging. For example, I could use a sprite sheet of a footballer running or kicking the ball, and animate it frame by frame when the player moves or shoots. Also, I’d like to add multiple levels of difficulty with new environments or faster defenders to make gameplay more dynamic. Finally, I’d love to create a high-score tracker, allowing players to save and compare their best performances.

Leave a Reply