Game Lighting - UQcsse3200/2024-studio-2 GitHub Wiki

Lighting System

The Lighting System in our game is responsible for creating and managing light sources, as well as rendering lighting effects throughout the game world. This system uses Box2D's RayHandler through LibGDX to manage real-time lighting and shadow effects. Below, is the break-down of the key components involved in the lighting system, including how to integrate lights with entities, and how to customize lighting properties.

Overview

The Lighting System provides:

  • Dynamic Light Sources: Includes point lights, cone lights, directional lights, and chain lights.
  • Real-time Shadows: Light objects interact with physical objects in the game world to create shadows.
  • Ambient Lighting: A global light setting to create a dark or bright environment, which can be adjusted dynamically.
  • Light Effects: Lights can be customized with different colors, distances, and softness to achieve specific visual effects.
  • Entity Lighting: Lights can be attached to entities and will follow them as they move around the game world.

Core Components

1. Lighting Service

The LightingService acts as the entry point to the lighting system, providing access to the LightingEngine. Entities can use this to interact with the lighting system for creating and controlling lights.

public class LightingService {
  private final LightingEngine engine;

  public LightingService(LightingEngine engine) {
    this.engine = engine;
  }

  public LightingEngine getLighting() {
    return engine;
  }
}

Key Method:

getLighting(): Returns the LightingEngine, which is responsible for managing all light objects in the game.

Types of Lights

1. Point Light

A PointLight creates a circular light source that radiates in all directions from a central point.

public PointLight createPointLight(float x, float y, float dist, Color color) {
    PointLight pl = new PointLight(rayHandler, 128, color, dist, x, y);
    applyDefaultLightingSettings(pl);
    return pl;
}

Distance: The radius of the light. Color: The color of the light.

2. Cone Light

A ConeLight creates a spotlight effect, projecting light in a specific direction with a defined angle.

public ConeLight createConeLight(float x, float y, float dist, float dir, float cone, Color color) {
    ConeLight cl = new ConeLight(rayHandler, 128, color, dist, x, y, dir, cone);
    applyDefaultLightingSettings(cl);
    return cl;
}

Direction: The angle (in degrees) where the light is pointed. Cone: The spread of the light.

3. Directional Light

A DirectionalLight simulates a light source with infinite range, like sunlight.

public DirectionalLight createDirectionalLight(float dir, Color color) {
    DirectionalLight dl = new DirectionalLight(rayHandler, 128, color, dir);
    applyDefaultLightingSettings(dl);
    return dl;
}

Direction: The angle at which the light comes from.

4. Chain Light

A ChainLight distributes rays across multiple points, useful for creating segmented lighting effects (e.g., string lights).

public ChainLight createChainLight(float[] chain, float dist, int dir, Color color) {
    ChainLight cl = new ChainLight(rayHandler, 128, color, dist, dir, chain);
    applyDefaultLightingSettings(cl);
    return cl;
}

Chain: Array of vertices where light rays are emitted.

Lighting Settings

Each light can be customized with default lighting settings applied via the applyDefaultLightingSettings method. These settings control how the light behaves when interacting with physics objects or entities in the game.

public static void applyDefaultLightingSettings(Light light) {
    light.setIgnoreAttachedBody(true);  // Ignore collisions with the entity the light is attached to
    light.setSoftnessLength(3f);  // Create a smooth lighting effect around edges
    light.setContactFilter(PhysicsLayer.DEFAULT, PhysicsLayer.NONE, PhysicsLayer.ALL);  // Ensure light interacts with all physics objects
}

Default Settings: Ignore Attached Body: Ensures the light does not collide with the entity to which it is attached. Softness Length: Controls how much light bleeds through objects. Contact Filter: Controls which physics objects the light interacts with

Dark Theme Implementation

In addition to individual lights, the game supports a dark theme using ambient light. By setting a low-intensity ambient light, the environment becomes dark, and only areas with specific light sources (like the player’s light) are illuminated.

rayHandler.setAmbientLight(new Color(0.05f, 0.05f, 0.05f, 1f));  // Dark ambient light

Ambient Light Color: Controls the overall darkness level in the game.

Usage Example Creating a Player with a Light Bubble The player entity is created with a point light (light bubble) that follows the player around, providing visibility in a dark environment.

LightingComponent light = new LightingComponent(
    LightingComponent.createPointLight(8f, new Color(1f, 0.5f, 0.5f, 1f)), 
    Vector2.Zero, 
    true
);
player.addComponent(light);

In this example:

The point light has a distance of 8f and a soft coral color. The light follows the player as it moves.

UML diagram

image