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 + 6 files changed, 171 insertions(+), 80 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 (limited to 'pacman/controller/src/main') 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; } -- cgit v1.2.3-70-g09d2