From 1cff5fdbe85d9f269519947b4241aeb1f5febeaf Mon Sep 17 00:00:00 2001 From: Max Date: Mon, 22 Apr 2024 14:31:43 +0200 Subject: [PATCH] WIP BoardUI implementation --- src/ch/epfl/chacun/gui/BoardUI.java | 37 +++++++++++++++++------------ src/ch/epfl/chacun/gui/DecksUI.java | 9 ++----- 2 files changed, 24 insertions(+), 22 deletions(-) diff --git a/src/ch/epfl/chacun/gui/BoardUI.java b/src/ch/epfl/chacun/gui/BoardUI.java index 376b380..d8aa387 100644 --- a/src/ch/epfl/chacun/gui/BoardUI.java +++ b/src/ch/epfl/chacun/gui/BoardUI.java @@ -7,12 +7,15 @@ import javafx.scene.control.ScrollPane; import javafx.scene.image.Image; import javafx.scene.image.ImageView; +import javafx.scene.image.WritableImage; import javafx.scene.layout.GridPane; +import javafx.scene.paint.Color; +import java.util.HashMap; +import java.util.Map; import java.util.Set; import java.util.function.Consumer; -import static ch.epfl.chacun.gui.ImageLoader.LARGE_TILE_FIT_SIZE; import static ch.epfl.chacun.gui.ImageLoader.NORMAL_TILE_FIT_SIZE; /** @@ -23,16 +26,15 @@ */ public final class BoardUI { + private static final double EMPTY_TILE_GRAY_SCALE = 0.98; + /** * Non-instantiable class constructor. */ private BoardUI() { } - public static Node create(int reach, ObservableValue gameStateO, ObservableValue rotationO, - ObservableValue> occupantsO, ObservableValue> tileIdsO, - Consumer rotationToApply, Consumer tileToPlacePos, - Consumer selectedOccupant) { + public static Node create(int reach, ObservableValue gameStateO, ObservableValue rotationO, ObservableValue> occupantsO, ObservableValue> tileIdsO, Consumer rotationToApply, Consumer tileToPlacePos, Consumer selectedOccupant) { Preconditions.checkArgument(reach > 0); @@ -43,24 +45,29 @@ public static Node create(int reach, ObservableValue gameStateO, Obse GridPane gridPane = new GridPane(); gridPane.setId("board-grid"); - ObservableValue boardO = gameStateO.map(GameState::board); + WritableImage emptyTileImage = new WritableImage(1, 1); + emptyTileImage.getPixelWriter().setColor(0, 0, Color.gray(EMPTY_TILE_GRAY_SCALE)); + + Map tileImagesCache = new HashMap<>(); for (int x = -reach; x <= reach; ++x) { for (int y = -reach; y <= reach; ++y) { ImageView view = new ImageView(); view.setFitHeight(NORMAL_TILE_FIT_SIZE); view.setFitWidth(NORMAL_TILE_FIT_SIZE); - // Display the image of the tile to place - int finalX = x; - int finalY = y; - boardO.addListener((_, _, board) -> { - PlacedTile placedTile = board.tileAt(new Pos(finalX, finalY)); - if (placedTile != null) { - Image newImage = ImageLoader.largeImageForTile(placedTile.id()); - view.setImage(newImage); - } + + Pos tilePos = new Pos(x, y); + ObservableValue placedTileO = gameStateO + .map(gameState -> gameState.board().tileAt(tilePos)); + + // Reactive image data + ObservableValue tileImageO = placedTileO.map(placedTile -> { + if (placedTile != null) + return tileImagesCache.computeIfAbsent(placedTile.id(), ImageLoader::normalImageForTile); + return emptyTileImage; }); + view.imageProperty().bind(tileImageO); gridPane.getChildren().add(new Group(view)); } } diff --git a/src/ch/epfl/chacun/gui/DecksUI.java b/src/ch/epfl/chacun/gui/DecksUI.java index c7491ad..b040c34 100644 --- a/src/ch/epfl/chacun/gui/DecksUI.java +++ b/src/ch/epfl/chacun/gui/DecksUI.java @@ -106,13 +106,8 @@ private static StackPane createNextTileCover(ObservableValue tileToPlaceO, view.setFitWidth(LARGE_TILE_FIT_SIZE); view.visibleProperty().bind(textToDisplayO.map(String::isEmpty)); // Display the image of the tile to place - Image image = ImageLoader.largeImageForTile(tileToPlaceO.getValue().id()); - view.setImage(image); - tileToPlaceO.addListener((_, _, newTile) -> { - Image newImage = ImageLoader.largeImageForTile(newTile.id()); - view.setImage(newImage); - }); - + ObservableValue nextTileImage = tileToPlaceO.map(tile -> ImageLoader.largeImageForTile(tile.id())); + view.imageProperty().bind(nextTileImage); // Display the text of the special action and register a mouse click event to skip it Text text = new Text(); text.textProperty().bind(textToDisplayO);