-
Notifications
You must be signed in to change notification settings - Fork 7
Lighting system
To enhance the game and make the game time feel more meaningful, a day/night cycle has been implemented. This complements the existing game time display by adding brightness and darkness to the game during day and night respectively. To implement this system, a 2D lighting framework for LibGdx has been used called Box2dLights. This lighting framework uses Box2d for all of its raycasting which is helpful as this is the 2D physics engine that is used in this game engine. This framework provides a vast number of lighting features; however, to keep the lighting system within the game style and to reduce CPU burden, very little of the dynamic lighting features are used.
There is very little helpful documentation out there on box2dlights so I will try my best to add some.
In order to manage everything related to lights updating and rendering, box2dlights uses a RayHandler
class. This RayHandler
class uses the World
from the PhysicsEngine
in order to handle all of the collision geometry for the lighting. In order to readily access this RayHandler
in order to create lights across the game, the LightService
has been created, which essentially acts as a wrapper class for the RayHandler
following the design patterns similar to the other services seen in the ServiceLocator
. Additionally, this LightService
is accessible through the ServiceLocator
as lighting may not be restricted to the main game area as it could be used on other screens (eg: main game screen, loading screens, etc.).
As the lights are all registered with the RayHandler
instance, they are all kept track of and easily drawn using the updateAndRender()
method of the RayHandler
. In order for the lights to be drawn in the correct order and not be drawn over important ui components, the render()
method in the Renderer
class was modified. This method is shown below:
public void render() {
Matrix4 projMatrix = camera.getProjectionMatrix();
batch.setProjectionMatrix(projMatrix);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
batch.begin();
renderService.render(batch);
batch.end();
if (ServiceLocator.getLightService() != null) {
ServiceLocator.getLightService().renderLight();
}
debugRenderer.render(projMatrix);
stage.act();
stage.draw();
}
The order of rendering here is quite simple, as is as follows:
- Anything renderable with a sprite is rendered by the
RenderService
. This includes the player, animals, items, the map, etc. - The lights are then rendered by the
LightService
with therenderLight()
method. - The game UI is then rendered as it is part of the stage.
When creating new visual components, you need to determine whether or not they will be drawn before or after the lights are drawn and hence decide whether they should be part of the game stage or not.