Death-Of-A-Deal

Physics-Based Platformer Game

Mechanism-Oriented Design

The game Death-of-a-Deal is a physics-based platformer developed in Java using LibGDX. Leveraging the Box2D physics engine, my teammates and I introduced a unique core mechanic: "turning to stone." When players activate this mechanic, their character loses all mobility but becomes solid and heavy. This transformation enables players to interact with the environment (bouncy platforms, breakable platforms, air flows, …)in creative ways, utilizing their altered physical properties to overcome challenges.

Game Story Design

The story unfolds in Hallowville, a district known for its many haunted mansions. These abandoned estates serve as a sanctuary for the town’s ghost population. However, their peace is disrupted when a daring real estate agent brings a client to finalize the sale of one of these mansions. You take on the role of the mansion’s guardian angel statue, tasked with protecting its ghostly inhabitants. Using your unique ability to switch between statue and ghost forms, your goal is to scare off the agent and client, ensuring the mansion remains undisturbed.

Code Samples


// This part of the code handles the collision
  // between plasyers and sloped platforms
  private void prepareImpulse(SlopeModel slope) {
    float slopeAngle = slope.getSlopeAngle();
    float forceMagnitude = slope.getSlopeFrozenImpulse();

    if (slopeAngle >= 0 && slopeAngle <= Math.PI) {
      // Slope is pointing down left
      v2Cache.set(
          (float) -Math.cos(slopeAngle) * forceMagnitude,
          (float) -Math.sin(slopeAngle) * forceMagnitude);
    } else {
      // Slope is pointing down right
      v2Cache.set((float) Math.cos(slopeAngle) * forceMagnitude,
          (float) Math.sin(slopeAngle) * forceMagnitude);
    }
  }
/**
   * Handles potential wind contact, returning whether we indeed had contact
   */
  private boolean handleWindContact(Contact contact, Fixture fix1, Fixture fix2, Obstacle bd2,
      Obstacle bd1) {
    boolean is1WindFixture = fix1.getUserData() instanceof WindParticleModel;
    boolean is2WindFixture = fix2.getUserData() instanceof WindParticleModel;
    WindParticleModel windParticle = null;
    Obstacle obj = null;

    if (is1WindFixture) {
      windParticle = (WindParticleModel) fix1.getUserData();
      obj = bd2;
    } else if (is2WindFixture) {
      windParticle = (WindParticleModel) fix2.getUserData();
      obj = bd1;
    }

    // On wind contact callback
    if (windParticle != null && obj != null) {
      // Should not continue detection with static body
      if (obj.getBodyType() == BodyType.StaticBody) {
        contact.setEnabled(false);
      } else {
        // Apply wind force
        Vector2 windForce = windParticle.getForce(obj.getX(), obj.getY());
        obj.getBody().applyForce(windForce, obj.getPosition(), true);
      }
    }

    return is1WindFixture || is2WindFixture || fix1.getUserData() instanceof WindModel
        || fix2.getUserData() instanceof WindModel;
  }

Gameplay Screenshots