From 5f53564c3fbe03483d34289a9480fc7c03b451fd Mon Sep 17 00:00:00 2001
From: =
Date: Sun, 24 May 2026 16:57:37 +0200
Subject: [PATCH] Feat: Added help section in minigames overview
---
.../minigames/MiniGamesController.java | 20 ++-
.../view/widgets/minigames/MiniGamesView.java | 159 ++++++++++++++++--
2 files changed, 161 insertions(+), 18 deletions(-)
diff --git a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/widgets/minigames/MiniGamesController.java b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/widgets/minigames/MiniGamesController.java
index ee9a2d9..acad65a 100644
--- a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/widgets/minigames/MiniGamesController.java
+++ b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/widgets/minigames/MiniGamesController.java
@@ -1,7 +1,10 @@
package edu.ntnu.idi.idatt2003.g40.mappe.view.widgets.minigames;
import edu.ntnu.idi.idatt2003.g40.mappe.model.Stock;
+import edu.ntnu.idi.idatt2003.g40.mappe.service.event.EventData;
import edu.ntnu.idi.idatt2003.g40.mappe.service.event.EventManager;
+import edu.ntnu.idi.idatt2003.g40.mappe.service.event.EventSubscriber;
+import edu.ntnu.idi.idatt2003.g40.mappe.service.event.EventType;
import edu.ntnu.idi.idatt2003.g40.mappe.view.ViewController;
import edu.ntnu.idi.idatt2003.g40.mappe.view.ingame.InGameView;
import edu.ntnu.idi.idatt2003.g40.mappe.view.widgets.minigames.games.ClickerGame;
@@ -13,7 +16,9 @@
*
* Extends {@link ViewController}
* */
-public final class MiniGamesController extends ViewController {
+public final class MiniGamesController
+ extends ViewController
+ implements EventSubscriber {
/**
* The currently selected stock for the minigame.
@@ -81,13 +86,14 @@ public MiniGamesController(final MiniGamesView viewElement,
this.findStockGame = findStockGame;
this.timeInputsGame = timeInputsGame;
super(viewElement, eventManager);
+ eventManager.addSubscriber(this, EventType.SELECT_STOCK_FOR_MINIGAME);
refresh();
}
@Override
protected void initInteractions() {
getViewElement().setOnAction(MiniGamesActions.HELP, () -> {
- // Implement help dialog or print logic
+ getViewElement().showHelpSection();
});
getViewElement().setOnAction(MiniGamesActions.CLICKER_GAME, () -> {
@@ -109,10 +115,11 @@ protected void initInteractions() {
/**
* Sets the target stock context for the minigames.
*
- * @param stock Chosen active layout context stock.
+ * @param stock stock to set.
*/
public void setActiveStock(final Stock stock) {
this.activeStock = stock;
+ getViewElement().setSelectedStockText(stock.getSymbol());
gameEngineController.setChosenStock(stock);
refresh();
}
@@ -127,4 +134,11 @@ public void refresh() {
getViewElement().setSelectedStockText("None");
}
}
+
+ @Override
+ public void handleEvent(EventData data) {
+ if (data.data() instanceof Stock s) {
+ setActiveStock(s);
+ }
+ }
}
diff --git a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/widgets/minigames/MiniGamesView.java b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/widgets/minigames/MiniGamesView.java
index ca00af3..633c400 100644
--- a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/widgets/minigames/MiniGamesView.java
+++ b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/widgets/minigames/MiniGamesView.java
@@ -1,12 +1,18 @@
package edu.ntnu.idi.idatt2003.g40.mappe.view.widgets.minigames;
import edu.ntnu.idi.idatt2003.g40.mappe.view.ViewElement;
+import javafx.geometry.Insets;
+import javafx.geometry.Pos;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
+import javafx.scene.control.ScrollPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.Region;
+import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
+import javafx.scene.text.Text;
+import javafx.scene.text.TextFlow;
/**
* Minigames view in the in game section of the application.
@@ -17,7 +23,13 @@
* To see the elements creating the minigames themselves,
* see {@link GameEngineView}.
* */
-public final class MiniGamesView extends ViewElement {
+public final class MiniGamesView
+ extends ViewElement {
+
+ /**
+ * Main layout container.
+ * */
+ private VBox mainLayoutContainer;
/**
* Top section of the page (Title, selected stock, question mark block).
@@ -72,21 +84,146 @@ public final class MiniGamesView extends ViewElement {
* */
private Button timeInputsBtn;
+ /**
+ * Overlay for help section when pressing help button.
+ * */
+ private StackPane helpOverlay;
+
/**
* Constructor.
*/
public MiniGamesView() throws IllegalArgumentException {
- super(new VBox(), MiniGamesActions.class);
+ super(new StackPane(), MiniGamesActions.class);
+ }
+
+ /**
+ * Updates the selected stock text.
+ *
+ * @param symbol the symbol representing the stock selected.
+ */
+ public void setSelectedStockText(final String symbol) {
+ stockValueLabel.setText(symbol);
+ }
+
+ /**
+ * Method for showing the help section for minigames.
+ * */
+ public void showHelpSection() {
+ if (helpOverlay != null) {
+ return;
+ }
+
+ helpOverlay = new StackPane();
+ helpOverlay.getStyleClass().add("minigames-help-overlay-dimmer");
+
+ StackPane modalCard = new StackPane();
+ modalCard.getStyleClass().add("minigames-help-container");
+
+ VBox textContainer = new VBox();
+ textContainer.getStyleClass().add("minigames-help-text-vbox");
+
+ textContainer.getChildren().add(createTextParagraph("MINIGAMES",
+ "Welcome to the minigames section! Here you can boost a selected stock (choose in dashboard page)"
+ + " by playing minigames! A minigame takes one minute, and you are able to exit before the time runs out."
+ + " This will not have any negative effects. "
+ + " When you complete a minigame, you get a rank based on your score. Higher scores yield a higher rank."
+ + " The higher rank you are at the end of the round, the more fortune the selected stock will get."
+ + " Every stock can only be boosted one time per week by playing minigames, so play minigames for all your investments!"));
+
+ textContainer.getChildren().add(createTextParagraph("What are minigames?",
+ "A minigame is a short interactive experience where you are able to gain points by performing"
+ + " task(s) that are differ from minigame to minigame. Each minigame session takes exactly one minute to complete"
+ + " from start to finish, and you will gain a report based on your performance at the end of the round."
+ + " You can also choose to exit before a round ends to go back, but note that quitting after the round ends"
+ + " will still cause the effect."));
+
+ textContainer.getChildren().add(createTextParagraph("Rank",
+ "When playing minigames, you gain score. By earning enough score, you increase your rank."
+ + " At the end of a round, you are given a game report that shows your rank."
+ + " The higher your rank, the better the fortune for the selected stock will be."));
+
+ textContainer.getChildren().add(createTextParagraph("Fortune",
+ "In the minigame page, you can see your selected stock. This stock will then get a"
+ + " positive or negative flat percent amount added to their next weekly price change, based on your rank."
+ + " This is called the stocks fortune."
+ + " Each stock can only be manipulated once per week by playing minigames, so be sure to"
+ + " play minigames for all your investments!"));
+
+ textContainer.getChildren().add(createTextParagraph("Minigame 1: Clicker Minigame",
+ "Click the primary action tile to increase points. Balance your point allocation strategy between immediate click returns and structural upgrades."));
+
+ textContainer.getChildren().add(createTextParagraph("Minigame 2: Find The Stock",
+ "Scan the choice matrix panel grid and find the symbol matching the target description. Incorrect selections will deduct points."));
+
+ textContainer.getChildren().add(createTextParagraph("Minigame 3: Timed Inputs.",
+ "Track the white line that moves across the circle circumference. Fire your strike command inputs using SPACE or ENTER precisely inside the highlighted chartreuse section"
+ + " to gain points. Incorrect firing will deduct points."));
+
+ ScrollPane scrollPane = new ScrollPane(textContainer);
+ scrollPane.getStyleClass().add("minigames-help-scroll-pane");
+ scrollPane.setFitToWidth(true);
+ scrollPane.setVbarPolicy(ScrollPane.ScrollBarPolicy.AS_NEEDED);
+ scrollPane.setHbarPolicy(ScrollPane.ScrollBarPolicy.NEVER);
+
+ modalCard.getChildren().add(scrollPane);
+
+ Button closeBtn = new Button("X");
+ closeBtn.setFocusTraversable(false);
+
+ closeBtn.getStyleClass().add("minigames-help-closeBtn");
+
+ closeBtn.setOnAction(e -> hideHelpSection());
+
+ modalCard.getChildren().add(closeBtn);
+ StackPane.setAlignment(closeBtn, Pos.TOP_RIGHT);
+ StackPane.setMargin(closeBtn, new Insets(10, 10, 0, 0));
+
+ helpOverlay.getChildren().add(modalCard);
+ getRootPane().getChildren().add(helpOverlay);
+ }
+
+ /**
+ * Helper method for formatting a {@link TextFlow}
+ * object with a header and paragraph.
+ *
+ * @param headerText the title of the paragraph.
+ * @param descText the paragraph itself.
+ *
+ * @return formatted {@link TextFlow} object.
+ */
+ private TextFlow createTextParagraph(final String headerText,
+ final String descText) {
+ TextFlow textFlow = new TextFlow();
+ Text header = new Text(headerText + "\n");
+ Text desc = new Text(descText);
+
+ textFlow.getStyleClass().add("minigames-help-textflow");
+ header.getStyleClass().add("minigames-help-header");
+ desc.getStyleClass().add("minigames-help-description");
+
+ textFlow.getChildren().addAll(header, desc);
+ return textFlow;
+ }
+
+ /**
+ * Cleans down the operational help window layer state.
+ */
+ public void hideHelpSection() {
+ if (helpOverlay != null) {
+ getRootPane().getChildren().remove(helpOverlay);
+ helpOverlay = null;
+ }
}
@Override
protected void initLayout() {
+ mainLayoutContainer = new VBox();
headerBar = new HBox();
- titleLabel = new Label("Mini games");
+ titleLabel = new Label("Minigames");
stockSelectionRow = new HBox();
selectedStockLabel = new Label("Selected stock: ");
- stockValueLabel = new Label("AAPL");
+ stockValueLabel = new Label("");
stockSelectionRow.getChildren().addAll(selectedStockLabel, stockValueLabel);
VBox titleSection = new VBox();
@@ -112,7 +249,8 @@ protected void initLayout() {
findStockBtn, timeInputsBtn);
VBox.setVgrow(gamesContainer, Priority.ALWAYS);
- getRootPane().getChildren().addAll(headerBar, gamesContainer);
+ mainLayoutContainer.getChildren().addAll(headerBar, gamesContainer);
+ getRootPane().getChildren().add(mainLayoutContainer);
registerButton(MiniGamesActions.HELP, helpBtn);
registerButton(MiniGamesActions.CLICKER_GAME, clickerGameBtn);
@@ -120,18 +258,9 @@ protected void initLayout() {
registerButton(MiniGamesActions.TIME_CLICKS, timeInputsBtn);
}
- /**
- * Updates the selected stock text.
- *
- * @param symbol the symbol representing the stock selected.
- */
- public void setSelectedStockText(final String symbol) {
- stockValueLabel.setText(symbol);
- }
-
@Override
protected void initStyling() {
- getRootPane().getStyleClass().add("minigames-root");
+ mainLayoutContainer.getStyleClass().add("minigames-root");
headerBar.getStyleClass().add("minigames-headerBar");
stockSelectionRow.getStyleClass().add("minigames-stockSelectionRow");
titleLabel.getStyleClass().add("minigames-titleLabel");