Custom Buttons - UQcsse3200/2024-studio-2 GitHub Wiki

CustomButton


Introduction:

The CustomButton class provides a customizable button component with enhanced interaction features such as hover effects, dynamic resizing, and sound effects. Unlike the default LibGDX button class, CustomButton is designed with flexibility and aesthetics in mind with UI designs implemented.


How to Use the CustomButton Class:

1. Importing the CustomButton Class:

To use the CustomButton class, ensure that you have the necessary imports and the class integrated into your project. Here’s how you can import it:

import com.csse3200.game.ui.CustomButton;

2. Creating a CustomButton Instance:

You can create a new button by instantiating the CustomButton class and providing the button label and skin for styling the text:

CustomButton myButton = new CustomButton("Click Me", skin);

3. Adding a Click Listener:

You can assign an action to the button using the addClickListener() method. This method allows you to specify a Runnable that will be executed when the button is clicked:

myButton.addClickListener(() -> {
    System.out.println("Button clicked!");
});

4. Adding Hover Effects:

The CustomButton class automatically adds hover effects, so no additional setup is needed. On hover, the button slightly scales and moves for visual feedback.

5. Resizing the Button:

The button can be resized dynamically using the setButtonSize() or resize() methods. For example:

myButton.setButtonSize(200, 60);  // Set a specific width and height

You can also resize the button based on screen size and a scale factor:

myButton.resize(screenWidth, screenHeight, 0.1f);  // 10% of the screen width/height

Design Choices:

Custom Visual Effects:

The CustomButton class was designed to provide enhanced visual feedback for the user. The built-in hover effects, such as slight scaling and movement, give the user an intuitive understanding that the button is interactive.


No Use of Skins:

Instead of relying on LibGDX’s skin system, CustomButton directly manipulates textures to give developers more control over the look and feel of the buttons. Skins often restrict customization and are more difficult to modify for specific aesthetic needs. This approach offers greater flexibility in terms of appearance and allows for more direct customization of the button’s behavior and design.

Static Resource Management:

The textures and sound effects are statically loaded to ensure that multiple instances of CustomButton do not reload the same assets. This approach improves efficiency by reducing redundant resource loading while still allowing for custom visual assets.

Integration with CustomCursor throughout game:

The textures and implementation of the CustomButton class is consistent with the implementation of the CustomCursor class, thus allowing for synergy amongst the two features.


Features:

Preloaded Textures and Sounds:

The class comes with a pre-defined button texture (BlankLarge.png) and a sound effect (click.mp3) for a unified look and sound across all buttons. These resources are static to ensure they are reused efficiently across instances.

Hover Effects:

Hovering over the button triggers visual feedback through movement and scaling. These effects are handled smoothly, improving user experience by making the button feel more interactive.

Dynamic Resizing:

Buttons can be resized dynamically using the resize() method. This feature allows the button to adjust its dimensions based on the screen size or resolution, making it ideal for responsive UI designs.

Customizable Label:

The button's label text can be updated dynamically using the setLabelText() method, allowing for flexible use cases where the button’s text needs to change during the game.

Complete Implementation example:


In the MainMenuDisplay class, the CustomButton is used to create interactive buttons for various actions in the game's main menu. Below is an example of how CustomButton is utilized for the main menu buttons, including Start, Load, Settings, and Exit.

Step 1: Creating Menu Buttons

The CustomButton instances are created with labels and a skin to style the button's text. For instance, here's how the "Start" button is created:

CustomButton startBtn = new CustomButton("Start", skin);

Step 2: Adding Click Listeners to Buttons

Each button has a click listener added to it, which triggers an action when the button is clicked. For the "Start" button, the following code sets up the action to start the game:

startBtn.addClickListener(() -> {
    logger.info("Start button clicked");
    entity.getEvents().trigger("start");
});

Similarly, other buttons like "Load", "Settings", and "Exit" follow the same approach:

CustomButton loadBtn = new CustomButton("Load", skin);
loadBtn.addClickListener(() -> {
    logger.info("Load button clicked");
    entity.getEvents().trigger("load");
});

CustomButton settingsBtn = new CustomButton("Settings", skin);
settingsBtn.addClickListener(() -> {
    logger.info("Settings button clicked");
    settingsMenu.showSettingsMenu();  // Opens the settings menu when clicked
});

CustomButton exitBtn = new CustomButton("Exit", skin);
exitBtn.addClickListener(() -> {
    logger.info("Exit button clicked");
    entity.getEvents().trigger("exitConfirmation");  // Triggers exit confirmation dialog
});

Step 3: Adding Buttons to a Table Layout

The buttons are added to a Table for proper layout management. This helps to center the buttons on the screen and manage their placement.

Table menuButtonTable = new Table();
menuButtonTable.setPosition(screenWidth / 2, screenHeight / 2);

// Add buttons to the table with spacing
menuButtonTable.add(startBtn).size(buttonWidth, buttonHeight).padBottom(buttonSpacing);
menuButtonTable.row();
menuButtonTable.add(loadBtn).size(buttonWidth, buttonHeight).padBottom(buttonSpacing);
menuButtonTable.row();
menuButtonTable.add(settingsBtn).size(buttonWidth, buttonHeight).padBottom(buttonSpacing);
menuButtonTable.row();
menuButtonTable.add(exitBtn).size(buttonWidth, buttonHeight).padBottom(buttonSpacing);

Step 4: Final Touch After setting up the buttons and adding them to the stage, they become fully interactive in the game's main menu. The combination of dynamic resizing, hover effects, and click actions provides a smooth and visually appealing user experience.

stage.addActor(menuButtonTable);

Accessing the Internal Button Instance

If you need to access the internal Button object directly (for more advanced use cases), you can call the getButton() method in the class, which returns the button instance. With this method, you can access any of the standard Button methods, like adding a different type of listener, changing styles, etc.

Example:

Button internalButton = customButton.getButton();

// Now you can add any listeners or change properties directly on the internal button
internalButton.addListener(new ClickListener() {
    @Override
    public void clicked(InputEvent event, float x, float y) {
        System.out.println("Button clicked!");
    }
});