Boss Room Dialogue System - UQcsse3200/2024-studio-1 GitHub Wiki
Overview
The Boss Room Dialogue System is a crucial component of our game that enhances boss encounters by implementing dynamic health-based dialogue triggers and enemy summoning mechanics. This system transforms boss fights into engaging, narrative-rich experiences that adapt to the player's progress.
The core idea is to create boss encounters that evolve as the fight progresses, keeping players engaged through contextual dialogue and increasing challenge. As the boss's health decreases, it triggers various events such as taunting dialogue and spawning of additional enemies.
Key Features
-
Health-based Dialogue Triggers: The boss initiates context-sensitive dialogue at specific health thresholds (75%, 50%, and 25%), adding personality and narrative depth to the encounter.
-
Dynamic Enemy Summoning: Additional enemies are spawned when the boss reaches 50% health, increasing the challenge and variety of the fight.
-
Adaptive Boss Behavior: The system is designed to be easily expandable for more complex behavior changes based on boss health.
-
Seamless Integration: The system integrates smoothly with existing dialogue, combat, and room management systems, ensuring a cohesive gameplay experience.
Class Structure
classDiagram
class Component {
+create()
+update()
}
class RenderComponent {
+draw(SpriteBatch batch)
}
class EnemyRoom {
+spawn(Entity player, GameArea area)
+removeRoom()
}
class BossHealthDialogueComponent {
-float[] healthThresholds
-Random random
-CombatStatsComponent combatStats
-int currentThresholdIndex
+create()
+update()
-showRandomDialogueAndPause()
-getRandomBossDialogue(int index): String
-spawnRandomAdditionalEnemies()
}
class BossRoom {
-NPCFactory npcFactory
-GameArea area
-Entity player
-Entity stairs
+spawn(Entity player, GameArea area)
+spawnRandomEnemies(String enemy)
-getRandomPosition(): GridPoint2
+removeRoom()
}
class DialogComponent {
-NameComponent nameComponent
-ShapeRenderer shapeRenderer
-GlyphLayout layout
+create()
+showDialog(String newText)
-completeDialog()
+dismissDialog(): boolean
+draw(SpriteBatch batch)
}
Component <|-- BossHealthDialogueComponent
EnemyRoom <|-- BossRoom
RenderComponent <|-- DialogComponent
BossHealthDialogueComponent --> CombatStatsComponent: uses
BossRoom --> NPCFactory: uses
BossRoom --> GameArea: uses
DialogComponent --> NameComponent: uses
Sequence Diagram
sequenceDiagram
actor P as Player
participant BHD as BossHealthDialogueComponent
participant BR as BossRoom
participant D as DialogComponent
participant ABS as AlertBoxService
activate P
P ->> BHD: Damage Boss
activate BHD
BHD ->> BHD: update()
alt Health threshold reached
BHD ->> BHD: getRandomBossDialogue()
BHD ->>+ ABS: confirmDialogBox()
ABS ->>+ D: showDialog()
D -->>- P: Display Dialogue
alt 50% health threshold
BHD ->>+ BR: spawnRandomAdditionalEnemies()
activate BR
BR ->> BR: getRandomPosition()
BR -->> P: Spawn Additional Enemies
deactivate BR
end
end
P ->> D: Dismiss Dialogue
activate D
D -->>- BHD: Resume Game
deactivate BHD
deactivate P
Detailed Component Breakdown
BossHealthDialogueComponent
The BossHealthDialogueComponent
is the core of the Boss Room Dialogue System. It's responsible for monitoring the boss's health and triggering appropriate responses.
Key methods:
create()
: Initializes the component, getting references to necessary components likeCombatStatsComponent
.update()
: Called every frame to check the boss's health and trigger events if thresholds are reached.showRandomDialogueAndPause()
: Selects and displays a random dialogue message, pausing the game.getRandomBossDialogue(int index)
: Selects a random dialogue message based on the current health threshold.spawnRandomAdditionalEnemies()
: Triggers the spawning of additional enemies when health reaches 50%.
public class BossHealthDialogueComponent extends Component {
private final float[] healthThresholds = {0.75f, 0.5f, 0.25f};
private final Random random = new Random();
private CombatStatsComponent combatStats;
private int currentThresholdIndex = 0;
@Override
public void create() {
combatStats = entity.getComponent(CombatStatsComponent.class);
}
@Override
public void update() {
if (currentThresholdIndex >= healthThresholds.length) {
return;
}
float healthPercentage = (float) combatStats.getHealth() / combatStats.getMaxHealth();
if (healthPercentage <= healthThresholds[currentThresholdIndex]) {
if (healthThresholds[currentThresholdIndex] == 0.5f) {
spawnRandomAdditionalEnemies();
}
showRandomDialogueAndPause();
currentThresholdIndex++;
}
}
// Other methods...
}
BossRoom
The BossRoom
class extends EnemyRoom
and is responsible for managing the boss encounter environment.
Key methods:
spawn(Entity player, GameArea area)
: Sets up the boss room, including spawning the boss and stairs.spawnRandomEnemies(String enemy)
: Spawns additional enemies during the fight.getRandomPosition()
: Generates a random position within the room for spawning entities.
DialogComponent
The DialogComponent
handles the rendering of dialogue on the screen.
Key methods:
create()
: Sets up the rendering components.showDialog(String newText)
: Initiates the display of a new dialogue.draw(SpriteBatch batch)
: Renders the dialogue box and text on the screen.
Visual on the Screen
Implementation Details
Health Monitoring
The BossHealthDialogueComponent
continuously monitors the boss's health in its update()
method. It compares the current health percentage to predefined thresholds:
float healthPercentage = (float) combatStats.getHealth() / combatStats.getMaxHealth();
if (healthPercentage <= healthThresholds[currentThresholdIndex]) {
// Trigger events...
}
Dialogue System
Dialogue is triggered at specific health thresholds. The system uses a 2D array to store dialogue options for each threshold:
private String getRandomBossDialogue(int index) {
String[][] dialogueOptions = {
{
"Your looks hurt more than your attacks.",
"If I had a nickel for every time you missed… I'd have a lot of nickels.",
// ... more options ...
},
// ... more thresholds ...
};
return dialogueOptions[index][random.nextInt(dialogueOptions[index].length)];
}
The DialogComponent
then renders this dialogue on the screen, character by character for a typewriter effect.
Enemy Summoning
When the boss's health reaches 50%, additional enemies are spawned:
private void spawnRandomAdditionalEnemies() {
GameAreaService gameAreaService = ServiceLocator.getGameAreaService();
if (gameAreaService.getGameArea() instanceof GameController) {
GameController area = (GameController) gameAreaService.getGameController();
if (area.getCurrentRoom() instanceof BossRoom bossRoom) {
String[] possibleEnemies = {"Dog", "Snake", "rat", "bear", "bat", "dino", "minotaur", "dragon"};
int numberOfEnemies = determineNumberOfEnemies();
for (int i = 0; i < numberOfEnemies; i++) {
String enemy = possibleEnemies[random.nextInt(possibleEnemies.length)];
bossRoom.spawnRandomEnemies(enemy);
}
}
}
}
The number of enemies spawned depends on the game's difficulty level.
Testing
The system is thoroughly tested using JUnit and Mockito. Key test cases include:
- Dialogue triggering at correct health thresholds (75%, 50%, 25%)
- No dialogue triggering above thresholds
- Enemy spawning at 50% health threshold
- Correct random dialogue selection
Example test:
@Test
void testDialogueTriggeredAt75PercentHealth() {
when(mockCombatStats.getHealth()).thenReturn(74); // Just below 75% threshold
component.update();
verify(mockAlertBoxService, times(1)).confirmDialogBox(
eq(mockEntity),
anyString(),
any(AlertBoxService.ConfirmationListener.class)
);
}