Game End screen - UQcsse3200/2026-studio-2 GitHub Wiki

Game End Screen

Overview

The Game End Screen displays the result of a game when the player either wins or loses. It provides a reusable UI for both outcomes and presents the result message using the existing typewriter effect system.

The screen supports:

  • Win state: displays YOU WIN!
  • Lose state: displays GAME OVER!
  • A result message with a typewriter effect
  • Restart button
  • Exit to Main Menu button
  • Exit to Desktop button

Implementation

The main UI is implemented in GameEndDisplay.

GameEndDisplay listens for the global gameEnd event and receives a GameEndState value. The state determines whether the UI displays the win or lose result.

Gameplay / game condition
        |
        v
gameEnd event
        |
        v
GameEndDisplay.setState(GameEndState)
        |
        +--> WIN  -> "YOU WIN!"
        |
        +--> LOSE -> "GAME OVER!"

The result message is passed to the existing TypewriterEffect, which progressively reveals the text.

GameEndState

GameEndState is an enum containing the two possible game-ending states:

public enum GameEndState {
  WIN,
  LOSE
}

Using an enum keeps the game-ending state explicit and avoids relying on boolean values whose meaning could be unclear.

UI Layout

The game-end panel uses a Scene2D Table layout.

The panel does not rely on fixed width and height values. Its size is determined from its contents using Table.pack(), while the contents use the available UI space through the table layout.

The panel is centred relative to the current stage dimensions.

This allows the UI to adapt more naturally to different screen sizes instead of depending on hard-coded panel dimensions.

Buttons and Actions

GameEndDisplay raises entity events when buttons are pressed:

Button Event
Restart restart
Exit to Main Menu mainMenu
Exit to Desktop exitDesktop

These events are handled separately by GameEndActions.

Current restart behaviour

The restart button is currently a placeholder. GameEndActions logs the restart request because a complete game-reset system has not yet been implemented.

The main menu and exit actions are connected to their corresponding game behaviour.

Event Integration

For the game-end display to work, the screen must use the shared game-end event handler and include the game-end UI components.

The gameplay logic is responsible for deciding when the game has ended and which GameEndState should be sent. The UI is responsible for presenting that state.

For example:

ServiceLocator.getGameEndEventHandler()
    .trigger("gameEnd", GameEndState.WIN);

The display then receives the state through its gameEnd listener and calls setState(...).

Testing

Win condition

To test the win screen:

  1. Start the tutorial level.
  2. Reach the win-condition entity.
  3. Confirm that a gameEnd event is triggered with GameEndState.WIN.
  4. Confirm that the game-end panel appears and displays YOU WIN!.

Lose condition

To test the lose screen:

  1. Start the level.
  2. Reduce the player's health to zero through the game's damage/death system.
  3. Confirm that a gameEnd event is triggered with GameEndState.LOSE.
  4. Confirm that the game-end panel appears and displays GAME OVER!.

Dev Tools/Commands

win : Triggers win screen.

lose : Triggers lose screen.

Layout

The panel should remain centred and resize according to its contents rather than relying on a fixed panel width and height.

Related Classes

Class Responsibility
GameEndDisplay Builds and displays the game-end UI
GameEndActions Handles game-end button events
GameEndState Represents WIN or LOSE
TypewriterEffect Reveals the result message progressively
EventHandler Publishes and delivers the gameEnd event