From 192ae89a79b78b26e0a935ead4c8365f6b112afb Mon Sep 17 00:00:00 2001 From: co012 Date: Wed, 4 May 2022 13:44:05 +0200 Subject: [PATCH 1/8] chore: pass stage to Controller --- src/main/java/io/rpg/Game.java | 9 ++++---- src/main/java/io/rpg/Main.java | 21 ++++++++++--------- .../java/io/rpg/controller/Controller.java | 14 +++++++++++++ .../model/actions/LocationChangeAction.java | 13 ++++++++++++ 4 files changed, 43 insertions(+), 14 deletions(-) create mode 100644 src/main/java/io/rpg/model/actions/LocationChangeAction.java diff --git a/src/main/java/io/rpg/Game.java b/src/main/java/io/rpg/Game.java index 14f5dd67..f38a5c2f 100644 --- a/src/main/java/io/rpg/Game.java +++ b/src/main/java/io/rpg/Game.java @@ -2,6 +2,7 @@ import io.rpg.controller.Controller; import javafx.scene.Scene; +import javafx.stage.Stage; import org.jetbrains.annotations.NotNull; public class Game { @@ -11,10 +12,6 @@ private Game() { } - public void setLocationControllerForLocationTag(String tag) { - // tutaj przyda sie hashmapa: nazwa lokacji -> kontroller - } - public Scene getWorldView() { return controller.getView(); } @@ -23,6 +20,10 @@ public void setController(Controller controller) { this.controller = controller; } + public void setMainStage(Stage stage) { + controller.setMainStage(stage); + } + public static class Builder { private final Game game; diff --git a/src/main/java/io/rpg/Main.java b/src/main/java/io/rpg/Main.java index eba5a09e..439cfb7a 100644 --- a/src/main/java/io/rpg/Main.java +++ b/src/main/java/io/rpg/Main.java @@ -19,7 +19,7 @@ public void start(Stage stage) throws IOException { Logger logger = LogManager.getLogger(Main.class); Initializer worldInitializer = new Initializer("configurations/demo-config-1", stage); - Result initializationResult = worldInitializer.initialize(); + Result initializationResult = worldInitializer.initialize(); if (initializationResult.isError()) { logger.error("Initialization error"); @@ -37,28 +37,29 @@ public void start(Stage stage) throws IOException { return; } + // TODO: 04.05.2022 Null check for game was already made but IDE still screams Game game = initializationResult.getOkValue(); + game.setMainStage(stage); stage.setScene(game.getWorldView()); stage.show(); - AnimationTimer animationTimer=new AnimationTimer() { - long lastUpdate=-1; + AnimationTimer animationTimer = new AnimationTimer() { + long lastUpdate = -1; + @Override public void handle(long now) { - if(lastUpdate!=-1){ - float difference=(now-lastUpdate)/1e6f; + if (lastUpdate != -1) { + float difference = (now - lastUpdate) / 1e6f; game.getController().getCurrentModel().update(difference); -// locationModel.update(difference); - Player player=game.getController().getCurrentModel().getPlayer(); - if(player!=null){ -// game.getController().getCurrentModel().getPlayer().render(); + Player player = game.getController().getCurrentModel().getPlayer(); + if (player != null) { player.render(); } } - lastUpdate=now; + lastUpdate = now; } }; diff --git a/src/main/java/io/rpg/controller/Controller.java b/src/main/java/io/rpg/controller/Controller.java index d99f3a6a..c868d3f1 100644 --- a/src/main/java/io/rpg/controller/Controller.java +++ b/src/main/java/io/rpg/controller/Controller.java @@ -1,5 +1,6 @@ package io.rpg.controller; +import io.rpg.model.actions.LocationChangeAction; import io.rpg.model.data.KeyboardEvent; import io.rpg.model.data.MouseClickedEvent; import io.rpg.model.data.Vector; @@ -13,6 +14,7 @@ import io.rpg.view.LocationView; import javafx.scene.Scene; import javafx.scene.input.KeyEvent; +import javafx.stage.Stage; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.jetbrains.annotations.NotNull; @@ -27,6 +29,7 @@ public class Controller implements KeyboardEvent.Observer, MouseClickedEvent.Obs private LinkedHashMap tagToLocationViewMap; private Logger logger; private final PopupController popupController = new PopupController(); + private Stage mainStage; public Controller() { @@ -49,6 +52,10 @@ public Controller(LinkedHashMap tagToLocationModelMap, this.currentView = this.tagToLocationViewMap.get(rootTag); } + public void setMainStage(Stage mainStage) { + this.mainStage = mainStage; + } + public void setModel(@NotNull LocationModel model) { this.tagToLocationModelMap.put(model.getTag(), model); currentModel = model; @@ -64,6 +71,13 @@ public void registerToViews(List views) { } } + private void onAction(LocationChangeAction action) { + Scene nextView = this.tagToLocationViewMap.get(action.destinationLocationTag); + LocationModel nextModel = this.tagToLocationModelMap.get(action.destinationLocationTag); + + + } + public Scene getView() { return currentView; } diff --git a/src/main/java/io/rpg/model/actions/LocationChangeAction.java b/src/main/java/io/rpg/model/actions/LocationChangeAction.java new file mode 100644 index 00000000..b65c1ab4 --- /dev/null +++ b/src/main/java/io/rpg/model/actions/LocationChangeAction.java @@ -0,0 +1,13 @@ +package io.rpg.model.actions; + +/** + * Class for storing local data needed to preform a location change action + */ + +public class LocationChangeAction { + public final String destinationLocationTag; + + public LocationChangeAction(String destinationLocationTag) { + this.destinationLocationTag = destinationLocationTag; + } +} From ca34ce7e1e95b00f0e8e1a343f268fbca30d0c39 Mon Sep 17 00:00:00 2001 From: co012 Date: Wed, 4 May 2022 14:09:26 +0200 Subject: [PATCH 2/8] feat: change location --- .../locations/location-2/location-2.json | 11 +++++ configurations/demo-config-1/root.json | 3 +- .../java/io/rpg/controller/Controller.java | 14 +++++-- .../model/actions/LocationChangeAction.java | 6 ++- .../io/rpg/model/location/LocationModel.java | 1 + src/main/java/io/rpg/model/object/Player.java | 42 +++++++++---------- src/main/java/io/rpg/view/LocationView.java | 9 ++-- 7 files changed, 55 insertions(+), 31 deletions(-) create mode 100644 configurations/demo-config-1/locations/location-2/location-2.json diff --git a/configurations/demo-config-1/locations/location-2/location-2.json b/configurations/demo-config-1/locations/location-2/location-2.json new file mode 100644 index 00000000..e82af4e6 --- /dev/null +++ b/configurations/demo-config-1/locations/location-2/location-2.json @@ -0,0 +1,11 @@ +{ + "tag": "location-2", + "objects": [ + { "tag": "object-1", "position": { "row": 1, "col": 8 }, "type": "collectible", "assetPath": "assets/diamond.png" }, + { "tag": "object-2", "position": { "row": 6, "col": 3 }, "type": "collectible", "assetPath": "assets/key.png" }, + { "tag": "object-3", "position": { "row": 1, "col": 1 }, "type": "dialog", "assetPath": "assets/zombie.png" }, + { "tag": "object-4", "position": { "row": 3, "col": 2 }, "type": "dialog", "assetPath": "assets/zombie.png" }, + { "tag": "object-5", "position": { "row": 8, "col": 8 }, "type": "dialog", "assetPath": "assets/chest.png" } + ], + "backgroundPath": "assets/map10x10.png" +} diff --git a/configurations/demo-config-1/root.json b/configurations/demo-config-1/root.json index a1a906e8..d3144043 100644 --- a/configurations/demo-config-1/root.json +++ b/configurations/demo-config-1/root.json @@ -1,7 +1,8 @@ { "tag": "GameByConfig1", "locationTags": [ - "location-1" + "location-1", + "location-2" ], "rootLocation": "location-1", "player": { diff --git a/src/main/java/io/rpg/controller/Controller.java b/src/main/java/io/rpg/controller/Controller.java index c868d3f1..385b266a 100644 --- a/src/main/java/io/rpg/controller/Controller.java +++ b/src/main/java/io/rpg/controller/Controller.java @@ -3,6 +3,7 @@ import io.rpg.model.actions.LocationChangeAction; import io.rpg.model.data.KeyboardEvent; import io.rpg.model.data.MouseClickedEvent; +import io.rpg.model.data.Position; import io.rpg.model.data.Vector; import io.rpg.model.location.LocationModel; import io.rpg.model.object.CollectibleGameObject; @@ -72,10 +73,16 @@ public void registerToViews(List views) { } private void onAction(LocationChangeAction action) { + if (!this.tagToLocationModelMap.containsKey(action.destinationLocationTag)) { + logger.error("Unknown location tag"); + return; + } + Scene nextView = this.tagToLocationViewMap.get(action.destinationLocationTag); LocationModel nextModel = this.tagToLocationModelMap.get(action.destinationLocationTag); - - + this.currentModel = nextModel; + this.currentView = nextView; + mainStage.setScene(nextView); } public Scene getView() { @@ -121,10 +128,11 @@ public void onKeyboardEvent(KeyboardEvent event) { KeyEvent payload = event.payload(); - if (payload.getEventType() == KeyEvent.KEY_PRESSED){ + if (payload.getEventType() == KeyEvent.KEY_PRESSED) { switch (payload.getCode()) { case F -> popupController.openPointsPopup(5, getWindowCenterX(), getWindowCenterY()); case G -> popupController.openTextPopup("Hello!", getWindowCenterX(), getWindowCenterY()); + case L -> onAction(new LocationChangeAction("location-2", new Position(2, 2))); case A -> currentModel.getPlayer().setLeftPressed(true); case D -> currentModel.getPlayer().setRightPressed(true); case S -> currentModel.getPlayer().setDownPressed(true); diff --git a/src/main/java/io/rpg/model/actions/LocationChangeAction.java b/src/main/java/io/rpg/model/actions/LocationChangeAction.java index b65c1ab4..cc7f65c6 100644 --- a/src/main/java/io/rpg/model/actions/LocationChangeAction.java +++ b/src/main/java/io/rpg/model/actions/LocationChangeAction.java @@ -1,13 +1,17 @@ package io.rpg.model.actions; +import io.rpg.model.data.Position; + /** * Class for storing local data needed to preform a location change action */ public class LocationChangeAction { public final String destinationLocationTag; + private Position playerPosition; - public LocationChangeAction(String destinationLocationTag) { + public LocationChangeAction(String destinationLocationTag, Position playerPosition) { this.destinationLocationTag = destinationLocationTag; + this.playerPosition = playerPosition; } } diff --git a/src/main/java/io/rpg/model/location/LocationModel.java b/src/main/java/io/rpg/model/location/LocationModel.java index 97b227eb..07da8020 100644 --- a/src/main/java/io/rpg/model/location/LocationModel.java +++ b/src/main/java/io/rpg/model/location/LocationModel.java @@ -44,6 +44,7 @@ public Player getPlayer() { return player; } + public GameObject getObject(int row, int column) { GameObject object = gameObjects.stream().filter(gameObject -> gameObject.getPosition() .equals(new Position(row, column))) diff --git a/src/main/java/io/rpg/model/object/Player.java b/src/main/java/io/rpg/model/object/Player.java index 4ef5acc7..29a7b73e 100644 --- a/src/main/java/io/rpg/model/object/Player.java +++ b/src/main/java/io/rpg/model/object/Player.java @@ -9,25 +9,21 @@ public class Player extends GameObject { - Vector currentPosition; - int strength; - float speed; - Vector direction; - boolean rightPressed; - boolean leftPressed; - boolean upPressed; - boolean downPressed; - GameObjectView gameObjectView; + private Vector currentPosition; + private int strength; + private float speed; + private Vector direction; + private boolean rightPressed; + private boolean leftPressed; + private boolean upPressed; + private boolean downPressed; + private GameObjectView gameObjectView; private Vector pixelPosition; - // public GameObject(@NotNull String tag, @NotNull Position position, @NotNull String assetPath) { -// this.tag = tag; -// this.position = position; -// this.assetPath = assetPath; -// } + public Player(@NotNull String tag, @NotNull Position position, @NotNull String assetPath) { super(tag, position, assetPath); - this.currentPosition=new Vector(position.col, position.row); + this.currentPosition = new Vector(position.col, position.row); this.speed = 100f; this.direction = new Vector(0, 0); this.rightPressed = false; @@ -54,17 +50,21 @@ public void update(float elapsed) { float y = 0; float x = 0; // the sum tells us the direction - if (upPressed) + if (upPressed) { y += -1; + } - if (downPressed) + if (downPressed) { y += 1; + } - if (leftPressed) + if (leftPressed) { x += -1; + } - if (rightPressed) + if (rightPressed) { x += 1; + } this.pixelPosition = new Vector(this.pixelPosition.x + speed * x * elapsed / 1000, this.pixelPosition.y + speed * y * elapsed / 1000); } @@ -93,8 +93,8 @@ public void setGameObjectView(GameObjectView gameObjectView) { this.gameObjectView = gameObjectView; } - public void render(){ - if(gameObjectView!=null){ + public void render() { + if (gameObjectView != null) { gameObjectView.setX(this.pixelPosition.x); gameObjectView.setY(this.pixelPosition.y); } diff --git a/src/main/java/io/rpg/view/LocationView.java b/src/main/java/io/rpg/view/LocationView.java index e9c4fbcc..67cc3509 100644 --- a/src/main/java/io/rpg/view/LocationView.java +++ b/src/main/java/io/rpg/view/LocationView.java @@ -102,13 +102,12 @@ public void onLocationModelStateChange(LocationModelStateChange event) { } - List gameObjectViews=new ArrayList<>(); + List gameObjectViews = new ArrayList<>(); - public void createViewsForObjects(LocationModel locationModel){ - for(GameObject g: locationModel.getGameObjects()){ - GameObjectView gameObjectView=new GameObjectView(Path.of(g.getAssetPath()),g.getPosition()); + public void createViewsForObjects(LocationModel locationModel) { + for (GameObject g : locationModel.getGameObjects()) { + GameObjectView gameObjectView = new GameObjectView(Path.of(g.getAssetPath()), g.getPosition()); gameObjectViews.add(gameObjectView); -// g.view=gameObjectView; viewModel.getForegroundPane().getChildren().add(gameObjectView); } } From a20668394de41f4047e06956e61cc49a1ea92b2d Mon Sep 17 00:00:00 2001 From: co012 Date: Wed, 4 May 2022 14:58:18 +0200 Subject: [PATCH 3/8] chore: create PlayerController --- src/main/java/io/rpg/Initializer.java | 16 ++++++++++------ .../java/io/rpg/controller/Controller.java | 8 +++++++- .../io/rpg/controller/PlayerController.java | 19 +++++++++++++++++++ 3 files changed, 36 insertions(+), 7 deletions(-) create mode 100644 src/main/java/io/rpg/controller/PlayerController.java diff --git a/src/main/java/io/rpg/Initializer.java b/src/main/java/io/rpg/Initializer.java index 2886a802..cf95319d 100644 --- a/src/main/java/io/rpg/Initializer.java +++ b/src/main/java/io/rpg/Initializer.java @@ -5,6 +5,7 @@ import io.rpg.controller.Controller; import io.rpg.config.model.GameWorldConfig; import io.rpg.config.model.LocationConfig; +import io.rpg.controller.PlayerController; import io.rpg.model.location.LocationModel; import io.rpg.model.object.GameObject; import io.rpg.config.model.GameObjectConfig; @@ -79,9 +80,11 @@ public Result initialize() { }); if (locationConfig.getTag().equals(gameWorldConfig.getRootLocation())) { - controllerBuilder - .setModel(model) - .setView(view); +// controllerBuilder +// .setModel(model) +// .setView(view); + + } model.addOnLocationModelStateChangeObserver(view); @@ -98,9 +101,10 @@ public Result initialize() { // TODO: consider moving it to separate method Player player = (Player) GameObjectFactory.fromConfig(gameWorldConfig.getPlayerConfig()); GameObjectView playerView = GameObjectViewFactory.fromConfig(gameWorldConfig.getPlayerConfig()); - player.addGameObjectStateChangeObserver(playerView); - controllerBuilder.setPlayer(player); - player.setGameObjectView(playerView); + PlayerController playerController = new PlayerController(player, playerView); + + controllerBuilder.setPlayerController(playerController); + Controller controller = controllerBuilder.build(); // TODO: this is a temporary solution diff --git a/src/main/java/io/rpg/controller/Controller.java b/src/main/java/io/rpg/controller/Controller.java index 385b266a..d23d5d80 100644 --- a/src/main/java/io/rpg/controller/Controller.java +++ b/src/main/java/io/rpg/controller/Controller.java @@ -30,6 +30,7 @@ public class Controller implements KeyboardEvent.Observer, MouseClickedEvent.Obs private LinkedHashMap tagToLocationViewMap; private Logger logger; private final PopupController popupController = new PopupController(); + private PlayerController playerController; private Stage mainStage; @@ -78,8 +79,9 @@ private void onAction(LocationChangeAction action) { return; } - Scene nextView = this.tagToLocationViewMap.get(action.destinationLocationTag); + LocationView nextView = this.tagToLocationViewMap.get(action.destinationLocationTag); LocationModel nextModel = this.tagToLocationModelMap.get(action.destinationLocationTag); + this.currentModel = nextModel; this.currentView = nextView; mainStage.setScene(nextView); @@ -257,6 +259,10 @@ public Builder setPlayer(Player gameObject) { player = gameObject; return this; } + + public void setPlayerController(PlayerController playerController) { + controller.playerController = playerController; + } } public LocationModel getCurrentModel() { return currentModel; diff --git a/src/main/java/io/rpg/controller/PlayerController.java b/src/main/java/io/rpg/controller/PlayerController.java new file mode 100644 index 00000000..34877a15 --- /dev/null +++ b/src/main/java/io/rpg/controller/PlayerController.java @@ -0,0 +1,19 @@ +package io.rpg.controller; + +import io.rpg.model.object.Player; +import io.rpg.view.GameObjectView; + +public class PlayerController { + private final Player player; + private final GameObjectView playerView; + + public PlayerController(Player player, GameObjectView playerView) { + this.player = player; + this.playerView = playerView; + + player.addGameObjectStateChangeObserver(playerView); + player.setGameObjectView(playerView); + } + + +} From 72ddb25bbf661580656b93ed33f8d840a69dadab Mon Sep 17 00:00:00 2001 From: co012 Date: Wed, 4 May 2022 15:25:35 +0200 Subject: [PATCH 4/8] chore: made generic Action --- src/main/java/io/rpg/Initializer.java | 7 +++--- .../java/io/rpg/controller/Controller.java | 23 ++++++++++++++++++- .../java/io/rpg/model/actions/Action.java | 7 ++++++ .../model/actions/LocationChangeAction.java | 4 ++-- 4 files changed, 34 insertions(+), 7 deletions(-) create mode 100644 src/main/java/io/rpg/model/actions/Action.java diff --git a/src/main/java/io/rpg/Initializer.java b/src/main/java/io/rpg/Initializer.java index cf95319d..e32e228b 100644 --- a/src/main/java/io/rpg/Initializer.java +++ b/src/main/java/io/rpg/Initializer.java @@ -80,10 +80,9 @@ public Result initialize() { }); if (locationConfig.getTag().equals(gameWorldConfig.getRootLocation())) { -// controllerBuilder -// .setModel(model) -// .setView(view); - + controllerBuilder + .setModel(model) + .setView(view); } diff --git a/src/main/java/io/rpg/controller/Controller.java b/src/main/java/io/rpg/controller/Controller.java index d23d5d80..2f56134d 100644 --- a/src/main/java/io/rpg/controller/Controller.java +++ b/src/main/java/io/rpg/controller/Controller.java @@ -1,5 +1,6 @@ package io.rpg.controller; +import io.rpg.model.actions.Action; import io.rpg.model.actions.LocationChangeAction; import io.rpg.model.data.KeyboardEvent; import io.rpg.model.data.MouseClickedEvent; @@ -13,6 +14,8 @@ import io.rpg.util.Result; import io.rpg.view.GameObjectView; import io.rpg.view.LocationView; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; import javafx.scene.Scene; import javafx.scene.input.KeyEvent; import javafx.stage.Stage; @@ -73,6 +76,24 @@ public void registerToViews(List views) { } } + public void onAction(Action action) { + Class[] args = {action.getClass()}; + Method onSpecificAction; + + try { + onSpecificAction = this.getClass().getDeclaredMethod("onAction", args); + } catch (NoSuchMethodException e) { + logger.error("onAction for " + action.getClass().getSimpleName() + "is not implemented"); + return; + } + + try { + onSpecificAction.invoke(this, action); + } catch (IllegalAccessException | InvocationTargetException e) { + throw new RuntimeException(e); + } + } + private void onAction(LocationChangeAction action) { if (!this.tagToLocationModelMap.containsKey(action.destinationLocationTag)) { logger.error("Unknown location tag"); @@ -134,7 +155,7 @@ public void onKeyboardEvent(KeyboardEvent event) { switch (payload.getCode()) { case F -> popupController.openPointsPopup(5, getWindowCenterX(), getWindowCenterY()); case G -> popupController.openTextPopup("Hello!", getWindowCenterX(), getWindowCenterY()); - case L -> onAction(new LocationChangeAction("location-2", new Position(2, 2))); + case L -> onAction((Action) new LocationChangeAction("location-2", new Position(2, 2))); case A -> currentModel.getPlayer().setLeftPressed(true); case D -> currentModel.getPlayer().setRightPressed(true); case S -> currentModel.getPlayer().setDownPressed(true); diff --git a/src/main/java/io/rpg/model/actions/Action.java b/src/main/java/io/rpg/model/actions/Action.java new file mode 100644 index 00000000..3b13b7d0 --- /dev/null +++ b/src/main/java/io/rpg/model/actions/Action.java @@ -0,0 +1,7 @@ +package io.rpg.model.actions; + +/** + * A marker interface for action classes. + */ +public interface Action { +} diff --git a/src/main/java/io/rpg/model/actions/LocationChangeAction.java b/src/main/java/io/rpg/model/actions/LocationChangeAction.java index cc7f65c6..5bd8f0a4 100644 --- a/src/main/java/io/rpg/model/actions/LocationChangeAction.java +++ b/src/main/java/io/rpg/model/actions/LocationChangeAction.java @@ -3,10 +3,10 @@ import io.rpg.model.data.Position; /** - * Class for storing local data needed to preform a location change action + * Class for storing local data needed to preform a location change action. */ -public class LocationChangeAction { +public class LocationChangeAction implements Action { public final String destinationLocationTag; private Position playerPosition; From 13781e33a1cdb4d6f17731df781b3ae5a6f0e183 Mon Sep 17 00:00:00 2001 From: co012 Date: Wed, 4 May 2022 15:57:18 +0200 Subject: [PATCH 5/8] chore: refactor game start --- src/main/java/io/rpg/Game.java | 12 +++++++-- src/main/java/io/rpg/Initializer.java | 21 +++++++-------- src/main/java/io/rpg/Main.java | 2 +- .../java/io/rpg/controller/Controller.java | 20 +++++++------- .../io/rpg/controller/PlayerController.java | 26 ++++++++++++++++++- 5 files changed, 55 insertions(+), 26 deletions(-) diff --git a/src/main/java/io/rpg/Game.java b/src/main/java/io/rpg/Game.java index f38a5c2f..5d110dd8 100644 --- a/src/main/java/io/rpg/Game.java +++ b/src/main/java/io/rpg/Game.java @@ -1,12 +1,13 @@ package io.rpg; import io.rpg.controller.Controller; +import io.rpg.model.actions.Action; import javafx.scene.Scene; import javafx.stage.Stage; -import org.jetbrains.annotations.NotNull; public class Game { private Controller controller; + private Action onStart; private Game() { @@ -20,8 +21,10 @@ public void setController(Controller controller) { this.controller = controller; } - public void setMainStage(Stage stage) { + public void start(Stage stage) { + stage.show(); controller.setMainStage(stage); + controller.onAction(onStart); } public static class Builder { @@ -41,6 +44,11 @@ public Builder setController(Controller controller) { game.setController(controller); return this; } + + public Builder setOnStartAction(Action onStart) { + game.onStart = onStart; + return this; + } } public Controller getController() { diff --git a/src/main/java/io/rpg/Initializer.java b/src/main/java/io/rpg/Initializer.java index e32e228b..723f0e8b 100644 --- a/src/main/java/io/rpg/Initializer.java +++ b/src/main/java/io/rpg/Initializer.java @@ -6,6 +6,8 @@ import io.rpg.config.model.GameWorldConfig; import io.rpg.config.model.LocationConfig; import io.rpg.controller.PlayerController; +import io.rpg.model.actions.LocationChangeAction; +import io.rpg.model.data.Position; import io.rpg.model.location.LocationModel; import io.rpg.model.object.GameObject; import io.rpg.config.model.GameObjectConfig; @@ -55,6 +57,7 @@ public Result initialize() { GameWorldConfig gameWorldConfig = gameWorldConfigLoadResult.getOkValue(); + Controller.Builder controllerBuilder = new Controller.Builder(); assert gameWorldConfig.getLocationConfigs() != null; @@ -79,13 +82,6 @@ public Result initialize() { view.getViewModel().addChild(view_); }); - if (locationConfig.getTag().equals(gameWorldConfig.getRootLocation())) { - controllerBuilder - .setModel(model) - .setView(view); - - } - model.addOnLocationModelStateChangeObserver(view); controllerBuilder @@ -106,13 +102,16 @@ public Result initialize() { Controller controller = controllerBuilder.build(); - // TODO: this is a temporary solution - controller.setPlayerView(playerView); +// // TODO: this is a temporary solution +// controller.setPlayerView(playerView); Game.Builder gameBuilder = new Game.Builder(); - gameBuilder.setController(controller); + Game game = gameBuilder + .setController(controller) + .setOnStartAction(new LocationChangeAction(gameWorldConfig.getRootLocation(), player.getPosition())) + .build(); - return Result.ok(gameBuilder.build()); + return Result.ok(game); } public static List loadGameObjectsForLocation(LocationConfig config) { diff --git a/src/main/java/io/rpg/Main.java b/src/main/java/io/rpg/Main.java index 439cfb7a..2bbd5f2a 100644 --- a/src/main/java/io/rpg/Main.java +++ b/src/main/java/io/rpg/Main.java @@ -39,7 +39,7 @@ public void start(Stage stage) throws IOException { // TODO: 04.05.2022 Null check for game was already made but IDE still screams Game game = initializationResult.getOkValue(); - game.setMainStage(stage); + game.start(stage); stage.setScene(game.getWorldView()); diff --git a/src/main/java/io/rpg/controller/Controller.java b/src/main/java/io/rpg/controller/Controller.java index 2f56134d..74042ed7 100644 --- a/src/main/java/io/rpg/controller/Controller.java +++ b/src/main/java/io/rpg/controller/Controller.java @@ -100,9 +100,15 @@ private void onAction(LocationChangeAction action) { return; } + if (currentView != null) { + ((LocationView) currentView).removeKeyboardEventObserver(playerController); + } + LocationView nextView = this.tagToLocationViewMap.get(action.destinationLocationTag); + nextView.addKeyboardEventObserver(playerController); LocationModel nextModel = this.tagToLocationModelMap.get(action.destinationLocationTag); + this.currentModel = nextModel; this.currentView = nextView; mainStage.setScene(nextView); @@ -156,19 +162,11 @@ public void onKeyboardEvent(KeyboardEvent event) { case F -> popupController.openPointsPopup(5, getWindowCenterX(), getWindowCenterY()); case G -> popupController.openTextPopup("Hello!", getWindowCenterX(), getWindowCenterY()); case L -> onAction((Action) new LocationChangeAction("location-2", new Position(2, 2))); - case A -> currentModel.getPlayer().setLeftPressed(true); - case D -> currentModel.getPlayer().setRightPressed(true); - case S -> currentModel.getPlayer().setDownPressed(true); - case W -> currentModel.getPlayer().setUpPressed(true); - } - } else if (payload.getEventType() == KeyEvent.KEY_RELEASED) { - switch (payload.getCode()) { - case A -> currentModel.getPlayer().setLeftPressed(false); - case D -> currentModel.getPlayer().setRightPressed(false); - case S -> currentModel.getPlayer().setDownPressed(false); - case W -> currentModel.getPlayer().setUpPressed(false); } } + // } else if (payload.getEventType() == KeyEvent.KEY_RELEASED) { + // + // } } private int getWindowCenterX() { diff --git a/src/main/java/io/rpg/controller/PlayerController.java b/src/main/java/io/rpg/controller/PlayerController.java index 34877a15..b24acf05 100644 --- a/src/main/java/io/rpg/controller/PlayerController.java +++ b/src/main/java/io/rpg/controller/PlayerController.java @@ -1,9 +1,14 @@ package io.rpg.controller; +import io.rpg.model.actions.Action; +import io.rpg.model.actions.LocationChangeAction; +import io.rpg.model.data.KeyboardEvent; +import io.rpg.model.data.Position; import io.rpg.model.object.Player; import io.rpg.view.GameObjectView; +import javafx.scene.input.KeyEvent; -public class PlayerController { +public class PlayerController implements KeyboardEvent.Observer { private final Player player; private final GameObjectView playerView; @@ -15,5 +20,24 @@ public PlayerController(Player player, GameObjectView playerView) { player.setGameObjectView(playerView); } + @Override + public void onKeyboardEvent(KeyboardEvent event) { + KeyEvent payload = event.payload(); + if (payload.getEventType() == KeyEvent.KEY_PRESSED) { + switch (payload.getCode()) { + case A -> player.setLeftPressed(true); + case D -> player.setRightPressed(true); + case S -> player.setDownPressed(true); + case W -> player.setUpPressed(true); + } + } else if (payload.getEventType() == KeyEvent.KEY_RELEASED) { + switch (payload.getCode()) { + case A -> player.setLeftPressed(false); + case D -> player.setRightPressed(false); + case S -> player.setDownPressed(false); + case W -> player.setUpPressed(false); + } + } + } } From 8ddda7d961608cfb3fe3b669bf30b5ed0e6679a7 Mon Sep 17 00:00:00 2001 From: co012 Date: Wed, 4 May 2022 16:24:34 +0200 Subject: [PATCH 6/8] chore: teleport player --- src/main/java/io/rpg/Initializer.java | 4 +- src/main/java/io/rpg/Main.java | 4 -- .../java/io/rpg/controller/Controller.java | 55 +------------------ .../io/rpg/controller/PlayerController.java | 22 +++++++- src/main/java/io/rpg/view/LocationView.java | 7 +++ .../io/rpg/viewmodel/LocationViewModel.java | 4 -- 6 files changed, 28 insertions(+), 68 deletions(-) diff --git a/src/main/java/io/rpg/Initializer.java b/src/main/java/io/rpg/Initializer.java index 723f0e8b..a76d14cb 100644 --- a/src/main/java/io/rpg/Initializer.java +++ b/src/main/java/io/rpg/Initializer.java @@ -78,9 +78,7 @@ public Result initialize() { assert view != null; - gameObjectViews.forEach(view_ -> { - view.getViewModel().addChild(view_); - }); + gameObjectViews.forEach(view::addChild); model.addOnLocationModelStateChangeObserver(view); diff --git a/src/main/java/io/rpg/Main.java b/src/main/java/io/rpg/Main.java index 2bbd5f2a..c497e85c 100644 --- a/src/main/java/io/rpg/Main.java +++ b/src/main/java/io/rpg/Main.java @@ -41,10 +41,6 @@ public void start(Stage stage) throws IOException { Game game = initializationResult.getOkValue(); game.start(stage); - stage.setScene(game.getWorldView()); - - stage.show(); - AnimationTimer animationTimer = new AnimationTimer() { long lastUpdate = -1; diff --git a/src/main/java/io/rpg/controller/Controller.java b/src/main/java/io/rpg/controller/Controller.java index 74042ed7..bf82186a 100644 --- a/src/main/java/io/rpg/controller/Controller.java +++ b/src/main/java/io/rpg/controller/Controller.java @@ -100,14 +100,10 @@ private void onAction(LocationChangeAction action) { return; } - if (currentView != null) { - ((LocationView) currentView).removeKeyboardEventObserver(playerController); - } - LocationView nextView = this.tagToLocationViewMap.get(action.destinationLocationTag); - nextView.addKeyboardEventObserver(playerController); LocationModel nextModel = this.tagToLocationModelMap.get(action.destinationLocationTag); + playerController.teleportTo(nextModel, nextView); this.currentModel = nextModel; this.currentView = nextView; @@ -141,10 +137,6 @@ else if (tagToLocationViewMap.size() == 0) return Result.error(new Exception("Empty tag to location view map!")); else if (tagToLocationViewMap.size() != tagToLocationModelMap.size()) return Result.error(new Exception("Mismatched sizes of maps!")); - else if (currentView == null) - return Result.error(new Exception("No current view set!")); - else if (currentModel == null) - return Result.error(new Exception("No current model set!")); else return Result.ok(this); } @@ -200,54 +192,14 @@ private void setPlayer(Player gameObject) { currentModel.setPlayer(gameObject); } - // TODO: temporary solution - public void setPlayerView(GameObjectView playerView) { - ((LocationView) currentView).getViewModel().addChild(playerView); - } - public static class Builder { private final Controller controller; - private boolean isViewSet = false; - private boolean isModelSet = false; - - private Player player; public Builder() { controller = new Controller(); } - public Builder setTagToLocationModelMap(LinkedHashMap tagToLocationModelMap) { - controller.setTagToLocationModelMap(tagToLocationModelMap); - return this; - } - - public Builder setTagToLocationViewMap(LinkedHashMap tagToLocationViewMap) { - controller.setTagToLocationViewMap(tagToLocationViewMap); - return this; - } - - public Builder setModel(@NotNull LocationModel model) { - if (!isModelSet) { - isModelSet = true; - controller.setModel(model); - return this; - } else { - throw new IllegalStateException("Attempt to set model for the second time!"); - } - } - - public Builder setView(Scene currentView) { - if (!isViewSet) { - isViewSet = true; - controller.setView(currentView); - return this; - } else { - throw new IllegalStateException("Attempt to set view for the second time!"); - } - } - public Controller build() { - controller.setPlayer(player); Result validationResult = controller.validate(); if (validationResult.isError()) { throw new IllegalStateException(validationResult.getErrorValue()); @@ -274,11 +226,6 @@ public Builder addModelForTag(String tag, LocationModel model) { return this; } - public Builder setPlayer(Player gameObject) { - player = gameObject; - return this; - } - public void setPlayerController(PlayerController playerController) { controller.playerController = playerController; } diff --git a/src/main/java/io/rpg/controller/PlayerController.java b/src/main/java/io/rpg/controller/PlayerController.java index b24acf05..b25b9791 100644 --- a/src/main/java/io/rpg/controller/PlayerController.java +++ b/src/main/java/io/rpg/controller/PlayerController.java @@ -1,20 +1,21 @@ package io.rpg.controller; -import io.rpg.model.actions.Action; -import io.rpg.model.actions.LocationChangeAction; import io.rpg.model.data.KeyboardEvent; -import io.rpg.model.data.Position; +import io.rpg.model.location.LocationModel; import io.rpg.model.object.Player; import io.rpg.view.GameObjectView; +import io.rpg.view.LocationView; import javafx.scene.input.KeyEvent; public class PlayerController implements KeyboardEvent.Observer { private final Player player; private final GameObjectView playerView; + private Runnable onChangeLocation; public PlayerController(Player player, GameObjectView playerView) { this.player = player; this.playerView = playerView; + this.onChangeLocation = () -> {}; player.addGameObjectStateChangeObserver(playerView); player.setGameObjectView(playerView); @@ -40,4 +41,19 @@ public void onKeyboardEvent(KeyboardEvent event) { } } + public void teleportTo(LocationModel model, LocationView view) { + onChangeLocation.run(); + updateOnChangeLocation(model, view); + + model.setPlayer(player); + view.addChild(playerView); + view.addKeyboardEventObserver(this); + } + + private void updateOnChangeLocation(LocationModel model, LocationView view) { + this.onChangeLocation = () -> { + view.removeKeyboardEventObserver(this); + view.removeChild(this.playerView); + }; + } } diff --git a/src/main/java/io/rpg/view/LocationView.java b/src/main/java/io/rpg/view/LocationView.java index 67cc3509..d23370f8 100644 --- a/src/main/java/io/rpg/view/LocationView.java +++ b/src/main/java/io/rpg/view/LocationView.java @@ -112,4 +112,11 @@ public void createViewsForObjects(LocationModel locationModel) { } } + public void removeChild(GameObjectView view) { + viewModel.getForegroundPane().getChildren().remove(view); + } + + public void addChild(GameObjectView view) { + viewModel.getForegroundPane().getChildren().add(view); + } } diff --git a/src/main/java/io/rpg/viewmodel/LocationViewModel.java b/src/main/java/io/rpg/viewmodel/LocationViewModel.java index 451c5753..b3904feb 100644 --- a/src/main/java/io/rpg/viewmodel/LocationViewModel.java +++ b/src/main/java/io/rpg/viewmodel/LocationViewModel.java @@ -52,10 +52,6 @@ public void initialize(URL location, ResourceBundle resources) { }); } - public void addChild(ImageView child) { - contentPane.getChildren().add(child); - } - public Pane getForegroundPane() { return foregroundPane; } From 350e775dfa2b51a03a13d0d9a5000839be07f813 Mon Sep 17 00:00:00 2001 From: co012 Date: Wed, 4 May 2022 16:27:09 +0200 Subject: [PATCH 7/8] chore: fix for concurrent modification exception --- src/main/java/io/rpg/view/LocationView.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/java/io/rpg/view/LocationView.java b/src/main/java/io/rpg/view/LocationView.java index d23370f8..11889df2 100644 --- a/src/main/java/io/rpg/view/LocationView.java +++ b/src/main/java/io/rpg/view/LocationView.java @@ -9,6 +9,8 @@ import io.rpg.model.object.GameObject; import io.rpg.viewmodel.LocationViewModel; import io.rpg.config.model.LocationConfig; +import java.util.Collection; +import java.util.Collections; import javafx.fxml.FXMLLoader; import javafx.scene.Parent; import javafx.scene.Scene; @@ -89,7 +91,8 @@ public void removeKeyboardEventObserver(KeyboardEvent.Observer observer) { @Override public void emitKeyboardEvent(KeyboardEvent event) { - onKeyPressedObservers.forEach(observer -> { + List observers = new ArrayList<>(onKeyPressedObservers); + observers.forEach(observer -> { observer.onKeyboardEvent(event); }); } From 734ac91e8db26d791f1e9d805a89a3ded145dd74 Mon Sep 17 00:00:00 2001 From: co012 Date: Wed, 4 May 2022 16:41:14 +0200 Subject: [PATCH 8/8] chore: change player position on teleport --- src/main/java/io/rpg/Game.java | 4 ---- src/main/java/io/rpg/controller/Controller.java | 14 ++------------ .../java/io/rpg/controller/PlayerController.java | 11 ++++++++++- .../io/rpg/model/actions/LocationChangeAction.java | 2 +- src/main/java/io/rpg/model/object/Player.java | 4 ++++ 5 files changed, 17 insertions(+), 18 deletions(-) diff --git a/src/main/java/io/rpg/Game.java b/src/main/java/io/rpg/Game.java index 5d110dd8..268cd528 100644 --- a/src/main/java/io/rpg/Game.java +++ b/src/main/java/io/rpg/Game.java @@ -13,10 +13,6 @@ private Game() { } - public Scene getWorldView() { - return controller.getView(); - } - public void setController(Controller controller) { this.controller = controller; } diff --git a/src/main/java/io/rpg/controller/Controller.java b/src/main/java/io/rpg/controller/Controller.java index bf82186a..13d258b0 100644 --- a/src/main/java/io/rpg/controller/Controller.java +++ b/src/main/java/io/rpg/controller/Controller.java @@ -70,12 +70,6 @@ public void setView(Scene currentView) { this.currentView = currentView; } - public void registerToViews(List views) { - for (GameObjectView view : views) { - view.addOnClickedObserver(this); - } - } - public void onAction(Action action) { Class[] args = {action.getClass()}; Method onSpecificAction; @@ -103,7 +97,7 @@ private void onAction(LocationChangeAction action) { LocationView nextView = this.tagToLocationViewMap.get(action.destinationLocationTag); LocationModel nextModel = this.tagToLocationModelMap.get(action.destinationLocationTag); - playerController.teleportTo(nextModel, nextView); + playerController.teleportTo(nextModel, nextView, action.playerPosition); this.currentModel = nextModel; this.currentView = nextView; @@ -153,7 +147,7 @@ public void onKeyboardEvent(KeyboardEvent event) { switch (payload.getCode()) { case F -> popupController.openPointsPopup(5, getWindowCenterX(), getWindowCenterY()); case G -> popupController.openTextPopup("Hello!", getWindowCenterX(), getWindowCenterY()); - case L -> onAction((Action) new LocationChangeAction("location-2", new Position(2, 2))); + case L -> onAction((Action) new LocationChangeAction("location-2", new Position(1, 2))); } } // } else if (payload.getEventType() == KeyEvent.KEY_RELEASED) { @@ -188,10 +182,6 @@ public void onMouseClickedEvent(MouseClickedEvent event) { logger.info("Controller notified on click from " + event.source()); } - private void setPlayer(Player gameObject) { - currentModel.setPlayer(gameObject); - } - public static class Builder { private final Controller controller; diff --git a/src/main/java/io/rpg/controller/PlayerController.java b/src/main/java/io/rpg/controller/PlayerController.java index b25b9791..cab82897 100644 --- a/src/main/java/io/rpg/controller/PlayerController.java +++ b/src/main/java/io/rpg/controller/PlayerController.java @@ -1,6 +1,7 @@ package io.rpg.controller; import io.rpg.model.data.KeyboardEvent; +import io.rpg.model.data.Position; import io.rpg.model.location.LocationModel; import io.rpg.model.object.Player; import io.rpg.view.GameObjectView; @@ -41,10 +42,18 @@ public void onKeyboardEvent(KeyboardEvent event) { } } - public void teleportTo(LocationModel model, LocationView view) { + /** + * Changes player location. Removes listener from old location. + * + * @param model new location model. + * @param view new location view. + * @param playerPosition new player position. + */ + public void teleportTo(LocationModel model, LocationView view, Position playerPosition) { onChangeLocation.run(); updateOnChangeLocation(model, view); + player.setPosition(playerPosition); model.setPlayer(player); view.addChild(playerView); view.addKeyboardEventObserver(this); diff --git a/src/main/java/io/rpg/model/actions/LocationChangeAction.java b/src/main/java/io/rpg/model/actions/LocationChangeAction.java index 5bd8f0a4..08607743 100644 --- a/src/main/java/io/rpg/model/actions/LocationChangeAction.java +++ b/src/main/java/io/rpg/model/actions/LocationChangeAction.java @@ -8,7 +8,7 @@ public class LocationChangeAction implements Action { public final String destinationLocationTag; - private Position playerPosition; + public final Position playerPosition; public LocationChangeAction(String destinationLocationTag, Position playerPosition) { this.destinationLocationTag = destinationLocationTag; diff --git a/src/main/java/io/rpg/model/object/Player.java b/src/main/java/io/rpg/model/object/Player.java index 29a7b73e..4f5b8e6e 100644 --- a/src/main/java/io/rpg/model/object/Player.java +++ b/src/main/java/io/rpg/model/object/Player.java @@ -99,4 +99,8 @@ public void render() { gameObjectView.setY(this.pixelPosition.y); } } + + public void setPosition(Position position) { + pixelPosition = new Vector(position); + } }