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

Lighting System Overview

The lighting system in this game is responsible for creating and managing various light sources, simulating a dynamic day/night cycle, and rendering these effects. It heavily relies on the box2dLight library for creating and controlling light sources and is integrated with the game engine to adjust lighting properties in real-time based on the time of day.

Key Components:

1. DayNightCycle

The DayNightCycle class controls the ambient lighting for the game to simulate a day/night cycle. This includes changing the brightness and color of the global ambient light based on the in-game time.

Key Features:

  • Day Length: The class defines a static constant DAY_LENGTH that determines the length of a full in-game day (e.g., 24,000 ms representing 24 in-game hours).
  • Key Time Colors: The day is divided into different stages (e.g., midnight, dawn, noon) each represented by a unique color. The keyTimes array holds these colors.
  • Time Calculation: The method getTimeOfDay() retrieves the current time from the ServiceLocator and normalizes it to a value between 0.0 and 1.0, where 0.0 is midnight and 1.0 is the next midnight.
  • Color Interpolation: The update() method uses the LightingUtils.interpolateColorCycle() function to smoothly transition between these colors as the time of day progresses, creating a dynamic color shift over time.
  • RayHandler Integration: RayHandler is used to set the ambient light color based on the interpolated time of day.

Workflow:

  • Time of Day Calculation: Get the current in-game time using getTimeOfDay().
  • Color Transition: Based on the time, interpolate between the pre-defined key time colors.
  • Ambient Light Update: Update the ambient lighting in RayHandler using the interpolated color.

Key Components:

2. LightingEngine

The LightingEngine is the central component responsible for managing and rendering all light sources in the game. This class interfaces directly with the box2dLight library to create and control different types of lights.

Key Features:

  • RayHandler: The LightingEngine contains a RayHandler object that manages all light sources and renders the lighting effects.
  • Light Creation: It has methods to create different types of lights:
    • PointLight: A simple circular light.
    • ConeLight: A light shaped like a cone.
    • DirectionalLight: A light that shines in a particular direction, often used for sun or moon lighting.
    • ChainLight: A light that emits rays from a chain of vertices, useful for illuminating specific paths or shapes.
  • Rendering: The render() method updates and renders the lights each frame by setting the camera matrix and calling updateAndRender() on the RayHandler. The SpriteBatch is paused during this process to ensure lighting is rendered correctly.
  • Layering: The engine uses the getLayer() method to determine which layer in the rendering pipeline the lights should be drawn on.

Workflow:

  • Light Creation: Use specific methods like createPointLight() or createConeLight() to add lights to the scene.
  • Matrix Setup: Before rendering lights, set the combined matrix of the camera to match the game’s camera position.
  • Rendering Lights: Call updateAndRender() on the RayHandler to render the lights in the scene.
  • Disposal: When no longer needed, dispose of the RayHandler to free up resources.

3. LightingService

The LightingService acts as a global access point to the LightingEngine. It provides other parts of the game with access to the lighting system and ensures the engine is updated correctly each frame.

Key Features:

  • Engine Access: Provides a single method, getLighting(), that returns the LightingEngine instance. This allows easy integration and access to lighting functionalities across the game without directly managing the LightingEngine instance.

Workflow:

  • Initialization: The LightingService is initialized with an instance of LightingEngine.
  • Global Access: Any game component that needs access to the lighting system can use the service to retrieve the lighting engine.

4. LightingUtils

LightingUtils is a utility class that provides useful functions to help with lighting management. Its primary purpose is to handle color interpolation, allowing smooth transitions between colors for dynamic lighting effects.

Key Features:

  • Color Interpolation: The interpolateColorCycle() method is used to interpolate between an array of colors based on a position x (which represents a point in time). This is key to transitioning the ambient light color smoothly over time in the day/night cycle.

Workflow:

  • Interpolation: Given an array of colors and a float x representing the time position, the method calculates the transition between two key colors.
  • Smooth Transition: This is used in the DayNightCycle to smoothly transition the ambient lighting color as the day progresses.

5. FadeLightsDayTimeComponent

The FadeLightsDayTimeComponent is responsible for dynamically adjusting the distance (or intensity) of lights attached to entities in the game based on the time of day.

Key Features:

  • Light Fading: This component adjusts the distance of a Light object during certain times of the day. For example, lights may fade out during the daytime and brighten at night.
  • Time-Based Adjustments: It retrieves the time of day from the DayNightCycle and uses predefined thresholds (e.g., fadeInTime, fadeOutTime) to calculate the light’s intensity or distance.
  • Max Distance: The maximum distance the light can reach is stored when the component is created, ensuring that the light doesn’t exceed its original bounds.

Workflow:

  • Light Attachment: The component attaches to an entity with a light and stores the initial distance of the light.
  • Time-Based Update: During the game loop, it checks the current time of day and adjusts the light’s distance accordingly, fading the light in and out based on predefined times.

UML diagram

image

Sequence diagram

image