Settings - UQcsse3200/2024-studio-2 GitHub Wiki
Overview
The SettingsMenuDisplay class is a crucial part of the game's UI that allows players to adjust various game settings such as audio levels, screen resolution, fullscreen mode, and FPS cap. It is built using libGDX's Scene2D framework and integrates seamlessly with the overall game architecture through the ServiceLocator.
Key Components
UserSettings
: Contains functionality for loading, storing, and applying settings.SettingsMenuDisplay
: Logic for the Settings screen, which shows how to work with UserSettings.
Key Components Settings UI Elements
Audio and Sound Sliders: Sliders for adjusting the overall audio and sound effects levels. FPS Cap TextField: A text field for setting the desired frames-per-second (FPS) cap. Fullscreen Checkbox: A checkbox to toggle fullscreen mode. Resolution Dropdown: A SelectBox for selecting from available screen resolutions. Code Example: Creating UI Components
Label audioScaleLabel = new Label("Audio:", skin);
Slider audioScaleSlider = new Slider(0, 100, 1, false, skin);
audioScaleSlider.setValue(settings.audioScale);
Label fpsLabel = new Label("FPS Cap:", skin);
TextField fpsText = new TextField(Integer.toString(settings.fps), skin);
CheckBox fullScreenCheck = new CheckBox("", skin);
fullScreenCheck.setChecked(settings.fullscreen);
Label displayModeLabel = new Label("Resolution:", skin);
SelectBox<StringDecorator<DisplayMode>> displayModeSelect = new SelectBox<>(skin);
displayModeSelect.setItems(getDisplayModes(Gdx.graphics.getMonitor()));
Buttons
UserSettings Integration
The settings menu retrieves and saves settings using the UserSettings class. This ensures that any changes persist across game sessions and are consistently applied throughout the game. Code Example: Applying Changes to UserSettings
public void applyChanges() {
UserSettings.Settings settings = UserSettings.get();
Integer fpsVal = parseOrNull(fpsText.getText());
if (fpsVal != null) {
settings.fps = fpsVal;
}
settings.fullscreen = fullScreenCheck.isChecked();
settings.audioScale = audioScaleSlider.getValue();
settings.soundScale = soundScaleSlider.getValue();
settings.displayMode = new UserSettings.DisplaySettings(displayModeSelect.getSelected().object);
UserSettings.set(settings, true);
}
Integration with Pause Menu
The SettingsMenuDisplay
was integrated into the pause menu to provide a smooth and intuitive experience for players to adjust game settings without needing to exit the game. This integration involved extending the PauseDisplay
class to include a new button for opening the settings menu and handling the transition between the pause menu and the settings overlay.
Design Decisions
-
Overlay System: The settings menu was added as an overlay in the
PausableScreen
class. This system allows multiple UI elements to be layered on top of each other while maintaining game state integrity. TheOverlayType
enum was extended to includeSETTINGS_OVERLAY
, ensuring that the settings menu could be dynamically added or removed based on player input. -
Smooth Transitions: When the player selects the settings option in the pause menu, the game displays the settings overlay. The pause menu itself is hidden temporarily, and touch interaction with it is disabled to prevent any unintentional interactions. This design ensures that the focus remains solely on the settings menu when it is open.
-
Separation of Concerns: The settings logic is encapsulated in the
SettingsMenuDisplay
class, allowing the pause menu to remain focused on handling pause-specific functionalities. This separation of concerns ensures that the settings system remains reusable and can be displayed in other contexts outside of the pause menu if necessary. -
Button Events and Interaction: Buttons such as "Apply" and "Close" were given dedicated event listeners. When the player clicks the "Apply" button, settings changes (such as resolution or audio levels) are immediately applied by invoking
applyChanges()
from theSettingsMenuDisplay
class. The "Close" button transitions the player back to the pause menu, hiding the settings overlay. -
Background and Layout Adjustments: The settings menu is displayed with a semi-transparent background to maintain visual consistency with other game screens, while the UI layout is centered and adjusted to fit different screen resolutions. This ensures that players can always view the settings menu clearly, regardless of their screen setup.
Code Example: Integration in PauseDisplay
The PauseDisplay
class was extended to handle settings transitions. Here's how it interacts with the settings overlay:
settingsBtn.addListener(new ChangeListener() {
@Override
public void changed(ChangeEvent event, Actor actor) {
logger.debug("Settings button clicked");
openSettings(); // Call method to open settings overlay
}
});
private void openSettings() {
screen.addOverlay(Overlay.OverlayType.SETTINGS_OVERLAY);
}
Code Example: PausableScreen Overlay System
In the PausableScreen
, overlays are managed using a stack-like system. The settings overlay is added similarly to other overlays like the quest or pause menu.
switch (overlayType) {
case SETTINGS_OVERLAY:
enabledOverlays.addFirst(new SettingsOverlay()); // Add settings overlay
break;
// Other overlay types...
}
Fullscreen Toggle: When toggling between fullscreen and windowed mode, the maximize/minimize button's texture wasn't updating correctly. This was addressed by adding a method to dynamically update the button's texture:
public void updateToggleWindowButtonTexture() {
if (Gdx.graphics.isFullscreen()) {
toggleWindowBtn.getStyle().imageUp = minimizeDrawable;
} else {
toggleWindowBtn.getStyle().imageUp = maximizeDrawable;
}
}
Resolving UI Conflicts
One of the challenges during integration was ensuring that the settings menu correctly interacted with the pause menu. Initially, there were issues where the settings menu would interfere with the pause menu controls, preventing the player from reopening the settings after closing it. This was resolved by ensuring proper visibility toggling and input handling through Scene2D's Touchable interface:
Design Choices and Their Impact
Flexibility: By designing the settings menu as an overlay, it can be reused in different parts of the game. This makes the system more flexible, as the settings can be invoked from both the main menu and the pause screen without duplicating code.
Immediate Feedback:
The "Apply" button allows players to see the effect of their changes immediately, enhancing user experience. Any changes to resolution, audio, or FPS are applied instantly, providing immediate visual or auditory feedback. Furthermore, these are stored globally, which transitions seamlessly across sessions and saves.
Player Experience:
Players can seamlessly transition between gameplay and settings adjustment, maintaining immersion in the game. The pause menu remains a key feature, with settings adjustments taking place in a familiar environment.
Common Issues Encountered During Integration
Background Clarity:
The settings menu's background originally interfered with UI elements, making text difficult to read. This was fixed by adjusting the transparency and ensuring that the UI layout was always centered and properly padded.
Button Interaction Issues:
Initially, clicking "Close" after opening the settings menu prevented the settings menu from being reopened. This issue was resolved by properly managing the state of the pause menu using the Touchable interface.
The SettingsMenu Class
The SettingsMenu class handles the actual creation and functionality of the settings window. It is responsible for displaying and managing the settings components such as sliders, checkboxes, and buttons. It also includes methods for saving and applying the user's changes.
Key Responsibilities of the SettingsMenu Class:
- Creating UI Components: It initializes and configures the UI components like sliders, checkboxes, and buttons.
- Displaying the Settings Menu: The settings menu can be shown or hidden, depending on whether the player accesses it from the main menu or pause menu.
- Handling Changes: It captures changes to the settings and applies them to the game's configuration.
- FullScreen Toggle: The menu integrates fullscreen toggling, ensuring a seamless user experience between windowed and fullscreen modes.
Example Code for Fullscreen Toggle
fullScreenCheck.addListener(new ChangeListener() {
@Override
public void changed(ChangeEvent event, Actor actor) {
boolean fullscreen = fullScreenCheck.isChecked();
if (fullscreen) {
Gdx.graphics.setFullscreenMode(Gdx.graphics.getDisplayMode());
} else {
Gdx.graphics.setWindowedMode(1280, 720);
}
}
});
Common Questions
I changed my resolution and now I can't see the game! How do I get back?
You can manually modify your settings file. This is stored in your home directory under DECO2800Game/settings.json
.
On Windows, this would likely be C:/Users/[username]/DECO2800Game/settings.json
.
You can manually make changes in the file, or delete it to revert to default settings.
The game runs too slow on my computer, what should I do?
The purpose of the settings menu is to let you adjust your graphics to keep the game running smoothly. Try:
- Lowering the FPS cap to 30. This controls how fast the game tries to run.
- Lowering your resolution (if running in fullscreen).