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
Binary file added assets/close-button.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/left-arrow.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/npc-frame.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/right-arrow.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions src/main/java/io/rpg/controller/Controller.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import io.rpg.model.actions.Action;
import io.rpg.model.actions.ActionConsumer;
import io.rpg.model.actions.DialogueAction;
import io.rpg.model.actions.ShowDescriptionAction;
import io.rpg.model.actions.GameEndAction;
import io.rpg.model.actions.LocationChangeAction;
Expand Down Expand Up @@ -108,6 +109,10 @@ private void onAction(LocationChangeAction action) {
mainStage.setScene(nextView);
}

private void onAction(DialogueAction action) {
popupController.openDialoguePopup(action.text, action.image, getWindowCenterX(), getWindowCenterY()); //TODO: load text from config
}

private void onAction(ShowDescriptionAction action) {
if (!action.description.isEmpty()) {
popupController.openTextImagePopup(action.description, action.image, getWindowCenterX(), getWindowCenterY());
Expand Down
16 changes: 13 additions & 3 deletions src/main/java/io/rpg/controller/PopupController.java
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
package io.rpg.controller;

import io.rpg.model.object.Question;
import io.rpg.view.popups.DialoguePopup;
import io.rpg.view.popups.QuestionPopup;
import io.rpg.view.popups.TextImagePopup;
import io.rpg.view.popups.TextPopup;
import javafx.scene.image.Image;
import javafx.stage.Stage;
import javafx.stage.StageStyle;


public class PopupController {

private final Stage popupStage = new Stage(StageStyle.TRANSPARENT);
Expand Down Expand Up @@ -68,11 +68,21 @@ public void openQuestionPopup(Question question, int x, int y) {
popupStage.setX(x - popupScene.getWidth() / 2);
popupStage.setY(y - popupScene.getHeight() / 2);
}

public void openDialoguePopup(String text, Image npcImage, int x, int y) {
DialoguePopup popupScene = new DialoguePopup(text, npcImage);
popupStage.setScene(popupScene);

popupStage.show();

popupStage.setX(x - popupScene.getWidth() / 2);
popupStage.setY(y - popupScene.getHeight() / 2);

popupScene.setCloseButtonCallback(event -> popupStage.hide());
}


public void hidePopup() {
popupStage.hide();
}

}

16 changes: 16 additions & 0 deletions src/main/java/io/rpg/model/actions/DialogueAction.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package io.rpg.model.actions;

import javafx.scene.image.Image;

/**
* Class for storing local data needed to perform a dialogue action.
*/
public class DialogueAction implements Action {
public final String text;
public final Image image;

public DialogueAction(String text, Image image) {
this.text = text;
this.image = image;
}
}
2 changes: 2 additions & 0 deletions src/main/java/io/rpg/model/object/GameObject.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import io.rpg.model.actions.Action;
import io.rpg.model.actions.BaseActionEmitter;
import io.rpg.model.actions.DialogueAction;
import io.rpg.model.actions.QuizAction;
import io.rpg.model.data.GameObjectStateChange;
import io.rpg.model.data.Position;
Expand All @@ -12,6 +13,7 @@
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.value.ObservableValue;
import javafx.geometry.Point2D;
import javafx.scene.image.Image;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

Expand Down
76 changes: 76 additions & 0 deletions src/main/java/io/rpg/view/popups/DialoguePopup.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package io.rpg.view.popups;

import io.rpg.viewmodel.DialoguePopupViewModel;
import javafx.event.EventHandler;
import javafx.fxml.FXMLLoader;
import javafx.scene.Group;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.scene.input.MouseEvent;
import javafx.scene.paint.Color;

import java.io.IOException;
import java.util.List;
import java.util.Objects;

public class DialoguePopup extends Scene {

private final DialoguePopupViewModel viewModel;
private final List<String> textPages;
private int currentPage = 0;

public DialoguePopup(String text, Image npcImage, String backgroundPath, String npcFramePath) {
this(text, npcImage);
viewModel.setBackgroundImage(backgroundPath);
viewModel.setNpcFrameImage(npcFramePath);
}

public DialoguePopup(String text, Image npcImage) {
super(new Group(), Color.TRANSPARENT);
FXMLLoader loader = new FXMLLoader(Objects.requireNonNull(DialoguePopupViewModel.class.getResource("dialogue-popup-view.fxml")));
Parent root = null;

try {
root = loader.load();
} catch (IOException e) {
e.printStackTrace();
}
this.setRoot(root);

viewModel = loader.getController();
viewModel.setNpcImage(npcImage);
this.setFill(Color.TRANSPARENT);

textPages = List.of(text.split("(?<=\\G.{200})")); //split text into 200-letter pages
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

splitting question into pages is nice, but we'll need a limit for answer's length, cause dividing answers into pages seems like too much for me (though it's just my opinion)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For now I've decided not to implement a back and forth dialogue. Thought of it as more of a guide or a quick tip for a player. I guess that's still up for debate.

viewModel.setText(textPages.get(currentPage));
if (textPages.size() == 1) {
viewModel.setNextVisibility(false);
}
viewModel.setPreviousVisibility(false);
viewModel.setNextButtonOnClick(event -> nextPage());
viewModel.setPreviousButtonOnClick(event -> previousPage());
}

public void setCloseButtonCallback(EventHandler<? super MouseEvent> callback) {
viewModel.setCloseButtonOnClick(callback);
}

public void nextPage() {
currentPage++;
viewModel.setText(textPages.get(currentPage));
if (currentPage == textPages.size() - 1) {
viewModel.setNextVisibility(false);
}
viewModel.setPreviousVisibility(true);
}

public void previousPage() {
currentPage--;
viewModel.setText(textPages.get(currentPage));
if (currentPage == 0) {
viewModel.setPreviousVisibility(false);
}
viewModel.setNextVisibility(true);
}
}
84 changes: 84 additions & 0 deletions src/main/java/io/rpg/viewmodel/DialoguePopupViewModel.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package io.rpg.viewmodel;

import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.ScrollPane;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Pane;
import javafx.scene.layout.StackPane;
import javafx.scene.text.Text;

public class DialoguePopupViewModel {

@FXML private Pane backgroundPane;
@FXML private StackPane npcFramePane;
@FXML private ImageView backgroundImage;
@FXML private ImageView npcImage;
@FXML private ImageView npcFrameImage;
@FXML private Text text;
@FXML private Button closeButton;
@FXML private Button nextButton;
@FXML private Button previousButton;

public void setText(String text) {
this.text.setText(text);
}

public void setNpcImage(Image image) {
npcImage.setImage(image);
}

public void setBackgroundImage(String url) {
Image image = new Image(url);
backgroundImage.setImage(image);
}

public void setCloseButtonImage(String url) {
ImageView imageView = new ImageView(url);
imageView.setFitWidth(16);
imageView.setPreserveRatio(true);
closeButton.setGraphic(imageView);
}

public void setNextButtonImage(String url) {
ImageView imageView = new ImageView(url);
imageView.setFitWidth(26);
imageView.setPreserveRatio(true);
nextButton.setGraphic(imageView);
}

public void setPreviousButtonImage(String url) {
ImageView imageView = new ImageView(url);
imageView.setFitWidth(26);
imageView.setPreserveRatio(true);
previousButton.setGraphic(imageView);
}

public void setNpcFrameImage(String url) {
Image image = new Image(url);
npcFrameImage.setImage(image);
}

public void setCloseButtonOnClick(EventHandler<? super MouseEvent> callback) {
closeButton.setOnMouseClicked(callback);
}

public void setNextVisibility(boolean value) {
nextButton.setVisible(value);
}

public void setPreviousVisibility(boolean value) {
previousButton.setVisible(value);
}

public void setNextButtonOnClick(EventHandler<? super MouseEvent> callback) {
nextButton.setOnMouseClicked(callback);
}

public void setPreviousButtonOnClick(EventHandler<? super MouseEvent> callback) {
previousButton.setOnMouseClicked(callback);
}
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, gj

65 changes: 65 additions & 0 deletions src/main/resources/io/rpg/viewmodel/dialogue-popup-view.fxml
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.Button?>
<?import javafx.scene.image.Image?>
<?import javafx.scene.image.ImageView?>
<?import javafx.scene.layout.Pane?>
<?import javafx.scene.layout.StackPane?>
<?import javafx.scene.text.Font?>
<?import javafx.scene.text.Text?>

<Pane fx:id="backgroundPane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="362.0" prefWidth="607.0" style="-fx-background-color: transparent;" xmlns="http://javafx.com/javafx/17" xmlns:fx="http://javafx.com/fxml/1" fx:controller="io.rpg.viewmodel.DialoguePopupViewModel">
<children>
<ImageView fx:id="backgroundImage" fitHeight="408.0" fitWidth="607.0" layoutX="-1.0" layoutY="-2.0" pickOnBounds="true" preserveRatio="true">
<image>
<Image url="@../../../../../../assets/popup-background.png" />
</image>
</ImageView>
<Button fx:id="closeButton" layoutX="528.0" layoutY="36.0" mnemonicParsing="false" prefHeight="26.0" prefWidth="24.0" style="-fx-background-color: transparent;">
<graphic>
<ImageView fitHeight="18.0" fitWidth="16.0" pickOnBounds="true" preserveRatio="true">
<image>
<Image url="@../../../../../../assets/close-button.png" />
</image>
</ImageView>
</graphic>
</Button>
<Text fx:id="text" fill="WHITE" layoutX="79.0" layoutY="175.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Hi! It's dangerous around here. You better watchout!" wrappingWidth="449.47006487846375">
<font>
<Font name="Monospaced Bold" size="18.0" />
</font>
</Text>
<StackPane fx:id="npcFramePane" layoutX="57.0" layoutY="36.0" prefHeight="85.0" prefWidth="84.0" style="-fx-background-color: brown;">
<children>
<ImageView fx:id="npcFrameImage" fitHeight="113.0" fitWidth="137.0" pickOnBounds="true" preserveRatio="true">
<image>
<Image url="@../../../../../../assets/npc-frame.png" />
</image>
</ImageView>
<ImageView fx:id="npcImage" fitHeight="100.0" fitWidth="135.0" pickOnBounds="true" preserveRatio="true">
<image>
<Image url="@../../../../../../assets/zombie.png" />
</image>
</ImageView>
</children>
</StackPane>
<Button fx:id="nextButton" layoutX="523.0" layoutY="280.0" mnemonicParsing="false" prefHeight="26.0" prefWidth="24.0" style="-fx-background-color: transparent;">
<graphic>
<ImageView fx:id="nextButtonImage" fitHeight="26.0" fitWidth="26.0" pickOnBounds="true" preserveRatio="true">
<image>
<Image url="@../../../../../../assets/right-arrow.png" />
</image>
</ImageView>
</graphic>
</Button>
<Button fx:id="previousButton" layoutX="57.0" layoutY="280.0" mnemonicParsing="false" prefHeight="26.0" prefWidth="24.0" style="-fx-background-color: transparent;">
<graphic>
<ImageView fx:id="previousButtonImage" fitHeight="26.0" fitWidth="26.0" pickOnBounds="true" preserveRatio="true">
<image>
<Image url="@../../../../../../assets/left-arrow.png" />
</image>
</ImageView>
</graphic>
</Button>
</children>
</Pane>