From e7563be943667b6aad5813090989b9e28424b052 Mon Sep 17 00:00:00 2001 From: mithe24 Date: Wed, 14 May 2025 12:30:20 +0200 Subject: feat/view-manager (#20) * feat(View & Controller): Added screens for game, main menu and pause menu Added screens: - MainMenuView & MainMenuController. - GameView & GameController. - PauseView & PauseController. * refactor(MainMenuController): MainMenuController constructs game MainMenuController constructs games and allows the creation of a new game without terminating the process: * feat(View): Resource Manager for loading game textures Add ResourceManager for centralized texture loading. Implemented a singleton ResourceManager to handle loading of game textures. Ensures each texture is loaded only once, improving performance and memory efficiency. Includes fallback logic to return a default "missing texture" image when a resource cannot be found. Prevents accidental instantiation by enforcing the singleton pattern. --- .../java/com/gr15/pacman/controller/GameApp.java | 33 +++--- .../com/gr15/pacman/controller/GameController.java | 63 ------------ .../pacman/controller/screen/GameController.java | 72 +++++++++++++ .../controller/screen/MainMenuController.java | 47 +++++++++ .../pacman/controller/screen/PauseController.java | 34 +++++++ pacman/controller/src/main/java/module-info.java | 2 + .../main/java/com/gr15/pacman/view/GameView.java | 113 --------------------- .../java/com/gr15/pacman/view/ResourceManager.java | 77 ++++++++++++++ .../java/com/gr15/pacman/view/ViewManager.java | 92 +++++++++++++++++ .../java/com/gr15/pacman/view/screen/GameView.java | 113 +++++++++++++++++++++ .../com/gr15/pacman/view/screen/MainMenuView.java | 27 +++++ .../com/gr15/pacman/view/screen/PauseView.java | 25 +++++ pacman/view/src/main/java/module-info.java | 2 + .../main/resources/gameAssets/missingTexture.png | Bin 0 -> 216 bytes 14 files changed, 507 insertions(+), 193 deletions(-) delete mode 100644 pacman/controller/src/main/java/com/gr15/pacman/controller/GameController.java create mode 100644 pacman/controller/src/main/java/com/gr15/pacman/controller/screen/GameController.java create mode 100644 pacman/controller/src/main/java/com/gr15/pacman/controller/screen/MainMenuController.java create mode 100644 pacman/controller/src/main/java/com/gr15/pacman/controller/screen/PauseController.java delete mode 100644 pacman/view/src/main/java/com/gr15/pacman/view/GameView.java create mode 100644 pacman/view/src/main/java/com/gr15/pacman/view/ResourceManager.java create mode 100644 pacman/view/src/main/java/com/gr15/pacman/view/ViewManager.java create mode 100644 pacman/view/src/main/java/com/gr15/pacman/view/screen/GameView.java create mode 100644 pacman/view/src/main/java/com/gr15/pacman/view/screen/MainMenuView.java create mode 100644 pacman/view/src/main/java/com/gr15/pacman/view/screen/PauseView.java create mode 100644 pacman/view/src/main/resources/gameAssets/missingTexture.png diff --git a/pacman/controller/src/main/java/com/gr15/pacman/controller/GameApp.java b/pacman/controller/src/main/java/com/gr15/pacman/controller/GameApp.java index ffd4493..98a8c5e 100644 --- a/pacman/controller/src/main/java/com/gr15/pacman/controller/GameApp.java +++ b/pacman/controller/src/main/java/com/gr15/pacman/controller/GameApp.java @@ -1,12 +1,18 @@ package com.gr15.pacman.controller; -import java.io.InputStream; - import com.gr15.pacman.model.GameState; import com.gr15.pacman.model.GameStateBuilder; -import com.gr15.pacman.view.GameView; +import com.gr15.pacman.view.ViewManager; +import com.gr15.pacman.view.screen.GameView; +import com.gr15.pacman.view.screen.MainMenuView; +import com.gr15.pacman.view.screen.PauseView; +import com.gr15.pacman.view.ViewManager.ViewKeys; +import com.gr15.pacman.controller.screen.GameController; +import com.gr15.pacman.controller.screen.MainMenuController; +import com.gr15.pacman.controller.screen.PauseController; import javafx.application.Application; +import javafx.scene.Scene; import javafx.stage.Stage; /** @@ -15,9 +21,8 @@ import javafx.stage.Stage; public class GameApp extends Application { - GameController gameController; - GameView gameView; - GameState gameState; + private ViewManager viewManager = new ViewManager(); + private MainMenuView mainMenuView = new MainMenuView(); @Override public void start(Stage primaryStage) throws Exception { @@ -25,18 +30,12 @@ public class GameApp primaryStage.setResizable(false); primaryStage.setFullScreen(true); - InputStream inputStream = this.getClass() - .getResourceAsStream("/testGameState.json"); - GameState gameState = GameStateBuilder.fromJson(inputStream); - inputStream.close(); - int tileWidth = gameState.getBoard().getWidth(); - int tileHeight = gameState.getBoard().getHeight(); - gameView = new GameView(gameState,tileWidth, tileHeight); - primaryStage.setScene(gameView); - - gameController = new GameController(gameState, gameView); - gameController.startGameLoop(); + viewManager.addView(ViewKeys.MAIN_MENU, mainMenuView); + viewManager.showView(ViewKeys.MAIN_MENU); + new MainMenuController(viewManager, mainMenuView); + Scene scene = new Scene(viewManager, 1920, 1080); + primaryStage.setScene(scene); primaryStage.show(); } diff --git a/pacman/controller/src/main/java/com/gr15/pacman/controller/GameController.java b/pacman/controller/src/main/java/com/gr15/pacman/controller/GameController.java deleted file mode 100644 index a334576..0000000 --- a/pacman/controller/src/main/java/com/gr15/pacman/controller/GameController.java +++ /dev/null @@ -1,63 +0,0 @@ -package com.gr15.pacman.controller; - -import com.gr15.pacman.model.GameState; -import com.gr15.pacman.model.entities.Entity.Direction; -import com.gr15.pacman.view.GameView; - -import javafx.animation.AnimationTimer; - -/** - * GameController - */ -public class GameController { - - private GameState gameState; - private GameView gameView; - - private AnimationTimer gameLoop; - private long lastUpdate = 0; - - public GameController(GameState gameState, GameView gameView) { - this.gameState = gameState; - this.gameView = gameView; - - setupEventHandlers(); - gameLoop = new AnimationTimer() { - - @Override - public void handle(long now) { - if (lastUpdate == 0) { - lastUpdate = now; - return; /* returning early, since no time have elapsed */ - } - - double deltaSeconds = (now - lastUpdate) / 1_000_000_000.0; - lastUpdate = now; - - gameState.update(deltaSeconds); - gameView.renderGame(deltaSeconds); - } - }; - } - - private void setupEventHandlers() { - gameView.setOnKeyPressed(event -> { - switch (event.getCode()) { - case UP -> gameState.getPacman().setDirection(Direction.UP); - case DOWN -> gameState.getPacman().setDirection(Direction.DOWN); - case LEFT -> gameState.getPacman().setDirection(Direction.LEFT); - case RIGHT -> gameState.getPacman().setDirection(Direction.RIGHT); - default -> {} - } - }); - } - - public void startGameLoop() { - gameLoop.start(); - } - - public void stopGameLoop() { - lastUpdate = 0; - gameLoop.stop(); - } -} diff --git a/pacman/controller/src/main/java/com/gr15/pacman/controller/screen/GameController.java b/pacman/controller/src/main/java/com/gr15/pacman/controller/screen/GameController.java new file mode 100644 index 0000000..0bb4e87 --- /dev/null +++ b/pacman/controller/src/main/java/com/gr15/pacman/controller/screen/GameController.java @@ -0,0 +1,72 @@ +package com.gr15.pacman.controller.screen; + +import com.gr15.pacman.model.GameState; +import com.gr15.pacman.model.entities.Entity.Direction; +import com.gr15.pacman.view.ViewManager; +import com.gr15.pacman.view.screen.GameView; +import com.gr15.pacman.view.ViewManager.ViewKeys; + +import javafx.animation.AnimationTimer; +import javafx.scene.input.KeyEvent; + +/** + * GameController + */ +public class GameController { + + private final ViewManager viewManager; + private final GameState gameState; + private final GameView gameView; + + private final AnimationTimer gameLoop; + private long lastUpdate = 0; + + public GameController(GameState gameState, GameView gameView, ViewManager viewManager) { + this.viewManager = viewManager; + this.gameState = gameState; + this.gameView = gameView; + + gameLoop = new AnimationTimer() { + + @Override + public void handle(long now) { + if (lastUpdate == 0) { + lastUpdate = now; + return; /* returning early, since no time have elapsed */ + } + + double deltaSeconds = (now - lastUpdate) / 1_000_000_000.0; + lastUpdate = now; + + gameState.update(deltaSeconds); + gameView.renderGame(deltaSeconds); + } + }; + } + + public void handleKeyEvent(KeyEvent event) { + switch (event.getCode()) { + case UP -> gameState.getPacman().setDirection(Direction.UP); + case DOWN -> gameState.getPacman().setDirection(Direction.DOWN); + case LEFT -> gameState.getPacman().setDirection(Direction.LEFT); + case RIGHT -> gameState.getPacman().setDirection(Direction.RIGHT); + case ESCAPE -> { + viewManager.showView(ViewKeys.PAUSE); + stopGameLoop(); + } + default -> {} + } + } + + public void startGameLoop() { + gameView.requestFocusForInput(); + gameView.setOnKeyPressed(event -> handleKeyEvent(event)); + + gameLoop.start(); + } + + public void stopGameLoop() { + lastUpdate = 0; + gameLoop.stop(); + } +} diff --git a/pacman/controller/src/main/java/com/gr15/pacman/controller/screen/MainMenuController.java b/pacman/controller/src/main/java/com/gr15/pacman/controller/screen/MainMenuController.java new file mode 100644 index 0000000..9477171 --- /dev/null +++ b/pacman/controller/src/main/java/com/gr15/pacman/controller/screen/MainMenuController.java @@ -0,0 +1,47 @@ +package com.gr15.pacman.controller.screen; + +import com.gr15.pacman.model.GameState; +import com.gr15.pacman.model.GameStateBuilder; +import com.gr15.pacman.view.ViewManager; +import com.gr15.pacman.view.screen.GameView; +import com.gr15.pacman.view.screen.MainMenuView; +import com.gr15.pacman.view.screen.PauseView; +import com.gr15.pacman.view.ViewManager.ViewKeys; + +/** + * MainMenuController + */ +public class MainMenuController { + + private final ViewManager viewManager; + private final MainMenuView mainMenuView; + + public MainMenuController(ViewManager viewManager, MainMenuView mainMenuView) { + this.viewManager = viewManager; + this.mainMenuView = mainMenuView; + initializeButtons(); + } + + private void initializeButtons() { + mainMenuView.getStartButton().setOnAction((event) -> { + GameState gameState = GameStateBuilder.fromJson( + this.getClass().getResourceAsStream("/testGameState.json")); + int tileWidth = gameState.getBoard().getWidth(); + int tileHeight = gameState.getBoard().getHeight(); + GameView gameView = new GameView(gameState, tileWidth, tileHeight); + PauseView pauseView = new PauseView(); + GameController gameController = new GameController(gameState, + gameView, viewManager); + new PauseController(pauseView, gameController, viewManager); + viewManager.removeView(ViewKeys.GAME_VIEW); + viewManager.removeView(ViewKeys.PAUSE); + viewManager.addView(ViewKeys.GAME_VIEW, gameView); + viewManager.addView(ViewKeys.PAUSE, pauseView); + viewManager.showView(ViewKeys.GAME_VIEW); + gameController.startGameLoop(); + }); + mainMenuView.getQuitButton().setOnAction((event) -> { + System.exit(0); + }); + } +} diff --git a/pacman/controller/src/main/java/com/gr15/pacman/controller/screen/PauseController.java b/pacman/controller/src/main/java/com/gr15/pacman/controller/screen/PauseController.java new file mode 100644 index 0000000..88b60ea --- /dev/null +++ b/pacman/controller/src/main/java/com/gr15/pacman/controller/screen/PauseController.java @@ -0,0 +1,34 @@ +package com.gr15.pacman.controller.screen; + +import com.gr15.pacman.view.ViewManager; +import com.gr15.pacman.view.ViewManager.ViewKeys; +import com.gr15.pacman.view.screen.PauseView; + +/** + * PauseController + */ +public class PauseController { + + private final PauseView pauseView; + private final GameController gameController; + private final ViewManager viewManager; + + public PauseController(PauseView pauseView, GameController gameController, + ViewManager viewManager) { + this.gameController = gameController; + this.pauseView = pauseView; + this.viewManager = viewManager; + initialize(); + } + + private void initialize() { + pauseView.getQuitButton().setOnAction((e) -> { System.exit(0); }); + pauseView.getMainMenuButton().setOnAction((e) -> { + viewManager.showView(ViewKeys.MAIN_MENU); + }); + pauseView.getResumeButton().setOnAction((e) -> { + viewManager.showView(ViewKeys.GAME_VIEW); + gameController.startGameLoop(); + }); + } +} diff --git a/pacman/controller/src/main/java/module-info.java b/pacman/controller/src/main/java/module-info.java index 9df9dd5..c240f2c 100644 --- a/pacman/controller/src/main/java/module-info.java +++ b/pacman/controller/src/main/java/module-info.java @@ -6,5 +6,7 @@ module com.gr15.pacman.controller { requires javafx.graphics; requires com.gr15.pacman.view; requires com.gr15.pacman.model; + exports com.gr15.pacman.controller; + exports com.gr15.pacman.controller.screen; } diff --git a/pacman/view/src/main/java/com/gr15/pacman/view/GameView.java b/pacman/view/src/main/java/com/gr15/pacman/view/GameView.java deleted file mode 100644 index d9235f6..0000000 --- a/pacman/view/src/main/java/com/gr15/pacman/view/GameView.java +++ /dev/null @@ -1,113 +0,0 @@ -package com.gr15.pacman.view; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import com.gr15.pacman.model.GameState; -import com.gr15.pacman.model.Board.TileType; - -import javafx.scene.Scene; -import javafx.scene.canvas.Canvas; -import javafx.scene.canvas.GraphicsContext; -import javafx.scene.image.Image; -import javafx.scene.layout.StackPane; -import javafx.scene.paint.Color; - -import com.gr15.pacman.model.entities.Entity; -import com.gr15.pacman.model.entities.Items; - -/** - * GameView - */ -public class GameView - extends Scene { - - /* Utils */ - private Canvas canvas; - private GraphicsContext gc; - private GameState gameState; - private StackPane root; - - private float scaleX = 4.0f; - private float scaleY = 4.0f; - private int tileWidth; - private int tileHeight; - - private Map tileTextures = new HashMap<>(); - private Map entityTextures = new HashMap<>(); - private Map itemTextures = new HashMap<>(); - - /* UI elements */ - private Sprite pacmanSprite; - - public GameView(GameState gameState, - int tileWidth, int tileHeight) { - super(new StackPane()); - root = (StackPane)super.getRoot(); - - canvas = new Canvas(tileWidth * 16 * scaleX, tileHeight * 16 * scaleY); - gc = canvas.getGraphicsContext2D(); - root.getChildren().add(canvas); - - this.tileHeight = tileHeight; - this.tileWidth = tileWidth; - this.gameState = gameState; - this.setFill(Color.BLACK); - - tileTextures.put(TileType.WALL, new Image( - this.getClass().getResourceAsStream("/gameAssets/wall.png"))); - pacmanSprite = new Sprite(new Image( - this.getClass().getResourceAsStream("/gameAssets/pacmanRight.png")), - gameState.getPacman().getPositionX() - 0.5, - gameState.getPacman().getPositionY() - 0.5, - 16 * scaleX, 16 * scaleY); - } - - public void renderGame(double deltaSeconds) { - gc.clearRect(0, 0, tileWidth * 16 * scaleX, tileHeight * 16 * scaleY); - TileType[][] tileBoard = gameState.getBoard().getTileBoard(); - for (int y = 0; y < tileBoard.length; y++) { - for (int x = 0; x < tileBoard[y].length; x++) { - Image texture = tileTextures.get(tileBoard[y][x]); - if (texture != null) { - gc.drawImage(texture, - x * 16 * scaleX, - y * 16 * scaleY, - texture.getWidth() * scaleX, - texture.getHeight() * scaleY); - } - } - } - - pacmanSprite.setX((gameState.getPacman().getPositionX() - - 0.5) * 16 * scaleX); - pacmanSprite.setY((gameState.getPacman().getPositionY() - - 0.5) * 16 * scaleY); - pacmanSprite.render(gc); - - List entities = gameState.getEntities(); - for (Entity entity : entities) { - Image texture = entityTextures.get(entity); - if (texture != null) { - gc.drawImage(texture, - entity.getPositionX() * 16 * scaleX, - entity.getPositionY() * 16 * scaleY, - texture.getWidth() * scaleX, - texture.getHeight() * scaleY); - } - } - - gameState.getItems().forEach((pos, item) -> { - Image texture = itemTextures.get(item); - if (texture != null) { - gc.drawImage(texture, - pos.x() * 16 * scaleX, - pos.y() * 16 * scaleY, - texture.getWidth() * scaleX, - texture.getHeight() * scaleY); - - } - }); - } -} diff --git a/pacman/view/src/main/java/com/gr15/pacman/view/ResourceManager.java b/pacman/view/src/main/java/com/gr15/pacman/view/ResourceManager.java new file mode 100644 index 0000000..3e7103e --- /dev/null +++ b/pacman/view/src/main/java/com/gr15/pacman/view/ResourceManager.java @@ -0,0 +1,77 @@ +package com.gr15.pacman.view; + +import java.util.HashMap; +import java.util.Map; + +import javafx.scene.image.Image; + +/** + * The {@code ResourceManager} class is a singleton responsible + * for managing {@link Image} resources used in the application. + * It provides caching to avoid loading the same {@link Image} multiple times, + * improving performance and resource efficiency. + * + * If an {@link Image} cannot be found at the specified path, + * a default "missing texture" {@link Image} is returned. + */ + +public class ResourceManager { + + /** Singleton instance of ResourceManager. */ + private static ResourceManager instance; + + /** Cache to store loaded images keyed by their file path. */ + private Map resources = new HashMap<>(); + + /** Image to be used when the requested image is not found. */ + private Image missingTexture = new Image( + this.getClass().getResourceAsStream("/gameAssets/missingTexture.png")); + + /** + * Private constructor to prevent external instantiation + * and enforce singleton pattern. + */ + private ResourceManager() {} + + /** + * Returns the singleton instance of {@code ResourceManager}. + * If it does not exist yet, it is created. + * + * @return the singleton instance of {@code ResourceManager}. + */ + public static ResourceManager getInstance() { + if (instance == null) { + instance = new ResourceManager(); + return instance; + } else { + return instance; + } + } + + /** + * Returns an {@link Image} corresponding to the specified resource path. + * If the {@link Image} has already been loaded before, + * it is returned from the cache. Otherwise, it is loaded + * and added to the cache. + * If loading fails (e.g., if the file does not exist), + * the default "missing texture" {@link Image} is returned. + * + * @param path the path to the image resource, relative to the classpath + * @return the loaded {@link Image}, + * or a default image if the resource could not be found + */ + public Image getTexture(String path) { + if (resources.containsKey(path)) { + return resources.get(path); + } else { + try { + Image texture = new Image( + this.getClass().getResourceAsStream(path)); + resources.put(path, texture); + return texture; + } catch (NullPointerException e) { + return missingTexture; + } + } + } +} diff --git a/pacman/view/src/main/java/com/gr15/pacman/view/ViewManager.java b/pacman/view/src/main/java/com/gr15/pacman/view/ViewManager.java new file mode 100644 index 0000000..2f1eb3a --- /dev/null +++ b/pacman/view/src/main/java/com/gr15/pacman/view/ViewManager.java @@ -0,0 +1,92 @@ +package com.gr15.pacman.view; + +import java.util.HashMap; +import java.util.Map; + +import javafx.geometry.Insets; +import javafx.scene.Parent; +import javafx.scene.layout.Background; +import javafx.scene.layout.BackgroundFill; +import javafx.scene.layout.CornerRadii; +import javafx.scene.layout.StackPane; +import javafx.scene.paint.Color; + +/** + * The {@code ViewManager} class is responsible for managing and switching between + * different views in a JavaFX application. It extends {@code StackPane} and provides + * methods to add, remove, check for, and display views identified by an enum key. + */ +public class ViewManager + extends StackPane { + + /** + * Enumeration of all possible view keys used to identify different views. + */ + public enum ViewKeys { MAIN_MENU, GAME_VIEW, PAUSE }; + + /** + * A map that stores views associated with their corresponding keys. + */ + private Map views = new HashMap<>(); + + /** + * Constructs a new {@code ViewManager} with a black background. + */ + public ViewManager() { + setBackground(new Background(new BackgroundFill( + Color.BLACK, + CornerRadii.EMPTY, + Insets.EMPTY + ))); + } + + /** + * Adds a new view to the manager. + * + * @param key the key to identify the view. + * @param view the view to be added. + * @throws IllegalArgumentException if a view with the same key already exists. + */ + public void addView(ViewKeys key, Parent view) { + if (views.containsKey(key)) { + throw new IllegalArgumentException( + "View with key " + key + " already exists."); + } else { + views.put(key, view); + } + } + + /** + * Displays the view associated with the specified key. + * + * @param key the key of the view to be shown. + * @throws IllegalArgumentException if no view exists for the specified key. + */ + public void showView(ViewKeys key) { + if (!views.containsKey(key)) { + throw new IllegalArgumentException( + "No view with key " + key + " exists."); + } else { + getChildren().setAll(views.get(key)); + } + } + + /** + * Checks whether a view exists for the specified key. + * + * @param key the key to check. + * @return {@code true} if a view with the key exists, {@code false} otherwise. + */ + public boolean hasView(ViewKeys key) { + return views.containsKey(key); + } + + /** + * Removes the view associated with the specified key. + * + * @param key the key of the view to remove. + */ + public void removeView(ViewKeys key) { + views.remove(key); + } +} diff --git a/pacman/view/src/main/java/com/gr15/pacman/view/screen/GameView.java b/pacman/view/src/main/java/com/gr15/pacman/view/screen/GameView.java new file mode 100644 index 0000000..33c4e2d --- /dev/null +++ b/pacman/view/src/main/java/com/gr15/pacman/view/screen/GameView.java @@ -0,0 +1,113 @@ +package com.gr15.pacman.view.screen; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import com.gr15.pacman.view.ResourceManager; +import com.gr15.pacman.view.Sprite; + +import com.gr15.pacman.model.GameState; +import com.gr15.pacman.model.Board.TileType; + +import javafx.geometry.Pos; +import javafx.scene.canvas.Canvas; +import javafx.scene.canvas.GraphicsContext; +import javafx.scene.image.Image; +import javafx.scene.layout.VBox; + +import com.gr15.pacman.model.entities.Entity; +import com.gr15.pacman.model.entities.Items; + +/** + * GameView + */ +public class GameView + extends VBox { + + /* Utils */ + private Canvas canvas; + private GraphicsContext gc; + private GameState gameState; + + private float scaleX = 3.0f; + private float scaleY = 3.0f; + private int tileWidth; + private int tileHeight; + + private Map tileTextures = new HashMap<>(); + private Map entityTextures = new HashMap<>(); + private Map itemTextures = new HashMap<>(); + + /* UI elements */ + private Sprite pacmanSprite; + + public GameView(GameState gameState, int tileWidth, int tileHeight) { + canvas = new Canvas(tileWidth * 16 * scaleX, tileHeight * 16 * scaleY); + gc = canvas.getGraphicsContext2D(); + getChildren().add(canvas); + setAlignment(Pos.CENTER); + + this.tileHeight = tileHeight; + this.tileWidth = tileWidth; + this.gameState = gameState; + + tileTextures.put(TileType.WALL, ResourceManager.getInstance() + .getTexture("/gameAssets/wall.png")); + pacmanSprite = new Sprite( + ResourceManager.getInstance().getTexture("/gameAssets/pacmanRight.png"), + gameState.getPacman().getPositionX() - 0.5, + gameState.getPacman().getPositionY() - 0.5, + 16 * scaleX, 16 * scaleY); + } + + public void renderGame(double deltaSeconds) { + gc.clearRect(0, 0, tileWidth * 16 * scaleX, tileHeight * 16 * scaleY); + TileType[][] tileBoard = gameState.getBoard().getTileBoard(); + for (int y = 0; y < tileBoard.length; y++) { + for (int x = 0; x < tileBoard[y].length; x++) { + Image texture = tileTextures.get(tileBoard[y][x]); + if (texture != null) { + gc.drawImage(texture, + x * 16 * scaleX, + y * 16 * scaleY, + texture.getWidth() * scaleX, + texture.getHeight() * scaleY); + } + } + } + + pacmanSprite.setX((gameState.getPacman().getPositionX() + - 0.5) * 16 * scaleX); + pacmanSprite.setY((gameState.getPacman().getPositionY() + - 0.5) * 16 * scaleY); + pacmanSprite.render(gc); + + List entities = gameState.getEntities(); + for (Entity entity : entities) { + Image texture = entityTextures.get(entity); + if (texture != null) { + gc.drawImage(texture, + entity.getPositionX() * 16 * scaleX, + entity.getPositionY() * 16 * scaleY, + texture.getWidth() * scaleX, + texture.getHeight() * scaleY); + } + } + + gameState.getItems().forEach((pos, item) -> { + Image texture = itemTextures.get(item); + if (texture != null) { + gc.drawImage(texture, + pos.x() * 16 * scaleX, + pos.y() * 16 * scaleY, + texture.getWidth() * scaleX, + texture.getHeight() * scaleY); + } + }); + } + + public void requestFocusForInput() { + requestFocus(); + } +} diff --git a/pacman/view/src/main/java/com/gr15/pacman/view/screen/MainMenuView.java b/pacman/view/src/main/java/com/gr15/pacman/view/screen/MainMenuView.java new file mode 100644 index 0000000..c849fb9 --- /dev/null +++ b/pacman/view/src/main/java/com/gr15/pacman/view/screen/MainMenuView.java @@ -0,0 +1,27 @@ +package com.gr15.pacman.view.screen; + +import javafx.geometry.Pos; +import javafx.scene.control.Button; +import javafx.scene.control.Menu; +import javafx.scene.layout.VBox; + +/** + * MainMenuView + */ +public class MainMenuView + extends VBox { + + private Button newGameButton = new Button("New Game"); + private Button resumeButton = new Button("Resume"); + private Button quitButton = new Button("Exit Game"); + + public MainMenuView() { + resumeButton.setDisable(true); + getChildren().addAll(resumeButton, newGameButton, quitButton); + setAlignment(Pos.CENTER); + } + + public Button getNewGameButton() { return this.newGameButton; } + public Button getResumeButton() { return this.resumeButton; } + public Button getQuitButton() { return this.quitButton; } +} diff --git a/pacman/view/src/main/java/com/gr15/pacman/view/screen/PauseView.java b/pacman/view/src/main/java/com/gr15/pacman/view/screen/PauseView.java new file mode 100644 index 0000000..7dd46e2 --- /dev/null +++ b/pacman/view/src/main/java/com/gr15/pacman/view/screen/PauseView.java @@ -0,0 +1,25 @@ +package com.gr15.pacman.view.screen; + +import javafx.geometry.Pos; +import javafx.scene.control.Button; +import javafx.scene.layout.VBox; + +/** + * PauseView + */ +public class PauseView + extends VBox { + + private Button resumeButton = new Button("Resume"); + private Button mainMenuButton = new Button("Main Menu"); + private Button quitButton = new Button("Quit"); + + public PauseView() { + getChildren().addAll(resumeButton, mainMenuButton, quitButton); + setAlignment(Pos.CENTER); + } + + public Button getResumeButton() { return this.resumeButton; } + public Button getMainMenuButton() { return this.mainMenuButton; } + public Button getQuitButton() { return this.quitButton; } +} diff --git a/pacman/view/src/main/java/module-info.java b/pacman/view/src/main/java/module-info.java index f50cafa..f91361e 100644 --- a/pacman/view/src/main/java/module-info.java +++ b/pacman/view/src/main/java/module-info.java @@ -5,5 +5,7 @@ module com.gr15.pacman.view { requires javafx.controls; requires javafx.graphics; requires com.gr15.pacman.model; + + exports com.gr15.pacman.view.screen; exports com.gr15.pacman.view; } diff --git a/pacman/view/src/main/resources/gameAssets/missingTexture.png b/pacman/view/src/main/resources/gameAssets/missingTexture.png new file mode 100644 index 0000000..7317870 Binary files /dev/null and b/pacman/view/src/main/resources/gameAssets/missingTexture.png differ -- cgit v1.2.3-70-g09d2