Time Display UI in main game - UQcsse3200/2024-studio-2 GitHub Wiki

TimeDisplay Component

Overview

The TimeDisplay component is a UI element that shows the current in-game time on the screen in a simple and user-friendly format. It integrates with the game's Day-Night Cycle and InGameTime services to display the current hour based on the game's in-game time progression.

Players can toggle between 12-hour and 24-hour time formats by interacting with the TimeDisplay, adding flexibility to how the time is shown in-game. The button shows either HH:00 (24-hour format) or HH:00 AM/PM (12-hour format), depending on the selected mode.

Key Features

  • Live Time Display: Continuously updates and shows the current in-game hour, allowing players to see what time it is within the game world.
  • 24-hour and 12-hour Toggle: Players can toggle between 24-hour and 12-hour formats by clicking the display button.
  • Positioning: The time is displayed at the top-right corner of the screen, ensuring that it does not obstruct the player's view of the game world.
  • Scalable Button: The time is displayed on a resizable button, with the font size scaling to enhance visibility and readability.

Purpose

The main purpose of the TimeDisplay is to give players a visual representation of the in-game time. This is crucial for managing activities like day-night specific interactions, quests, or events. The toggle functionality allows players to switch between their preferred time display format (12-hour or 24-hour) during gameplay.


Methods

create()

This method is responsible for initializing the TimeDisplay component by creating a button that displays the current time and adding it to the stage. It sets up the button's position, size, and default display format.

Example:

@Override
public void create() {
    super.create();
    addActors();
}

addActors()

This method sets up the layout for the button using a Table. It positions the button at the top-right of the screen and configures its size. It also adds a click listener that toggles between 12-hour and 24-hour formats.

Example:

private void addActors() {
    table = new Table();
    table.top().right();  // Position the table in the top right
    table.setFillParent(true);  // Make sure the table takes up the entire screen space

    // Initialize the time button with default text
    timeButton = new CustomButton("Time: 00:00", skin);
    timeButton.setButtonSize(220f, 50f); // Resize the button to a smaller size that fits the UI

    // Update the button text with the current time
    updateTimeText();

    // Add the time button to the table and add padding
    table.add(timeButton).padTop(10f).padRight(100f).width(220f).height(50f);

    // Add click listener to toggle between 24-hour and 12-hour format
    timeButton.addClickListener(() -> {
        is24HourFormat = !is24HourFormat; // Toggle the format
        updateTimeText(); // Update the text after the format change
    });

    // Add the table to the stage
    stage.addActor(table);
}

updateTimeText()

This method updates the time displayed on the button based on the selected format (12-hour or 24-hour). It retrieves the current in-game time from InGameTime and updates the button's label text accordingly.

private void updateTimeText() {
    long currentTime = inGameTime.getTime();
    float timeOfDay = ((float) (currentTime % DayNightCycle.DAY_LENGTH)) / DayNightCycle.DAY_LENGTH;
    int hour24 = (int) (timeOfDay * 24); // 24-hour format

    String timeText;
    if (is24HourFormat) {
        timeText = String.format("Time: %02d:00", hour24); // 24-hour format
    } else {
        // Convert to 12-hour format with AM/PM
        int hour12 = hour24 % 12 == 0 ? 12 : hour24 % 12;
        String period = hour24 < 12 ? "AM" : "PM";
        timeText = String.format("Time: %02d:00 %s", hour12, period); // 12-hour format
    }

    timeButton.setLabelText(timeText); // Update the button label text
}

draw(SpriteBatch batch)

The draw() method is called continuously to update the displayed time. It retrieves the current time of day from the DayNightCycle system, calculates the corresponding hour, and updates the label with the current in-game time.

Example:

@Override
public void draw(SpriteBatch batch) {
    float timeOfDay = DayNightCycle.getTimeOfDay();
    int hour = (int) (timeOfDay * 24);
    String timeText = String.format("Time: %02d:00", hour);
    timeLabel.setText(timeText);
}

dispose()

The dispose() method ensures that resources related to the TimeDisplay are properly released when they are no longer needed. It clears the UI table and performs necessary cleanup.

Example:

@Override
public void dispose() {
    table.clear();
    super.dispose();
}

Integration with DayNightCycle The TimeDisplay relies on the DayNightCycle system to retrieve the current in-game time. The method DayNightCycle.getTimeOfDay() returns a floating-point value between 0.0 and 1.0, where 0.0 represents midnight (00:00) and 1.0 represents the next midnight. This value is multiplied by 24 to compute the current hour, which is then displayed in the label.

DayNightCycle Example:
float timeOfDay = DayNightCycle.getTimeOfDay();  // returns a value between 0.0 and 1.0
int hour = (int) (timeOfDay * 24);               // Calculate the current hour (0-23)

Usage Instantiating and Adding to UI: To use the TimeDisplay component in the game, it needs to be instantiated and added to the stage.

Rendering and Updating: The TimeDisplay will automatically update itself each frame when the game's DayNightCycle changes.

Example Usage:

TimeDisplay timeDisplay = new TimeDisplay();
timeDisplay.create();

// In the game loop:
timeDisplay.draw(spriteBatch);

Customization Position: The time label can be repositioned by adjusting the table's layout. It is currently positioned at the top-right of the screen with a slight padding (padRight).

Sequence diagram

image

sequence diagram PlantUML code (for further dev)

@startuml
actor Player

participant "TimeDisplay" as TD
participant "InGameTime" as IGT
participant "DayNightCycle" as DNC
participant "Stage" as ST
participant "CustomButton" as CB
participant "Label" as LB
participant "SpriteBatch" as SB

== Initialization ==

Player -> TD: create()
TD -> TD: addActors()
TD -> CB: new CustomButton("Time: 00:00")
TD -> ST: addActor(CustomButton)
ST -> TD: Actor added

== Update Time ==

Player -> TD: draw(SpriteBatch batch)
TD -> IGT: getTime()
IGT -> TD: return currentTime (long)
TD -> DNC: getTimeOfDay()
DNC -> TD: return timeOfDay (float)
TD -> TD: Calculate hour = timeOfDay * 24
alt Is 24-hour format
    TD -> CB: setLabelText("Time: HH:00")
else Is 12-hour format
    TD -> TD: Convert hour to 12-hour format
    TD -> CB: setLabelText("Time: HH:00 AM/PM")
end
CB -> TD: Time button label updated
TD -> SB: Draw updated time button

== Toggle Time Format ==

Player -> CB: Click Time Button
CB -> TD: Toggle time format (12-hour <-> 24-hour)
TD -> TD: updateTimeText()
TD -> SB: Update and redraw time label

@enduml