Skip to content
Snippets Groups Projects
Commit 77a185af authored by Trym Hamer Gudvangen's avatar Trym Hamer Gudvangen
Browse files

Merge branch 'enhance/playtrough' into 'feat/part-three'

Enhance/playtrough

See merge request !26
parents 4ab420a2 4b922a43
No related branches found
No related tags found
2 merge requests!26Enhance/playtrough,!7Feat/part three
Pipeline #229475 passed
Showing
with 289 additions and 86 deletions
......@@ -3,13 +3,18 @@ package edu.ntnu.idatt2001.group_30.paths;
import edu.ntnu.idatt2001.group_30.paths.model.Player;
import edu.ntnu.idatt2001.group_30.paths.model.Story;
import edu.ntnu.idatt2001.group_30.paths.model.goals.*;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import javafx.scene.image.ImageView;
/**
* This enumeration is constructed using the singleton design pattern. The implementation of this design pattern
* restricts the amount of instances of the enumeration to one. This is essential for the enumeration's purpose.
* The enum contains all the data that needs to be transmitted between controllers.
*
* @author Trym Hamer Gudvangen
* @author Trym Hamer Gudvangen, Nicolai H. Brand.
*/
public enum PathsSingleton {
INSTANCE;
......@@ -21,6 +26,7 @@ public enum PathsSingleton {
private ScoreGoal scoreGoal;
private InventoryGoal inventoryGoal;
private GoldGoal goldGoal;
private ImageView characterImageView;
/**
* This method gets the current selected story.
......@@ -85,6 +91,30 @@ public enum PathsSingleton {
};
}
public ImageView getCharacterImageView() {
return characterImageView;
}
public void setCharacterImageView(ImageView characterImageView) {
this.characterImageView = characterImageView;
}
/**
* Returns a list of all the non-null goals.
* @return A list of all the non-null goals, given as a List of Goal objects.
*/
public List<Goal> getGoals() {
List<Goal> goals = Stream
.of(healthGoal, scoreGoal, goldGoal)
.filter(Objects::nonNull)
.collect(Collectors.toList());
if (inventoryGoal != null && inventoryGoal.getGoalValue().size() != 0) {
goals.add(inventoryGoal);
}
return goals;
}
/**
* This method checks whether a passage is currently being moved.
* @return The passageMoving status, given as a boolean. {@code true} if the passage is moving, else {@code false}
......
package edu.ntnu.idatt2001.group_30.paths.controller;
import edu.ntnu.idatt2001.group_30.paths.view.HomeView;
import edu.ntnu.idatt2001.group_30.paths.view.View;
import edu.ntnu.idatt2001.group_30.paths.view.ViewFactory;
import edu.ntnu.idatt2001.group_30.paths.view.views.HomeView;
import edu.ntnu.idatt2001.group_30.paths.view.views.View;
import edu.ntnu.idatt2001.group_30.paths.view.views.ViewFactory;
import java.util.HashMap;
import java.util.Map;
import javafx.event.ActionEvent;
......@@ -44,6 +44,15 @@ public class Controller {
return actionEvent -> STAGE_MANAGER.goBack();
}
/**
* Go back to the previous instance of the given view class.
* @param viewClass The class of the view to go back to.
* @return An EventHandler that will set the current view to the previous instance of the given view class.
*/
public EventHandler<ActionEvent> goBackTo(Class<? extends View<?>> viewClass) {
return actionEvent -> STAGE_MANAGER.goBackTo(viewClass);
}
public Stage getRootStage() {
return STAGE_MANAGER.getStage();
}
......
package edu.ntnu.idatt2001.group_30.paths.controller;
import edu.ntnu.idatt2001.group_30.paths.view.NewGameView;
import edu.ntnu.idatt2001.group_30.paths.view.views.NewGameView;
public class CreatePlayerController extends Controller {
......
package edu.ntnu.idatt2001.group_30.paths.controller;
import edu.ntnu.idatt2001.group_30.paths.view.HomeView;
import edu.ntnu.idatt2001.group_30.paths.view.views.HomeView;
/**
* This class is used to control the HelpView.
......
package edu.ntnu.idatt2001.group_30.paths.controller;
import edu.ntnu.idatt2001.group_30.paths.view.CreatePlayerView;
import edu.ntnu.idatt2001.group_30.paths.view.HelpView;
import edu.ntnu.idatt2001.group_30.paths.view.NewGameView;
import edu.ntnu.idatt2001.group_30.paths.view.PlaythroughView;
import edu.ntnu.idatt2001.group_30.paths.view.views.CreatePlayerView;
import edu.ntnu.idatt2001.group_30.paths.view.views.HelpView;
import edu.ntnu.idatt2001.group_30.paths.view.views.NewGameView;
import edu.ntnu.idatt2001.group_30.paths.view.views.PlaythroughView;
/**
* This class is used to control the HomeView.
......
......@@ -3,7 +3,7 @@ package edu.ntnu.idatt2001.group_30.paths.controller;
import static edu.ntnu.idatt2001.group_30.paths.PathsSingleton.INSTANCE;
import edu.ntnu.idatt2001.group_30.paths.model.filehandling.StoryFileHandler;
import edu.ntnu.idatt2001.group_30.paths.view.PlaythroughView;
import edu.ntnu.idatt2001.group_30.paths.view.views.PlaythroughView;
import java.io.File;
import java.io.IOException;
......
......@@ -4,16 +4,16 @@ import static edu.ntnu.idatt2001.group_30.paths.PathsSingleton.INSTANCE;
import edu.ntnu.idatt2001.group_30.paths.model.*;
import edu.ntnu.idatt2001.group_30.paths.model.goals.Goal;
import edu.ntnu.idatt2001.group_30.paths.model.goals.HealthGoal;
import edu.ntnu.idatt2001.group_30.paths.model.goals.ScoreGoal;
import edu.ntnu.idatt2001.group_30.paths.view.HelpView;
import edu.ntnu.idatt2001.group_30.paths.view.HomeView;
import edu.ntnu.idatt2001.group_30.paths.view.views.HelpView;
import edu.ntnu.idatt2001.group_30.paths.view.views.HomeView;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Objects;
import javafx.beans.property.*;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.collections.ObservableMap;
import javafx.scene.image.ImageView;
/**
* Controller for the play-through of the game.
......@@ -26,6 +26,7 @@ public class PlaytroughController extends Controller {
private Game game;
/* reactive state */
private final StringProperty gameTitle = new SimpleStringProperty("Playing: " + INSTANCE.getStory().getTitle());
private final StringProperty passageTitle = new SimpleStringProperty();
private final StringProperty passageContent = new SimpleStringProperty();
private final ObservableList<Link> links = FXCollections.observableList(new ArrayList<>());
......@@ -52,16 +53,17 @@ public class PlaytroughController extends Controller {
* It also resets the reactive properties.
*/
public void startNewGame() {
//TODO: add from Singleton
Player player = new Player("Gorm", 50, 0, 100);
HealthGoal healthGoal = new HealthGoal(10);
ScoreGoal scoreGoal = new ScoreGoal(100);
ArrayList<Goal> goals = new ArrayList<>();
goals.add(healthGoal);
goals.add(scoreGoal);
assert INSTANCE.getPlayer() != null;
assert INSTANCE.getStory() != null;
assert INSTANCE.getGoals() != null;
/* cleanup previous game */
gameAlreadyWon = false;
game = new Game(player, INSTANCE.getStory(), goals);
gameOver.set(false);
gameWon.set(false);
/* start new game */
game = new Game(new Player(INSTANCE.getPlayer()), INSTANCE.getStory(), INSTANCE.getGoals());
Passage openingPassage = game.begin();
updateReactiveProperties(openingPassage);
}
......@@ -87,13 +89,14 @@ public class PlaytroughController extends Controller {
updateGoals();
updateGameState();
updateInventory();
updateGameTitle();
}
/**
* Computes the current state of the game.
* Updates the reactive properties based on the current state of the game.
*/
private void updateGameState() {
public void updateGameState() {
if (gameAlreadyWon) return;
if (game.isGameWon()) {
......@@ -139,6 +142,20 @@ public class PlaytroughController extends Controller {
inventory.addAll(getPlayer().getInventory());
}
/**
* Updates the game title based on the game state.
*/
private void updateGameTitle() {
System.out.println("value: " + gameWon.getValue() + " " + gameOver.getValue() + " " + gameAlreadyWon);
if (gameOver.getValue()) {
gameTitle.setValue("You died and lost the game!");
} else if (gameWon.getValue()) {
gameTitle.setValue("You won! (You can still play on)");
} else {
gameTitle.setValue("Playing: " + INSTANCE.getStory().getTitle());
}
}
/**
* Returns the title of the current passage as an observable StringProperty.
* @return the title of the current passage.
......@@ -180,21 +197,29 @@ public class PlaytroughController extends Controller {
}
/**
* Returns the current story.
* Helper method that returns the current story.
* @return the current story.
*/
public Story getStory() {
private Story getStory() {
return game.getStory();
}
/**
* Returns the current player.
* Helper method that returns the current player.
* @return the current player.
*/
public Player getPlayer() {
private Player getPlayer() {
return game.getPlayer();
}
/**
* Returns the name of the player.
* @return the name of the player.
*/
public String getPlayerName() {
return game.getPlayer().getName();
}
/**
* Returns the health of the player as an observable StringProperty.
* @return the health of the player.
......@@ -234,4 +259,21 @@ public class PlaytroughController extends Controller {
public BooleanProperty getGameWon() {
return gameWon;
}
/**
* Returns the title of the game as an observable StringProperty.
* The title of the game will be the title of the story while playing. If not playing, it will show the status of the game.
* @return the title of the game.
*/
public StringProperty getGameTitle() {
return gameTitle;
}
/**
* Returns the image of the character as an ImageView.
* @return the image of the character.
*/
public ImageView getCharacterImageView() {
return INSTANCE.getCharacterImageView();
}
}
package edu.ntnu.idatt2001.group_30.paths.controller;
import edu.ntnu.idatt2001.group_30.paths.view.View;
import edu.ntnu.idatt2001.group_30.paths.view.views.View;
import java.util.Stack;
import javafx.stage.Stage;
......@@ -71,6 +71,22 @@ public class StageManager {
}
}
/**
* Sets the current view of the stage to the previous instance of the given view class.
* If the view is not in the viewStack, an IllegalArgumentException is thrown.
* @param viewClass The class of the view to go back to.
* @throws IllegalArgumentException if the view is not in the viewStack.
*/
public void goBackTo(Class<? extends View<?>> viewClass) throws IllegalArgumentException {
while (viewStack.size() > 1 && !viewStack.peek().getClass().equals(viewClass)) {
popAndUpdate();
}
if (viewStack.size() == 1 && !viewStack.peek().getClass().equals(viewClass)) {
throw new IllegalArgumentException("The view " + viewClass.getSimpleName() + " is not in the viewStack.");
}
}
/**
* Pushes the given view onto the viewStack and updates the stage.
* @param view The view to push onto the viewStack.
......
......@@ -37,6 +37,19 @@ public class Player {
this.inventory = new ArrayList<>();
}
/**
* This constructor creates a new Player from an existing Player object.
* This creates a deep copy of the Player object.
* @param player The Player object to be copied.
*/
public Player(Player player) {
this.name = player.name;
this.health = player.health;
this.score = player.score;
this.gold = player.gold;
this.inventory = new ArrayList<>(player.inventory);
}
/**
* The Builder class is used to create a Player object.
* @param build The Builder object that contains the information needed to create a Player object.
......
......@@ -38,6 +38,10 @@ public class Story {
addPassage(this.openingPassage);
}
public boolean goalsAreAchievable() {
return true;
}
/**
* Adds a passage to the passages map
* The link object used as the key in the map is made from properties of the passage
......
......@@ -18,9 +18,9 @@ public class InventoryGoal implements Goal<List<String>> {
* The constructor defines the items a player must have.
* @param mandatoryItems Expected items, given as a List{@code <String>}.
*/
public InventoryGoal(List<String> mandatoryItems) {
public InventoryGoal(List<String> mandatoryItems) throws IllegalArgumentException {
Objects.requireNonNull(mandatoryItems);
this.mandatoryItems = mandatoryItems;
//TODO: Add exception?
}
/**
......
package edu.ntnu.idatt2001.group_30.paths.view;
import edu.ntnu.idatt2001.group_30.paths.controller.StageManager;
import edu.ntnu.idatt2001.group_30.paths.view.views.HomeView;
import javafx.application.Application;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
......
......@@ -9,8 +9,6 @@ import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.HBox;
//TODO: make this into an HBOX with arrows that actually work.
// Add option of looping or not and adjust how arrows are display accordingly
public class ImageCarousel {
private final LinkedList<Image> images = new LinkedList<>();
......@@ -50,7 +48,6 @@ public class ImageCarousel {
HBox carousel = new HBox(leftButton, currentImage, rightButton);
carousel.setAlignment(Pos.CENTER);
return carousel;
}
......@@ -67,4 +64,8 @@ public class ImageCarousel {
public int size() {
return size;
}
public ImageView getCurrentImage() {
return currentImage;
}
}
......@@ -20,7 +20,7 @@ public class DefaultFont {
* @return A JavaFX font.
*/
public static Font big() {
return new Font(DEFAULT_FONT, 48);
return new Font(DEFAULT_FONT, 42);
}
/**
......@@ -28,7 +28,7 @@ public class DefaultFont {
* @return A JavaFX font.
*/
public static Font medium() {
return new Font(DEFAULT_FONT, 24);
return new Font(DEFAULT_FONT, 26);
}
/**
......
package edu.ntnu.idatt2001.group_30.paths.view;
package edu.ntnu.idatt2001.group_30.paths.view.views;
import static edu.ntnu.idatt2001.group_30.paths.PathsSingleton.INSTANCE;
......@@ -17,7 +17,7 @@ import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;
import javafx.scene.image.ImageView;
import javafx.scene.image.*;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
......@@ -97,11 +97,10 @@ public class CreatePlayerView extends View<BorderPane> {
legsURIs.add("/images/GreenLegs.png");
ImageCarousel headCarousel = new ImageCarousel(headURIs);
ImageCarousel headCarousel2 = new ImageCarousel(torsoURIs);
ImageCarousel headCarousel3 = new ImageCarousel(legsURIs);
VBox centerBox = new VBox(headCarousel.getCarousel(), headCarousel2.getCarousel(), headCarousel3.getCarousel());
ImageCarousel torsoCarousel = new ImageCarousel(torsoURIs);
ImageCarousel legsCarousel = new ImageCarousel(legsURIs);
VBox centerBox = new VBox(headCarousel.getCarousel(), torsoCarousel.getCarousel(), legsCarousel.getCarousel());
centerBox.setAlignment(Pos.CENTER);
leftVBox.getStyleClass().add("left-vbox");
nameField = new TextField();
......@@ -114,7 +113,12 @@ public class CreatePlayerView extends View<BorderPane> {
continueButton = new Button("Continue");
returnButton = new Button("Return");
HBox bottomBox = new HBox(nameField, continueButton, returnButton);
HBox viewButtons = new HBox(returnButton, continueButton);
returnButton.setAlignment(Pos.CENTER_LEFT);
continueButton.setAlignment(Pos.CENTER_RIGHT);
viewButtons.setSpacing(200);
VBox bottomBox = new VBox(nameField, viewButtons);
bottomBox.setSpacing(20);
bottomBox.setAlignment(Pos.CENTER);
bottomBox.setPadding(new Insets(0, 0, 0, 0));
......@@ -137,6 +141,24 @@ public class CreatePlayerView extends View<BorderPane> {
INSTANCE.getPlayer().getGold()
)
);
Image headImage = headCarousel.getCurrentImage().getImage();
Image torsoImage = torsoCarousel.getCurrentImage().getImage();
Image legsImage = legsCarousel.getCurrentImage().getImage();
WritableImage characterImage = new WritableImage(
(int) headImage.getWidth(),
(int) headImage.getHeight() * 3
);
PixelWriter writer = characterImage.getPixelWriter();
copyImageOnto(headImage, writer, 0);
copyImageOnto(torsoImage, writer, (int) headImage.getHeight());
copyImageOnto(legsImage, writer, (int) ((int) headImage.getHeight() + torsoImage.getHeight()));
ImageView characterImageView = new ImageView(characterImage);
INSTANCE.setCharacterImageView(characterImageView);
createPlayerController.goTo(NewGameView.class).handle(event);
} catch (Exception e) {
AlertDialog.showWarning(e.getMessage());
......@@ -144,4 +166,13 @@ public class CreatePlayerView extends View<BorderPane> {
});
returnButton.setOnAction(e -> StageManager.getInstance().goBack());
}
private void copyImageOnto(Image image, PixelWriter writer, int yOffset) {
PixelReader reader = image.getPixelReader();
for (int y = 0; y < image.getHeight(); y++) {
for (int x = 0; x < image.getWidth(); x++) {
writer.setColor(x, y + yOffset, reader.getColor(x, y));
}
}
}
}
package edu.ntnu.idatt2001.group_30.paths.view;
package edu.ntnu.idatt2001.group_30.paths.view.views;
import edu.ntnu.idatt2001.group_30.paths.controller.HelpController;
import edu.ntnu.idatt2001.group_30.paths.controller.StageManager;
......
package edu.ntnu.idatt2001.group_30.paths.view;
package edu.ntnu.idatt2001.group_30.paths.view.views;
import edu.ntnu.idatt2001.group_30.paths.controller.HomeController;
import edu.ntnu.idatt2001.group_30.paths.view.components.common.DefaultButton;
......@@ -43,7 +43,7 @@ public class HomeView extends View<VBox> {
private List<Node> getStartMenuButtons() {
List<Node> buttons = new ArrayList<>();
if (controller.canContinueAGame()) buttons.add(
DefaultButton.big("Continue", controller.goTo(PlaythroughView.class))
DefaultButton.big("Continue", controller.goBackTo(PlaythroughView.class))
);
buttons.add(DefaultButton.big("New game", controller.goTo(CreatePlayerView.class)));
buttons.add(DefaultButton.big("Help", controller.goTo(HelpView.class)));
......
package edu.ntnu.idatt2001.group_30.paths.view;
package edu.ntnu.idatt2001.group_30.paths.view.views;
import static edu.ntnu.idatt2001.group_30.paths.PathsSingleton.INSTANCE;
import edu.ntnu.idatt2001.group_30.paths.controller.NewGameController;
import edu.ntnu.idatt2001.group_30.paths.controller.StageManager;
import edu.ntnu.idatt2001.group_30.paths.view.StoryDisplay;
import edu.ntnu.idatt2001.group_30.paths.view.components.common.DefaultButton;
import edu.ntnu.idatt2001.group_30.paths.view.components.pop_up.AlertDialog;
import java.io.File;
......@@ -56,13 +57,8 @@ public class NewGameView extends View<BorderPane> {
Button backButton = new Button("Back");
backButton.setOnAction(e -> StageManager.getInstance().goBack());
/*
Button startButton = new Button("Start");
startButton.setOnAction(e -> {
newGameController.goTo(PlaythroughView.class);
});
*/
Button startButton = DefaultButton.medium("Start game", newGameController.goTo(PlaythroughView.class));
startButton = DefaultButton.medium("Start game", newGameController.goTo(PlaythroughView.class));
startButton.setVisible(false);
HBox buttonBox = new HBox(10, backButton, startButton);
buttonBox.setAlignment(Pos.CENTER);
......
package edu.ntnu.idatt2001.group_30.paths.view;
package edu.ntnu.idatt2001.group_30.paths.view.views;
import edu.ntnu.idatt2001.group_30.paths.controller.PlaytroughController;
import edu.ntnu.idatt2001.group_30.paths.model.*;
import edu.ntnu.idatt2001.group_30.paths.model.Link;
import edu.ntnu.idatt2001.group_30.paths.model.goals.Goal;
import edu.ntnu.idatt2001.group_30.paths.view.components.common.DefaultButton;
import edu.ntnu.idatt2001.group_30.paths.view.components.common.DefaultText;
import edu.ntnu.idatt2001.group_30.paths.view.components.common.Ref;
import edu.ntnu.idatt2001.group_30.paths.view.components.pop_up.AlertDialog;
import java.net.URL;
import javafx.collections.ListChangeListener;
import javafx.collections.MapChangeListener;
import javafx.collections.ObservableList;
import javafx.collections.ObservableMap;
import javafx.geometry.Insets;
import javafx.geometry.Orientation;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.control.Button;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.Separator;
import javafx.scene.image.ImageView;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import javafx.scene.shape.Box;
import javafx.scene.text.Text;
/**
......@@ -102,7 +107,7 @@ public class PlaythroughView extends View<VBox> {
header.setBackground(new Background(new BackgroundFill(Color.LIGHTBLUE, null, null)));
/* header content */
header.getChildren().add(DefaultText.big("Playing: " + controller.getStory().getTitle()));
header.getChildren().add(Ref.bigText(controller.getGameTitle()));
header.getChildren().add(new Separator(Orientation.VERTICAL));
header.getChildren().add(DefaultButton.medium("Home", controller.goTo(HomeView.class)));
header
......@@ -133,43 +138,57 @@ public class PlaythroughView extends View<VBox> {
private Node playtroughBox(Pane parentPane) {
/* container box configuration */
VBox playtrough = new VBox();
playtrough.prefWidthProperty().bind(parentPane.widthProperty().multiply(0.7));
playtrough.getStyleClass().add("box-shadow");
playtrough.prefWidthProperty().bind(parentPane.widthProperty().multiply(0.6));
playtrough.prefHeightProperty().bind(parentPane.heightProperty());
playtrough.setAlignment(Pos.TOP_CENTER);
playtrough.setBackground(new Background(new BackgroundFill(Color.LIGHTBLUE, new CornerRadii(30), null)));
/* Passage title */
playtrough.getChildren().add(Ref.bigText(controller.getPassageTitle()));
playtrough.getChildren().add(Ref.mediumText(controller.getPassageTitle()));
/* Passage content */
ScrollPane passagePane = new ScrollPane();
passagePane.paddingProperty().setValue(new javafx.geometry.Insets(20));
passagePane.setMinHeight(350);
Text content = Ref.mediumText(controller.getPassageContent());
Text content = Ref.smallText(controller.getPassageContent());
content.wrappingWidthProperty().bind(passagePane.widthProperty().multiply(0.85));
passagePane.setContent(content);
playtrough.getChildren().add(passagePane);
/* links */
ScrollPane linksBoxWrapper = new ScrollPane();
linksBoxWrapper.prefHeightProperty().bind(parentPane.heightProperty().multiply(0.5));
linksBoxWrapper.centerShapeProperty().setValue(true);
VBox linksBox = new VBox();
linksBox.setAlignment(Pos.TOP_CENTER);
linksBox.prefWidthProperty().bind(linksBoxWrapper.widthProperty());
linksBox.setSpacing(10);
ObservableList<Link> links = controller.getLinks();
links.addListener(
(ListChangeListener<Link>) change -> {
linksBox.getChildren().clear();
for (Link link : links) {
linksBox.getChildren().add(DefaultButton.big(link.getText(), e -> controller.chooseLink(link)));
}
populateLinksBox(linksBox, links);
}
);
for (Link link : links) {
linksBox.getChildren().add(DefaultButton.big(link.getText(), e -> controller.chooseLink(link)));
}
playtrough.getChildren().add(linksBox);
populateLinksBox(linksBox, links);
linksBoxWrapper.setContent(linksBox);
playtrough.getChildren().add(linksBoxWrapper);
return playtrough;
}
private void populateLinksBox(VBox linksBox, ObservableList<Link> links) {
linksBox.getChildren().clear();
for (Link link : links) {
Button button = DefaultButton.medium(link.getText(), e -> controller.chooseLink(link));
button.setWrapText(true);
button.setPrefWidth(300);
button.getStyleClass().add("link-button");
linksBox.getChildren().add(button);
}
}
/**
* Creates the info box.
* It contains the current player information, like health, score and gold.
......@@ -179,11 +198,11 @@ public class PlaythroughView extends View<VBox> {
*/
private Node infoBox(Pane parentPane) {
VBox infoBox = new VBox();
infoBox.prefWidthProperty().bind(parentPane.widthProperty().multiply(0.3));
infoBox.prefWidthProperty().bind(parentPane.widthProperty().multiply(0.4));
infoBox.prefHeightProperty().bind(parentPane.heightProperty());
infoBox.setAlignment(Pos.TOP_CENTER);
infoBox.setSpacing(10);
infoBox.setPadding(new javafx.geometry.Insets(10));
infoBox.setSpacing(20);
infoBox.setPadding(new Insets(0, 0, 0, 20)); // Set 20 pixels of left padding
/* player information */
infoBox.getChildren().add(playerInfo(infoBox));
......@@ -201,34 +220,58 @@ public class PlaythroughView extends View<VBox> {
* @return The parent node of the player information box.
*/
private Node playerInfo(Pane parentPane) {
/*
* Player info:
* player info | image
*/
VBox playerInfoBox = new VBox();
playerInfoBox.getStyleClass().add("box-shadow");
playerInfoBox.prefHeightProperty().bind(parentPane.heightProperty().multiply(0.3));
playerInfoBox.setBackground(new Background(new BackgroundFill(Color.LIGHTBLUE, new CornerRadii(30), null)));
playerInfoBox.setAlignment(Pos.TOP_CENTER);
playerInfoBox.setSpacing(10);
final Player player = controller.getPlayer();
/* title */
playerInfoBox.getChildren().add(DefaultText.medium("Player info:"));
/* player data and image container */
HBox playerDataAndImage = new HBox();
playerDataAndImage.setAlignment(Pos.TOP_LEFT);
playerInfoBox.getChildren().add(DefaultText.medium("Game info:"));
playerInfoBox.getChildren().add(DefaultText.small("Player name: " + player.getName()));
/* player data */
VBox playerData = new VBox();
playerData.setAlignment(Pos.TOP_CENTER);
playerData.setSpacing(10);
playerData.prefWidthProperty().bind(playerInfoBox.widthProperty().multiply(0.5));
playerData.getChildren().add(DefaultText.small("Name: " + controller.getPlayerName()));
HBox score = new HBox();
score.setAlignment(Pos.TOP_CENTER);
score.getChildren().add(DefaultText.small("Score: "));
score.getChildren().add(Ref.smallText(controller.getScore()));
playerInfoBox.getChildren().add(score);
playerData.getChildren().add(score);
HBox health = new HBox();
health.setAlignment(Pos.TOP_CENTER);
health.getChildren().add(DefaultText.small("Health: "));
health.getChildren().add(Ref.smallText(controller.getHealth()));
playerInfoBox.getChildren().add(health);
playerData.getChildren().add(health);
HBox gold = new HBox();
gold.setAlignment(Pos.TOP_CENTER);
gold.getChildren().add(DefaultText.small("Gold: "));
gold.getChildren().add(Ref.smallText(controller.getGold()));
playerInfoBox.getChildren().add(gold);
playerData.getChildren().add(gold);
/* player image */
ImageView characterImageView = controller.getCharacterImageView();
characterImageView.setFitHeight(150);
characterImageView.setPreserveRatio(true);
playerDataAndImage.getChildren().add(playerData);
playerDataAndImage.getChildren().add(characterImageView);
playerInfoBox.getChildren().add(playerDataAndImage);
return playerInfoBox;
}
......@@ -240,10 +283,7 @@ public class PlaythroughView extends View<VBox> {
* @return The parent node of the goal information box.
*/
private Node goalInfo(Pane parentPane) {
VBox goalInfoBox = new VBox();
goalInfoBox.setAlignment(Pos.TOP_CENTER);
goalInfoBox.prefHeightProperty().bind(parentPane.heightProperty().multiply(0.3));
goalInfoBox.setBackground(new Background(new BackgroundFill(Color.LIGHTBLUE, new CornerRadii(30), null)));
Pane goalInfoBox = initInfoCard(parentPane);
/* title */
goalInfoBox.getChildren().add(DefaultText.medium("Goals:"));
......@@ -254,6 +294,7 @@ public class PlaythroughView extends View<VBox> {
VBox content = new VBox();
content.setAlignment(Pos.TOP_LEFT);
content.setSpacing(20);
content.setPadding(new Insets(0, 0, 0, 20));
ObservableMap<Goal, Boolean> goals = controller.getGoals();
goals.addListener(
......@@ -274,10 +315,7 @@ public class PlaythroughView extends View<VBox> {
* @return The parent node of the inventory information box.
*/
private Node inventoryInfo(Pane parentPane) {
VBox inventoryInfoBox = new VBox();
inventoryInfoBox.setAlignment(Pos.TOP_CENTER);
inventoryInfoBox.prefHeightProperty().bind(parentPane.heightProperty().multiply(0.3));
inventoryInfoBox.setBackground(new Background(new BackgroundFill(Color.LIGHTBLUE, new CornerRadii(30), null)));
Pane inventoryInfoBox = initInfoCard(parentPane);
/* title */
inventoryInfoBox.getChildren().add(DefaultText.medium("Inventory:"));
......@@ -302,6 +340,15 @@ public class PlaythroughView extends View<VBox> {
return inventoryInfoBox;
}
private Pane initInfoCard(Pane parentPane) {
VBox box = new VBox();
box.getStyleClass().add("box-shadow");
box.setAlignment(Pos.TOP_CENTER);
box.prefHeightProperty().bind(parentPane.heightProperty().multiply(0.3));
box.setBackground(new Background(new BackgroundFill(Color.LIGHTBLUE, new CornerRadii(30), null)));
return box;
}
private void showInventory(ObservableList<String> inventory, Pane content) {
content.getChildren().clear();
for (String item : inventory) {
......@@ -322,7 +369,17 @@ public class PlaythroughView extends View<VBox> {
goalBox.setAlignment(Pos.TOP_LEFT);
goalBox.setSpacing(10);
goalBox.getChildren().add(DefaultText.small(goal.toString()));
goalBox.getChildren().add(DefaultText.small(completed ? "Completed" : "Not completed"));
//goalBox.getChildren().add(DefaultText.small(completed ? "Completed" : "Not completed"));
URL imageUrl = getClass().getResource("/images/checkbox-" + (completed ? "marked" : "blank") + ".png");
if (imageUrl != null) {
ImageView imageView = new ImageView(imageUrl.toString());
imageView.setFitWidth(20);
imageView.setPreserveRatio(true);
goalBox.getChildren().add(imageView);
} else {
System.err.println("Unable to load image: " + imageUrl);
}
content.getChildren().add(goalBox);
});
}
......
package edu.ntnu.idatt2001.group_30.paths.view;
package edu.ntnu.idatt2001.group_30.paths.view.views;
import edu.ntnu.idatt2001.group_30.paths.view.components.common.DefaultText;
import java.lang.reflect.InvocationTargetException;
......@@ -7,6 +7,7 @@ import java.util.Objects;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.layout.*;
import javafx.scene.shape.SVGPath;
/**
* A View is a wrapper for a JavaFX Pane.
......@@ -35,6 +36,7 @@ public class View<T extends Pane> {
public View(Class<T> paneClass) {
try {
parentPane = paneClass.getDeclaredConstructor().newInstance();
parentPane.getStylesheets().add(getClass().getResource("/stylesheet.css").toExternalForm());
} catch (
InstantiationException | IllegalAccessException | NoSuchMethodException | InvocationTargetException e
) {
......@@ -78,6 +80,7 @@ public class View<T extends Pane> {
// The reason for using a BorderPane is that it is easy to add content to the top, bottom, left and right.
// A view is free to override this method and use a different Pane.
BorderPane wrapper = new BorderPane();
wrapper.setCenter(parentPane);
wrapper.setBottom(globalFooter());
wrapper.getStylesheets().add(stylesheet);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment