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 theLightingUtils.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 aRayHandler
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 callingupdateAndRender()
on theRayHandler
. TheSpriteBatch
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()
orcreateConeLight()
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 theRayHandler
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 theLightingEngine
instance. This allows easy integration and access to lighting functionalities across the game without directly managing theLightingEngine
instance.
Workflow:
- Initialization: The
LightingService
is initialized with an instance ofLightingEngine
. - 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 positionx
(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.