Transition to Boss - UQcsse3200/2024-studio-2 GitHub Wiki

Overview

The transition from the regular game to boss functionality includes the implementation of transitions for three specific bosses: Kanga (Land Boss), Leviathan (Water Boss), and Griffin (Air Boss).

The event starts from triggering the spawn of the respective boss, visual/audio effects during boss encounters, and ends with the pre-combat cutscene. Each boss has a unique transition with thematic elements based on their environment.

Kanga (Land Boss):

Rhythmic jungle-style drums, evoking the raw energy of the wild. The beat sets a tense yet primal tone, matching Kanga's powerful presence.

Audio: sounds/tension-land-boss.mp3

Leviathan (Water Boss):

Eerie soundscape creating an unsettling underwater tension. Haunting, deep reverberations echo through, giving the sense of a vast and mysterious creature lurking beneath the surface.

Audio: sounds/tension-water-boss.mp3

Griffin (Air Boss):

Sinister tone, with sharp, dark melodies that cut through the air. The ominous vibe intensifies the feeling of facing a swift and dangerous enemy from the skies.

Audio: sounds/tension-air-boss.mp3

Implementation

Starting with the boss creation in BossFactoryclass

Each of the bosses are created, where they are assigned their unique tasks. They are initialized with AI Task Components like ChaseTask, LeviathanTask, and GriffinTask.

public class BossFactory {
    public static Entity createBossNPC(Entity target, Entity.EnemyType type, BaseEnemyEntityConfig config) {
        AITaskComponent aiComponent = new AITaskComponent();

        // Add specific tasks for each boss type
        if (type == Entity.EnemyType.KANGAROO) {
            aiComponent.addTask(new ChaseTask(target, 10, 12f, 14f, new Vector2(configs.kangarooBoss.getSpeed(), configs.kangarooBoss.getSpeed()), true))
                    .addTask(new KangaJoeyTask(target, 9f, 2));
        } else if (type == Entity.EnemyType.WATER_BOSS) {
            aiComponent.addTask(new LeviathanTask(target, 10, 10f, 16f, 100f, 300));
        } else if (type == Entity.EnemyType.AIR_BOSS) {
            aiComponent.addTask(new GriffinTask(target, 10, 30f, 300, 100f));
        }
        .
        .
    }
}

Then in the ...Task component, methods are called to playTensionMusic() and trigger health bar beat

Implementations is quite similar for all three bosses in ChaseTask, LeviathanTask, and GriffinTask.

The only notable difference is in line AudioManager.playMusic("sounds/tension-land-boss.mp3", true); where the audio path need to be change

    @Override
    public void start() {
        super.start();
        .
        .
        .
        playTensionMusic();
        this.target.getEvents().trigger("startHealthBarBeating");
        .
        .
    }

    /**
     * Plays the tension music to enhance the experience during the chase.
     */
    void playTensionMusic() {
        // Play the music using AudioManager
        AudioManager.stopMusic();
        AudioManager.playMusic("sounds/tension-land-boss.mp3", true);
    }

    /**
     * Stops playing the tension music and play the background music.
     */
    void stopTensionMusic() {
        // Stop the music using AudioManager
        AudioManager.stopMusic();

        // Get the selected music track from the user settings
        UserSettings.Settings settings = UserSettings.get();
        String selectedTrack = settings.selectedMusicTrack; // This will be "Track 1" or "Track 2"

        if (Objects.equals(selectedTrack, "Track 1")) {
            AudioManager.playMusic("sounds/BGM_03_mp3.mp3", true);
        } else if (Objects.equals(selectedTrack, "Track 2")) {
            AudioManager.playMusic("sounds/track_2.mp3", true);
        }
    }
    
    @Override
    public void stop() {
        super.stop();
        movementTask.stop();

        stopTensionMusic();
        this.target.getEvents().trigger("stopHealthBarBeating");
    }

To start the health bar beating, in the PlayerStatsDisplay class, add listeners to detect the triggers mentioned

    // Add listener for kanga chase start/stop to trigger beating effect
    entity.getEvents().addListener("startHealthBarBeating", this::startHealthBarBeating);
    entity.getEvents().addListener("stopHealthBarBeating", this::stopHealthBarBeating);

Then calls the said methods

  public void startHealthBarBeating() {
    // Stop any existing beating actions
    heartImage.clearActions();
    vignetteImage.clearActions();

    vignetteImage.setVisible(true);

    heartImage.addAction(Actions.forever(
            Actions.sequence(
                    Actions.scaleTo(1.0f, 1.05f, 0.3f), // Slightly enlarge
                    Actions.scaleTo(1.0f, 0.95f, 0.3f)  // Return to normal size
            )
    ));

    vignetteImage.addAction(Actions.forever(
            Actions.sequence(
                    Actions.fadeIn(0.3f), // Fade in for vignette effect
                    Actions.fadeOut(0.3f)  // Fade out for vignette effect
            )
    ));
  }

  public void stopHealthBarBeating() {
    heartImage.clearActions();
    vignetteImage.clearActions();
    vignetteImage.setVisible(false); // Hide vignette when not beating
    heartImage.setScale(1.0f); // Reset to normal scale
  }

Testing Plan

Testing ensures that the functionalities being developed work as expected, which roughly includes:

  • Triggering the boss spawn correctly
  • Starting/Stopping audio/visual effects at the right time
  • Transitioning into cutscene and combat works correctly

Code Coverage & Reliability Report

Code Coverage Summary:

  • Line Coverage: 76.0% - This measures how much of the executable code has been tested. Uncovered lines are mainly tied to graphical rendering, where visual confirmation is more reliable than automated testing.

Bugs and Vulnerabilities:

  • Bugs: 0 - No bugs have been identified in the code.
  • Vulnerabilities: 0 - No security vulnerabilities were detected, ensuring the system is secure.

Maintainability:

  • Code Smells: 7 - These refer to areas in the code that could be improved for readability, maintainability, or efficiency. However, they do not negatively impact the performance or functionality of the game.

Testing Plan

Visual testing, with captioning to explain: https://youtu.be/Ny-1nAlynto?si=SvrpFAjzTigmaW_O&t=25

https://github.com/user-attachments/assets/4553a3ba-251a-412c-804c-97092cabe9dc

UML Diagram

BossFactory