-
Notifications
You must be signed in to change notification settings - Fork 28
Architecture
This project uses the default project structure for libGDX as generated by the libGDX Project Setup Tool. There is a sub-project for each supported platform. The actual game code resides in the core project.
The main building blocks of the game reside in packages within the core module. Each module contains a package-info.java with a brief description.
Most communication between the main building blocks is done using an event bus. This way, loose coupling is achieved between them.
The UI component uses the event bus for internal communication as well. Imho this is more elegant than attaching event listeners to every single screen.
Dependency injection is used wherever appropriate. This results in a desirable level of coupling and good testability. A DI/IoC framework is used to avoid manual creation of the object graph.
"Screens are fundamental to any game with multiple components. Screens contain many of the methods you are used to from ApplicationListener objects, and include a couple of new methods: show and hide, which are called when the Screen gains or loses focus, respectively. Screens are responsible for handling (i.e., processing and rendering) one aspect of your game: a menu screen, a settings screen, a game screen, etc." - LibGDX Documentation
A stage contains a hierarchy of UI elements. It automatically handles inputs (e.g. button clicks).
Each screen is responsible for manipulating one or more stages. For example, it might initialize the data presented in the stage in its show method. The IngameStage is an example for a stage that manages multiple screens. One of the use-cases is to show the ingame menu and then return to playing the game.
There are use-cases in which an action in a stage should cause the screen to do something. For example, closing the ingame menu using the back button should cause the hud (heads up display) stage to appear instead of the ingame menu stage.
The relation between the screens and their stages in this project is implemented as follows:
- a stage and its screens reside in the same package
- the screen exposes UI elements as needed to the stage by making them package private
- tight coupling is accepted here
- the screen holds a reference to its stages but not the other way around
- all UI listeners (e.g. ClickListeners) are registered by the screen
- this allows screen functionality to be used within the listeners
The unit tests focus on the things that are hard to test manually. This is mostly the game logic.
The project uses Java 8 because it is the latest version libGDX supports for all platforms.
-
libGDX is the core framework used for this game
- used for UI, 2D rendering, persistence
- cross-platform
- pure Java
- disadvantage: maintenance only mode
-
Dagger2 is the DI framework
- uses generated code instead of reflection
- in theory GWT compatible
-
Guava
- whenever I want to write a generic helper class, Guava already has it most of the times
- provides the event bus component
- JUnit and Mockito for unit tests
-
JUL is used via SLF4J for logging
- the libGDX logging is too basic
- Logback doesn't work on Android
- JUL works on Desktop and Android but I don't like the API (hence SLF4J)
- JUL has a MemoryHandler that can be used for data collection in crash situations