Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"java.configuration.updateBuildConfiguration": "interactive"
}
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,15 @@ mvn jpro:run
# Open http://localhost:8080
```

#### Debug Menu (Developers Only)
The debug menu is hidden by default. To enable it, pass `-DdebugMenu=true` when running:
```bash
mvn javafx:run -DdebugMenu=true

# Or with the browser version:
mvn jpro:run -DdebugMenu=true
```

📖 **More details:** [Java Setup Guide](https://github.com/jvondermarck/dinosaur-exploder/wiki/Java-Installation-Guide)

</details>
Expand Down
7 changes: 7 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
<junit.version>6.0.3</junit.version>
<mainClassName>com.dinosaur.dinosaurexploder.DinosaurApp</mainClassName>
<mainClassJProName>com.dinosaur.dinosaurexploder.DinosaurWebApp</mainClassJProName>
<debugMenu>false</debugMenu>
<sonar.projectKey>jvondermarck_dinosaur-exploder</sonar.projectKey>
<sonar.organization>jvondermarck</sonar.organization>
<sonar.host.url>https://sonarcloud.io</sonar.host.url>
Expand Down Expand Up @@ -160,6 +161,9 @@
<jlinkImageName>game</jlinkImageName>
<jlinkZipName>fxgl-game</jlinkZipName>
<mainClass>${mainClassName}</mainClass>
<options>
<option>-DdebugMenu=${debugMenu}</option>
</options>
</configuration>
</plugin>

Expand All @@ -170,6 +174,9 @@
<version>${jpro.version}</version>
<configuration>
<mainClassName>${mainClassJProName}</mainClassName>
<JVMArgs>
<JVMArg>-DdebugMenu=${debugMenu}</JVMArg>
</JVMArgs>
</configuration>
</plugin>

Expand Down
82 changes: 82 additions & 0 deletions src/main/java/com/dinosaur/dinosaurexploder/view/DebugMenu.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
/*
* SPDX-FileCopyrightText: 2026 jvondermarck
* SPDX-License-Identifier: MIT
*/

package com.dinosaur.dinosaurexploder.view;

import com.almasb.fxgl.app.scene.FXGLMenu;
import com.almasb.fxgl.app.scene.MenuType;
import com.dinosaur.dinosaurexploder.components.CollectedCoinsComponent;
import com.dinosaur.dinosaurexploder.components.ScoreComponent;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.text.Font;
import javafx.scene.text.FontWeight;

/**
* Developer-only debug menu for manually overriding game state during testing.
* This view should never be exposed to players in production builds.
*/
public class DebugMenu extends FXGLMenu {

public DebugMenu(ScoreComponent scoreComponent, CollectedCoinsComponent coinsComponent) {
super(MenuType.GAME_MENU); // ← FXGLMenu requires a MenuType, not a spacing int

// Build a VBox to hold all the controls, same layout as before
VBox layout = new VBox(12);
layout.setPadding(new Insets(16));
layout.setAlignment(Pos.TOP_LEFT);
layout.setStyle("-fx-background-color: rgba(0,0,0,0.85); -fx-border-color: yellow; -fx-border-width: 2;");
layout.setMaxWidth(280);

Label title = new Label("DEBUG MENU [DEV ONLY]");
title.setTextFill(Color.YELLOW);
title.setFont(Font.font("System", FontWeight.BOLD, 14));

// --- Score section ---
Label scoreLabel = new Label("Set Score:");
scoreLabel.setTextFill(Color.WHITE);
TextField scoreField = new TextField();
scoreField.setPromptText("Enter score value...");
Button setScoreButton = new Button("Set Score");
setScoreButton.setOnAction(e -> {
// TODO: wire up to scoreComponent.setScore(int)
});

// --- High score section ---
Label highScoreLabel = new Label("Set High Score:");
highScoreLabel.setTextFill(Color.WHITE);
TextField highScoreField = new TextField();
highScoreField.setPromptText("Enter high score value...");
Button setHighScoreButton = new Button("Set High Score");
setHighScoreButton.setOnAction(e -> {
// TODO: wire up to HighScore.setHigh(...)
});

// --- Coins section ---
Label coinsLabel = new Label("Set Coins:");
coinsLabel.setTextFill(Color.WHITE);
TextField coinsField = new TextField();
coinsField.setPromptText("Enter coin amount...");
Button setCoinsButton = new Button("Set Coins");
setCoinsButton.setOnAction(e -> {
// TODO: requires CollectedCoinsComponent.setCoin(int) to be added first
});

layout.getChildren().addAll(
title,
scoreLabel, scoreField, setScoreButton,
highScoreLabel, highScoreField, setHighScoreButton,
coinsLabel, coinsField, setCoinsButton
);

// ← FXGLMenu uses getContentRoot(), not getChildren() directly
getContentRoot().getChildren().add(layout);
}
}
51 changes: 39 additions & 12 deletions src/main/java/com/dinosaur/dinosaurexploder/view/DinosaurMenu.java
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@
import org.jetbrains.annotations.NotNull;

public class DinosaurMenu extends FXGLMenu {
private static final boolean DEBUG_MENU_ENABLED =
Boolean.parseBoolean(System.getProperty("debugMenu", "false"));

private final LanguageManager languageManager = LanguageManager.getInstance();
private final Settings settings = SettingsProvider.loadSettings();
private final MediaPlayer mainMenuSound;
Expand All @@ -55,6 +58,9 @@ public class DinosaurMenu extends FXGLMenu {
private final Button startButton = new Button("Start Game".toUpperCase());
private final Button quitButton = new Button("Quit".toUpperCase());
private final Button settingsButton = new Button("Options".toUpperCase());
// Dev-only debug menu button
private final Button debugButton = new Button("Debug Menu".toUpperCase());

private final Label languageLabel = new Label("Select Language:");

public DinosaurMenu() {
Expand Down Expand Up @@ -258,6 +264,12 @@ private void configureButtons() {
applyStylesheet(startButton);
applyStylesheet(quitButton);
applyStylesheet(settingsButton);
if (DEBUG_MENU_ENABLED) {
applyStylesheet(debugButton);
debugButton.setMinSize(140, 60);
debugButton.setTranslateY(660);
debugButton.setOnAction(event -> FXGL.getSceneService().pushSubScene(new DebugMenu(null, null)));
}

startButton.setMinSize(140, 60);
startButton.setTranslateY(420);
Expand Down Expand Up @@ -310,18 +322,20 @@ private void addComponentsToScene(
ImageView mute,
// VBox language,
VBox volumeControls) {
getContentRoot()
.getChildren()
.addAll(
background,
title,
startButton,
quitButton,
settingsButton,
dino,
creditsBadge,
mute,
volumeControls);
var children = getContentRoot().getChildren();
children.addAll(
background,
title,
startButton,
quitButton,
settingsButton,
dino,
creditsBadge,
mute,
volumeControls);
if (DEBUG_MENU_ENABLED) {
children.add(debugButton);
}
}

private void setupButtonCentering() {
Expand Down Expand Up @@ -351,12 +365,25 @@ private void setupButtonCentering() {
settingsButton.setTranslateX(getAppWidth() / 2.0 - newBounds.getWidth() / 2.0);
}
});
if (DEBUG_MENU_ENABLED) {
debugButton
.layoutBoundsProperty()
.addListener(
(obs, oldBounds, newBounds) -> {
if (newBounds.getWidth() > 0) {
debugButton.setTranslateX(getAppWidth() / 2.0 - newBounds.getWidth() / 2.0);
}
});
}

javafx.application.Platform.runLater(
() -> {
startButton.requestLayout();
quitButton.requestLayout();
settingsButton.requestLayout();
if (DEBUG_MENU_ENABLED) {
debugButton.requestLayout();
}
});
}

Expand Down