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");