Midterm Project – ICEY IMPACT


Concept:

The game is an arena-style, two-player game where each player controls a snowball. The goal is to either knock the opponent’s snowball (represented by an emoji image) out of the arena or collect three coins. Which ever player gets to three points first wins. A scoreboard is displayed on screen to show each player’s current score and coin count.

Sketch:
User Interaction: 
  • The game begins with an instruction screen, requiring user input to proceed.
  • Player 1 controls their snowball using the WASD keys, while Player 2 uses the arrow keys.
  • Players navigate the arena, collecting coins or attempting to knock their opponent out of bounds.
  • The first player to collect three coins or knock their opponent out three times wins.
  • Players can choose to start a new session after completing the game.
    Implementation: 
  • The game has several classes, each of which contributes to different aspects of the experience:

    • Game: This class manages the overall state of the game, including showing screens, handling instructions, tracking game progress, and determining when a round or the game ends.
    • Player: The Player class handles all of the attributes and behavior of each player. This includes movement (based on keyboard input), collision detection, score tracking, and boundary constraints.
    • Arena: The Arena class defines the boundary within which players compete. It is used to detect if a player has fallen out of bounds.
    • Item: The Item class is used to create collectible items (coins). When a player collects an item, it increases their coin count.

    Key features incorporated into the game:

    • Object-Oriented Programming: The game is structured using classes such as Game, Player, Arena, and Item to ensure modular and reusable code.
    • Visuals: The game uses images for players, the background, and items (coins).
    • Sound: Sounds are used for collecting coins and when the game ends.
    • User Input: Player controls are managed using keyboard inputs (WASD and arrow keys).
    • Collision and Boundary Detection: Players can collide with each other, and boundary detection is used to check if players fall out of the arena.
      Key Challenges Faced: 

      One of the primary challenges faced during development was handling the collision physics between the players. The snowball collisions had to feel dynamic, but it was difficult to achieve perfect elasticity. The physics calculations were complex, especially considering that each player’s position and velocity had to be updated to reflect an elastic collision.

      Another challenge was optimizing the game so that it could run smoothly in p5.js. Initially, I wanted to incorporate more images and sounds, but p5.js struggled to handle all of the resources, leading to long loading times. Ultimately, I had to simplify the assets to ensure smooth gameplay.

Code That I Am Proud Of: 

I am particularly proud of the resolveCollision() function in the Player class, which handles the collision between players. The function calculates the angle and then applies new velocities to the players to simulate the effect of a collision. This code makes the game feel more dynamic and fun, as players can push each other around the arena.

resolveCollision(other) {
  let dx = other.x - this.x;
  let dy = other.y - this.y;
  let distance = Math.sqrt(dx * dx + dy * dy);

  if (distance < this.radius + other.radius) {
    let angle = Math.atan2(dy, dx);
    let v1 = Math.sqrt(this.vx * this.vx + this.vy * this.vy);
    let v2 = Math.sqrt(other.vx * other.vx + other.vy * other.vy);

    let newVx1 = v2 * Math.cos(angle);
    let newVy1 = v2 * Math.sin(angle);
    let newVx2 = v1 * Math.cos(angle);
    let newVy2 = v1 * Math.sin(angle);

    this.vx = newVx1;
    this.vy = newVy1;
    other.vx = newVx2;
    other.vy = newVy2;

    let overlap = (this.radius + other.radius) - distance;
    let moveX = overlap * Math.cos(angle) / 2;
    let moveY = overlap * Math.sin(angle) / 2;
    this.x = this.x - moveX;
    this.y = this.y -moveY;
    other.x = other.x + moveX;
    other.y = other.y + moveY;
  }
}

This function might not achieve perfect elasticity, but it gives a satisfying collision effect, enhancing the overall player experience.

Reflection: 

Looking back, I am mostly satisfied with how the project turned out, especially given the challenges with collision detection and resource optimization. One thing I wish I could improve is the collision physics—ideally, the collisions would be perfectly elastic, allowing for even more realistic interactions between the players. However, achieving this in a way that felt right with p5.js was more challenging than expected. Despite these challenges, the game is enjoyable and provides a satisfying experience for both players.

Leave a Reply