diff options
| author | mithe24 <mithe24@student.sdu.dk> | 2025-05-20 18:26:53 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-05-20 18:26:53 +0200 |
| commit | 8c8a4023c98e076ae6c635b36734dbe28782ed69 (patch) | |
| tree | d85fddfd3ec5db1a2d138573399733922e0209e1 /pacman/controller/src/main/java/com | |
| parent | bf53777577aea4615559b56b319bfc8b24ed3fa0 (diff) | |
| download | pacman-8c8a4023c98e076ae6c635b36734dbe28782ed69.tar.gz pacman-8c8a4023c98e076ae6c635b36734dbe28782ed69.zip | |
view module overhaul (#26)
* chore(game assets): Removed unneeded pacman assets
Removed unneeded pacman assets, as a single asset just can be rotated.
* chore(): Updating to newest javafx version
Updated javafx to newest version.
Addded transitivity to modules.
* chore(GameController): Removes duplicate class GameController
* feat(camara): Adds camara abstraction and overhauls view
* fix(sprite): Removed exception from setRotation
No exception should be thrown if setting rotation in the Sprite class to
a number below 0 or above 360
Diffstat (limited to '')
5 files changed, 255 insertions, 110 deletions
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 98a8c5e..9c07798 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,44 +1,65 @@ package com.gr15.pacman.controller; -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; -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; /** - * GameApp + * The {@code GameApp} class is the entry point of the Pac-Man application. + * + * <p>It sets up the primary JavaFX stage, initializes the main menu view, + * and connects it to the corresponding controller. It also manages the + * view system using {@link ViewManager} and sets the application window properties.</p> + * + * <p>This class extends {@link javafx.application.Application} and uses + * JavaFX's lifecycle methods.</p> */ public class GameApp extends Application { + /** Manages the different views (scenes) of the application. */ private ViewManager viewManager = new ViewManager(); + + /** The main menu view shown when the application starts. */ private MainMenuView mainMenuView = new MainMenuView(); + /** + * Starts the JavaFX application and initializes the primary stage. + * + * <p>This method sets up the window properties, adds the main menu view + * to the {@link ViewManager}, and creates the {@link MainMenuController} + * to handle user interaction.</p> + * + * @param primaryStage the primary stage for this application + * @throws Exception if an error occurs during startup + */ @Override public void start(Stage primaryStage) throws Exception { + /* window properties */ primaryStage.setTitle("Pac-Man"); primaryStage.setResizable(false); primaryStage.setFullScreen(true); + /* Adding main menu, and instantiate controller */ viewManager.addView(ViewKeys.MAIN_MENU, mainMenuView); viewManager.showView(ViewKeys.MAIN_MENU); new MainMenuController(viewManager, mainMenuView); - Scene scene = new Scene(viewManager, 1920, 1080); + Scene scene = new Scene(viewManager.getRoot(), 1920, 1080); primaryStage.setScene(scene); primaryStage.show(); } - + + /** + * Launches the JavaFX application. + * + * @param args the command-line arguments passed to the application + */ public static void main(String[] args) { launch(args); } 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 index 0bb4e87..585247f 100644 --- 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 @@ -10,22 +10,47 @@ import javafx.animation.AnimationTimer; import javafx.scene.input.KeyEvent; /** - * GameController + * The {@code GameController} class manages the core game loop, + * user input handling, and interaction between the game state, + * view, and view manager. + * + * <p>It uses a JavaFX {@link AnimationTimer} to continuously update + * the game state and render the game view at regular intervals.</p> */ public class GameController { + /** Manages switching between different views/screens. */ private final ViewManager viewManager; + + /** Reference to the current game state. */ private final GameState gameState; + + /** The view responsible for rendering the game. */ private final GameView gameView; + /** The main game loop running. */ private final AnimationTimer gameLoop; + + /** Timestamp of the last update, used to calculate elapsed time. */ private long lastUpdate = 0; - public GameController(GameState gameState, GameView gameView, ViewManager viewManager) { + /** + * Constructs a new {@code GameController} with the specified game state, + * game view, and view manager. + * + * @param gameState the state of the game + * @param gameView the view that renders the game + * @param viewManager the manager responsible for switching views + */ + public GameController(GameState gameState, GameView gameView, + ViewManager viewManager) { + this.viewManager = viewManager; this.gameState = gameState; this.gameView = gameView; + gameView.setOnKeyPressed(this::handleKeyEvent); + gameLoop = new AnimationTimer() { @Override @@ -44,12 +69,20 @@ public class GameController { }; } - public void handleKeyEvent(KeyEvent event) { + /** + * Handles keyboard input for controlling the game, including + * Pac-Man's movement and other interactions like zoom or pausing. + * + * @param event the key event triggered by user input + */ + private 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 PAGE_UP -> gameView.changeZoom(0.1); + case PAGE_DOWN -> gameView.changeZoom(-0.1); case ESCAPE -> { viewManager.showView(ViewKeys.PAUSE); stopGameLoop(); @@ -58,13 +91,16 @@ public class GameController { } } + /** + * Starts the game loop, beginning the update and render cycle. + */ public void startGameLoop() { - gameView.requestFocusForInput(); - gameView.setOnKeyPressed(event -> handleKeyEvent(event)); - gameLoop.start(); } + /** + * Stops the game loop and resets the last update timestamp. + */ 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 index 5fa6140..58f4d60 100644 --- 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 @@ -6,42 +6,123 @@ 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 javafx.event.ActionEvent; + import com.gr15.pacman.view.ViewManager.ViewKeys; /** - * MainMenuController + * The {@code MainMenuController} handles interactions on the main menu screen. + * + * <p>This includes starting a new game, resuming an existing game, + * or exiting the application. + * It also manages setting up new + * game views and controllers when a new game is launched.</p> */ public class MainMenuController { + /** Manages switching between different views/screens in the application. */ private final ViewManager viewManager; + + /** The main menu view UI. */ private final MainMenuView mainMenuView; + /** The active game view instance, created when starting or resuming a game. */ + private GameView gameView; + + /** The active game controller instance, used to control the game loop. */ + GameController gameController; + + /** + * Constructs a new {@code MainMenuController} with the given + * view manager and main menu view. + * + * @param viewManager the manager responsible for view navigation + * @param mainMenuView the view representing the main menu UI + */ public MainMenuController(ViewManager viewManager, MainMenuView mainMenuView) { this.viewManager = viewManager; this.mainMenuView = mainMenuView; initializeButtons(); } + /** + * Initializes event handlers for the main menu buttons. + * + * <p>This includes setting actions for + * starting a new game, resuming a game, and exiting.</p> + */ private void initializeButtons() { - mainMenuView.getNewGameButton().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); - }); + mainMenuView.getResumeButton().setDisable(true); + mainMenuView.getNewGameButton().setOnAction(this::startNewGame); + mainMenuView.getExitButton().setOnAction(this::exitGame); + mainMenuView.getResumeButton().setOnAction(this::resumeGame); + } + + /** + * Handles the event when the "Resume" button is clicked. + * + * <p>This resumes the game by switching back to the game view + * and starting the game loop.</p> + * + * @param event the action event triggered by the button + */ + private void resumeGame(ActionEvent event) { + if (!viewManager.hasView(ViewKeys.GAME_VIEW) || gameController == null) { + startNewGame(event); + } + + viewManager.showView(ViewKeys.GAME_VIEW); + gameController.startGameLoop(); + } + + /** + * Starts a new game by creating a new game state, views, and controllers. + * + * <p>Loads the initial game state from a JSON file, + * initializes all related components, and switches to the game view.</p> + * + * @param event the action event triggered by the button + */ + private void startNewGame(ActionEvent event) { + GameState gameState = GameStateBuilder.fromJson( + this.getClass().getResourceAsStream("/testGameState.json")); + + /* Creating new views */ + gameView = new GameView(gameState); + + /* Creaing new controllers */ + gameController = new GameController(gameState, + gameView, viewManager); + + /* Removing potentiel old views */ + viewManager.removeView(ViewKeys.GAME_VIEW); + viewManager.removeView(ViewKeys.PAUSE); + + /* Adding new views */ + viewManager.addView(ViewKeys.GAME_VIEW, gameView); + + /* Enabling resume button */ + mainMenuView.getResumeButton().setDisable(false); + + /* Adding pause menu */ + PauseView pauseView = new PauseView(); + new PauseController(pauseView, gameController, viewManager); + viewManager.addView(ViewKeys.PAUSE, pauseView); + + /* Showing game view and starting game */ + viewManager.showView(ViewKeys.GAME_VIEW); + gameController.startGameLoop(); + } + + /** + * Handles the event when the "Quit" button is clicked. + * + * <p>This will exit the application immediately.</p> + * + * @param event the action event triggered by the button + */ + private void exitGame(ActionEvent 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 index 88b60ea..553455a 100644 --- 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 @@ -4,31 +4,101 @@ import com.gr15.pacman.view.ViewManager; import com.gr15.pacman.view.ViewManager.ViewKeys; import com.gr15.pacman.view.screen.PauseView; +import javafx.event.ActionEvent; +import javafx.scene.input.KeyEvent; + /** - * PauseController + * The {@code PauseController} handles user interactions on the game's pause screen. + * + * <p>This includes resuming the game, quitting to the main menu, + * or exiting the application entirely. + * It also manages key input while the pause view is active, + * such as using the ESC key to resume the game.</p> */ public class PauseController { + /** The view representing the pause screen UI. */ private final PauseView pauseView; + + /** The controller managing the main game loop. */ private final GameController gameController; + + /** The view manager responsible for switching between different scenes. */ private final ViewManager viewManager; + /** + * Constructs a new {@code PauseController} with the specified + * view, game controller, and view manager. + * + * @param pauseView the pause screen UI + * @param gameController the game controller to resume or control the game state + * @param viewManager the view manager for switching between views + */ public PauseController(PauseView pauseView, GameController gameController, ViewManager viewManager) { this.gameController = gameController; this.pauseView = pauseView; this.viewManager = viewManager; - initialize(); + setupEventHandlers(); + } + + /** + * Initializes event handlers for pause screen buttons and keyboard input. + */ + private void setupEventHandlers() { + pauseView.getQuitButton().setOnAction(this::exitGame); + pauseView.getMainMenuButton().setOnAction(this::quitToMainMenu); + pauseView.getResumeButton().setOnAction(this::resumeGame); + pauseView.setOnKeyPressed(this::handleKeyEvent); + } + + /** + * Handles key events while the pause view is active. + * + * <p>Pressing ESC will resume the game and return to the game view.</p> + * + * @param event the key event triggered by user input + */ + private void handleKeyEvent(KeyEvent event) { + switch (event.getCode()) { + case ESCAPE -> { + viewManager.showView(ViewKeys.GAME_VIEW); + gameController.startGameLoop(); + } + default -> {} + } + } + + /** + * Handles the event when the "Main Menu" button is clicked. + * + * @param event the action event triggered by the button + */ + private void quitToMainMenu(ActionEvent event) { + viewManager.showView(ViewKeys.MAIN_MENU); + } + + /** + * Handles the event when the "Quit" button is clicked. + * + * <p>This will exit the application immediately.</p> + * + * @param event the action event triggered by the button + */ + private void exitGame(ActionEvent event) { + System.exit(0); } - 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(); - }); + /** + * Handles the event when the "Resume" button is clicked. + * + * <p>This resumes the game by switching back to the game view + * and starting the game loop.</p> + * + * @param event the action event triggered by the button + */ + private void resumeGame(ActionEvent evnet) { + viewManager.showView(ViewKeys.GAME_VIEW); + gameController.startGameLoop(); } } |