From fea281c4a21947f3d092f17bea082974b647e5d4 Mon Sep 17 00:00:00 2001 From: zamojtel <56871145+zamojtel@users.noreply.github.com> Date: Sun, 5 Jun 2022 19:57:21 +0200 Subject: [PATCH] @zamojtel/in progress (#82) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: add equipment * chore: add simple equipment system for the player Collected collectibles are now displayed if we click on a non-collectible item * feat: Improve equipment system * add InventoryPopup * Update src/main/java/io/rpg/controller/PopupController.java Co-authored-by: Marcin Hawryluk <70582973+mhawryluk@users.noreply.github.com> * Update src/main/java/io/rpg/model/data/Inventory.java Co-authored-by: Marcin Hawryluk <70582973+mhawryluk@users.noreply.github.com> * Update src/main/java/io/rpg/model/object/CollectibleGameObject.java Co-authored-by: Marcin Hawryluk <70582973+mhawryluk@users.noreply.github.com> * Update src/main/java/io/rpg/view/InventoryPopup.java Co-authored-by: Marcin Hawryluk <70582973+mhawryluk@users.noreply.github.com> * Update src/main/java/io/rpg/viewmodel/InventoryPopupViewModel.java Co-authored-by: Marcin Hawryluk <70582973+mhawryluk@users.noreply.github.com> * Update src/main/java/io/rpg/view/InventoryGameObjectView.java Co-authored-by: Marcin Hawryluk <70582973+mhawryluk@users.noreply.github.com> * fix: make equipment work on current arch Co-authored-by: Marcin Hawryluk <70582973+mhawryluk@users.noreply.github.com> Co-authored-by: Kacper Kafara * add minor improvements (Proper)Gathering items is now available, collectibles are no longer visible on the ground after picking them up * fix: proper items are displayed in the equipment * chore: add battle logic implementation * chore: add BattlePopup * changes * fix: make things work KLEJONE GRUBÄ„ WARSTWÄ„ KLEJU Co-authored-by: Marcin Hawryluk <70582973+mhawryluk@users.noreply.github.com> Co-authored-by: Kacper Kafara --- assets/sword6.png | Bin 0 -> 1479 bytes .../location-1/objects/object-2.json | 10 + .../location-2/objects/object-6.json | 2 +- .../rpg/config/model/ActionConfigBundle.java | 5 + .../java/io/rpg/controller/Controller.java | 17 +- .../io/rpg/controller/PopupController.java | 34 ++++ .../io/rpg/model/actions/ActionEngine.java | 13 ++ .../java/io/rpg/model/actions/ActionType.java | 6 +- .../io/rpg/model/actions/CollectAction.java | 28 +++ .../java/io/rpg/model/data/Inventory.java | 20 ++ .../model/object/CollectibleGameObject.java | 15 ++ .../java/io/rpg/model/object/GameObject.java | 1 + .../model/object/InteractiveGameObject.java | 15 ++ src/main/java/io/rpg/model/object/Player.java | 11 ++ src/main/java/io/rpg/util/ActionFactory.java | 7 + .../java/io/rpg/util/GameObjectFactory.java | 1 + src/main/java/io/rpg/view/BattlePopup.java | 173 ++++++++++++++++++ src/main/java/io/rpg/view/GameObjectView.java | 9 +- .../io/rpg/view/InventoryGameObjectView.java | 15 ++ src/main/java/io/rpg/view/InventoryPopup.java | 97 ++++++++++ src/main/java/io/rpg/view/LocationView.java | 33 +++- .../io/rpg/view/popups/QuestionPopup.java | 2 + .../viewmodel/InventoryPopupViewModel.java | 42 +++++ 23 files changed, 548 insertions(+), 8 deletions(-) create mode 100644 assets/sword6.png create mode 100644 configurations/demo-config-1/locations/location-1/objects/object-2.json create mode 100644 src/main/java/io/rpg/model/actions/CollectAction.java create mode 100644 src/main/java/io/rpg/model/data/Inventory.java create mode 100644 src/main/java/io/rpg/model/object/CollectibleGameObject.java create mode 100644 src/main/java/io/rpg/model/object/InteractiveGameObject.java create mode 100644 src/main/java/io/rpg/view/BattlePopup.java create mode 100644 src/main/java/io/rpg/view/InventoryGameObjectView.java create mode 100644 src/main/java/io/rpg/view/InventoryPopup.java create mode 100644 src/main/java/io/rpg/viewmodel/InventoryPopupViewModel.java diff --git a/assets/sword6.png b/assets/sword6.png new file mode 100644 index 0000000000000000000000000000000000000000..7aa0e2dd2d76f2f15650154fa80fbe014bf94536 GIT binary patch literal 1479 zcmeAS@N?(olHy`uVBq!ia0vp^;y~=c!3-pi)yv!kQVPi)LB0$ORjLdO4b2P;KmP;i zmkbQ01`G_Z5*Qe)W&ri%Pl`Y4#=yYL5a1Ky3e=+`C14~cXr(A*tt8~FE9I*v9b>K- zXQ6bh)!skE&H}U^pCw_fB_uZqlUth2L z{CvZ&4-0<0JNEbUDWI97U^E1VL@(cbyvH?TzcXnX8!N6JI5n0T@ zz%2yAjF;}#{Q(L}l(rIsj|=o#plrnVZT0s~Rd)5S5w z!hh}LTHz)Io_6EY<$*@NuYcG3Nm*>WcrZ5Zq5bW{#r9h+p8RktN+-e7t~}y^P|dts zY^NLYcdg#YQ!D!Q`O5cMw-WYce$aejJ)d6<$gu4AVPkop{qKYO!vEebxUXLGRb1Xq z`=Nb_$^WfuoX^y+J8hxzXQJAlhvomWHriX>kJtUSwd)t#J^7j(miG6o^0P1GYq}NO zNYL3iSAUxQ&rcC26`ytF7e2AuE%8s8wQlYQX({E;w|?z$+_UlJhQ_teKV;u(u3q~6 zUh(fqzc+uMlkcqb^H|DH)x$;)QVVU9B|ofM^QbP=t+LQyzsHk!{h#rlj3XlI&Sp06 ujJg)~^#;egcg=^~KGaUQaiYdBHu>K7y@9jd_tstmWd%=HKbLh*2~7ZmIPOyb literal 0 HcmV?d00001 diff --git a/configurations/demo-config-1/locations/location-1/objects/object-2.json b/configurations/demo-config-1/locations/location-1/objects/object-2.json new file mode 100644 index 00000000..d9e6862d --- /dev/null +++ b/configurations/demo-config-1/locations/location-1/objects/object-2.json @@ -0,0 +1,10 @@ +{ + "tag": "object-2", + "position": { "row": 5, "col": 5 }, + "assetPath": "assets/key.png", + "onLeftClick": { + "tag": "dialogue-action", + "type": "collect", + "assetPath": "assets/coin.png" + } +} diff --git a/configurations/demo-config-1/locations/location-2/objects/object-6.json b/configurations/demo-config-1/locations/location-2/objects/object-6.json index 9922cc38..52c7ab12 100644 --- a/configurations/demo-config-1/locations/location-2/objects/object-6.json +++ b/configurations/demo-config-1/locations/location-2/objects/object-6.json @@ -8,4 +8,4 @@ ], "assetPath": "assets/goblin.png" } -} \ No newline at end of file +} diff --git a/src/main/java/io/rpg/config/model/ActionConfigBundle.java b/src/main/java/io/rpg/config/model/ActionConfigBundle.java index 40af11d4..b9583535 100644 --- a/src/main/java/io/rpg/config/model/ActionConfigBundle.java +++ b/src/main/java/io/rpg/config/model/ActionConfigBundle.java @@ -75,6 +75,7 @@ public class ActionConfigBundle implements ConfigWithValidation { /** * {@link io.rpg.model.actions.DialogueAction}
* {@link io.rpg.model.actions.ShowDescriptionAction}
+ * {@link io.rpg.model.actions.CollectAction}
* TODO */ @Nullable @@ -263,6 +264,10 @@ Result validateForBattle() { return Result.ok(); } + Result validateForCollectAction() { + return Result.ok(); + } + Result validateBasic() { ErrorMessageBuilder builder = new ErrorMessageBuilder(); if (tag == null) { diff --git a/src/main/java/io/rpg/controller/Controller.java b/src/main/java/io/rpg/controller/Controller.java index 059223b4..0594994b 100644 --- a/src/main/java/io/rpg/controller/Controller.java +++ b/src/main/java/io/rpg/controller/Controller.java @@ -7,18 +7,23 @@ import io.rpg.model.data.MouseClickedEvent; import io.rpg.model.data.Position; import io.rpg.model.location.LocationModel; +import io.rpg.model.object.CollectibleGameObject; import io.rpg.model.object.GameObject; import io.rpg.model.object.Player; import io.rpg.model.object.Question; import io.rpg.util.BattleResult; import io.rpg.view.GameEndView; import io.rpg.view.GameObjectView; +import io.rpg.view.InventoryPopup; import io.rpg.view.LocationView; import javafx.geometry.Point2D; import javafx.scene.Scene; +import javafx.scene.image.Image; import javafx.scene.input.KeyEvent; import javafx.scene.input.MouseButton; import javafx.stage.Stage; +import javafx.stage.StageStyle; +import io.rpg.view.popups.TextPopup; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.jetbrains.annotations.NotNull; @@ -41,10 +46,8 @@ public class Controller implements KeyboardEvent.Observer, MouseClickedEvent.Obs private final ConditionEngine conditionEngine; private final ActionEngine actionEngine; - public Controller() { logger = LogManager.getLogger(Controller.class); - tagToLocationModelMap = new LinkedHashMap<>(); tagToLocationViewMap = new LinkedHashMap<>(); @@ -158,6 +161,7 @@ public void onKeyboardEvent(KeyboardEvent event) { case Q -> popupController.openQuestionPopup(new Question("How many bits are there in one byte?", new String[]{"1/8", "1024", "8", "256"}, 'C'), getWindowCenterX(), getWindowCenterY()); case L -> consumeAction(new LocationChangeAction("location-2", new Position(1, 2), null)); case U -> consumeAction(new GameEndAction("You have pressed the forbidden button", null)); + case E -> popupController.openInventoryPopup(playerController.getPlayer().getInventory(), getWindowCenterX(), getWindowCenterY(), playerController.getPlayer()); } } } @@ -176,7 +180,7 @@ public void onMouseClickedEvent(MouseClickedEvent event) { GameObjectView objectView = event.source(); Position position = new Position(objectView.getPosition()); GameObject object = currentModel.getObject(position) - .orElseThrow(() -> new RuntimeException("No object present at position " + position)); + .orElseThrow(() -> new RuntimeException("No object present at position " + position)); double distance = playerPos.distance(objectView.getPosition()); @@ -192,6 +196,13 @@ public void onMouseClickedEvent(MouseClickedEvent event) { logger.info("Controller notified on click from " + event.source()); } + public void removeObjectFromModel(GameObject object) { + String tag = currentModel.getTag(); + LocationView currentLocationView = tagToLocationViewMap.get(tag); + currentLocationView.removeViewBoundToObject(object); + currentModel.removeGameObject(object); + } + public PlayerController getPlayerController() { return playerController; } diff --git a/src/main/java/io/rpg/controller/PopupController.java b/src/main/java/io/rpg/controller/PopupController.java index acea9da2..40795d3a 100644 --- a/src/main/java/io/rpg/controller/PopupController.java +++ b/src/main/java/io/rpg/controller/PopupController.java @@ -1,10 +1,15 @@ package io.rpg.controller; +import io.rpg.model.object.Player; import io.rpg.model.object.Question; +import io.rpg.view.BattlePopup; import io.rpg.view.popups.DialoguePopup; import io.rpg.view.popups.QuestionPopup; +import io.rpg.model.data.Inventory; +import io.rpg.view.InventoryPopup; import io.rpg.view.popups.TextImagePopup; import io.rpg.view.popups.TextPopup; +import javafx.event.EventHandler; import javafx.scene.image.Image; import javafx.stage.Stage; import javafx.stage.StageStyle; @@ -33,6 +38,7 @@ public void openTextPopup(String text, int x, int y) { popupStage.setX(x - popupScene.getWidth() / 2); popupStage.setY(y - popupScene.getHeight() / 2); }); + if (!popupStage.isShowing()) { popupStage.showAndWait(); } @@ -56,6 +62,34 @@ public void openPointsPopup(int pointsCount, int x, int y) { openTextImagePopup("You earned " + pointsCount + " points!", coinImage, x, y); } + public void openInventoryPopup(Inventory inventory, int x, int y, Player player) { +// InventoryPopup inventoryPopup=new InventoryPopup(); +// final Stage popupStage = new Stage(StageStyle.TRANSPARENT); + + InventoryPopup popupScene = new InventoryPopup(inventory,player); + popupStage.setScene(popupScene); + + popupStage.onShownProperty().setValue(event -> { + popupStage.setX(x - popupScene.getWidth() / 2); + popupStage.setY(y - popupScene.getHeight() / 2); + }); + + if (!popupStage.isShowing()) { + popupStage.showAndWait(); + } + } + + public void openBattlePopup(Player player,int x,int y){ + BattlePopup battlePopup = new BattlePopup(player); + this.popupStage.setScene(battlePopup); + popupStage.show(); + popupStage.setX(x - battlePopup.getWidth() / 2); + popupStage.setY(y - battlePopup.getHeight() / 2); + battlePopup.setCloseButtonActionListener((event)->{ + popupStage.close(); + }); + } + public void openQuestionPopup(Question question, int x, int y, Runnable successCallback, Runnable failureCallback) { QuestionPopup popupScene = new QuestionPopup(question); popupScene.setSuccessCallback(successCallback); diff --git a/src/main/java/io/rpg/model/actions/ActionEngine.java b/src/main/java/io/rpg/model/actions/ActionEngine.java index bc5d1e41..70670945 100644 --- a/src/main/java/io/rpg/model/actions/ActionEngine.java +++ b/src/main/java/io/rpg/model/actions/ActionEngine.java @@ -5,8 +5,10 @@ import io.rpg.model.object.GameObject; import io.rpg.model.object.Player; import io.rpg.util.BattleResult; +import io.rpg.view.InventoryGameObjectView; import io.rpg.view.LocationView; import javafx.application.Platform; +import javafx.scene.image.Image; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.jetbrains.annotations.NotNull; @@ -119,6 +121,17 @@ public void onAction(BattleAction action) { }); } + public void onAction(CollectAction action) { + actionGuard(action, () -> { + var controller = controller(); + controller.getPopupController().openTextImagePopup("Picked up an item!", new Image("file:" + action.getAssetPath()), + controller.getWindowCenterX(), controller.getWindowCenterY()); + controller.getPlayerController().getPlayer().getInventory() + .add(new InventoryGameObjectView(action.getOwner(), action.getAssetPath())); + controller.removeObjectFromModel(action.getOwner()); + }); + } + private void actionGuard(BaseAction action, Runnable actionLogic) { if (action.getCondition() != null && !action.getCondition().acceptEngine(controller().getConditionEngine())) { logger.info("Action not executed due to condition being not satisfied"); diff --git a/src/main/java/io/rpg/model/actions/ActionType.java b/src/main/java/io/rpg/model/actions/ActionType.java index e67e1023..b18b6989 100644 --- a/src/main/java/io/rpg/model/actions/ActionType.java +++ b/src/main/java/io/rpg/model/actions/ActionType.java @@ -21,7 +21,10 @@ public enum ActionType { Dialogue("dialogue"), @SerializedName("battle") - Battle("battle"); + Battle("battle"), + + @SerializedName("collect") + Collect("collect"); private final String asString; @@ -41,6 +44,7 @@ public static Optional fromString(String action) { case "show-description" -> { return Optional.of(ShowDescription); } case "dialogue" -> { return Optional.of(Dialogue); } case "battle" -> { return Optional.of(Battle); } + case "collect" -> { return Optional.of(Collect); } default -> { return Optional.empty(); } } } diff --git a/src/main/java/io/rpg/model/actions/CollectAction.java b/src/main/java/io/rpg/model/actions/CollectAction.java new file mode 100644 index 00000000..f6fd399f --- /dev/null +++ b/src/main/java/io/rpg/model/actions/CollectAction.java @@ -0,0 +1,28 @@ +package io.rpg.model.actions; + +import io.rpg.model.actions.condition.Condition; +import io.rpg.model.object.GameObject; +import org.jetbrains.annotations.Nullable; + +public class CollectAction extends BaseAction { + private final String assetPath; + + public CollectAction(String assetPath, @Nullable Condition condition) { + super(condition); + this.assetPath = assetPath; + } + + public GameObject getOwner() { + return getEmitter(); + } + + @Override + public void acceptActionEngine(ActionEngine engine) { + engine.onAction(this); + } + + public String getAssetPath() { + return assetPath; + } +} + diff --git a/src/main/java/io/rpg/model/data/Inventory.java b/src/main/java/io/rpg/model/data/Inventory.java new file mode 100644 index 00000000..60b93f3f --- /dev/null +++ b/src/main/java/io/rpg/model/data/Inventory.java @@ -0,0 +1,20 @@ +package io.rpg.model.data; + +import io.rpg.model.object.GameObject; +import io.rpg.view.InventoryGameObjectView; + +import java.util.ArrayList; +import java.util.List; + +public class Inventory { + + public List items; + + public Inventory() { + items = new ArrayList<>(); + } + + public void add(InventoryGameObjectView object) { + items.add(object); + } +} diff --git a/src/main/java/io/rpg/model/object/CollectibleGameObject.java b/src/main/java/io/rpg/model/object/CollectibleGameObject.java new file mode 100644 index 00000000..a63b5c5e --- /dev/null +++ b/src/main/java/io/rpg/model/object/CollectibleGameObject.java @@ -0,0 +1,15 @@ +package io.rpg.model.object; + +import io.rpg.model.data.Position; +import org.jetbrains.annotations.NotNull; + +public final class CollectibleGameObject extends InteractiveGameObject { + public CollectibleGameObject(@NotNull String tag, @NotNull Position position, String assetPath) { + super(tag, position, assetPath); + } + + @Override + public void onAction() { + System.out.println("Collectible object action"); + } +} diff --git a/src/main/java/io/rpg/model/object/GameObject.java b/src/main/java/io/rpg/model/object/GameObject.java index 02e0739d..c36a5df2 100644 --- a/src/main/java/io/rpg/model/object/GameObject.java +++ b/src/main/java/io/rpg/model/object/GameObject.java @@ -7,6 +7,7 @@ import io.rpg.model.data.Position; import io.rpg.util.DataObjectDescriptionProvider; import javafx.application.Platform; +import io.rpg.view.GameObjectView; import javafx.beans.property.SimpleObjectProperty; import javafx.beans.value.ObservableValue; import javafx.geometry.Point2D; diff --git a/src/main/java/io/rpg/model/object/InteractiveGameObject.java b/src/main/java/io/rpg/model/object/InteractiveGameObject.java new file mode 100644 index 00000000..4427fa5a --- /dev/null +++ b/src/main/java/io/rpg/model/object/InteractiveGameObject.java @@ -0,0 +1,15 @@ +package io.rpg.model.object; + +import io.rpg.model.data.Position; +import org.jetbrains.annotations.NotNull; + +public abstract class InteractiveGameObject extends GameObject { + public InteractiveGameObject(@NotNull String tag, @NotNull Position position, String assetPath) { + super(tag, position); + } + public InteractiveGameObject(@NotNull String tag, @NotNull Position position) { + super(tag, position); + } + + abstract public void onAction(); +} diff --git a/src/main/java/io/rpg/model/object/Player.java b/src/main/java/io/rpg/model/object/Player.java index 08323a3e..b0e0c587 100644 --- a/src/main/java/io/rpg/model/object/Player.java +++ b/src/main/java/io/rpg/model/object/Player.java @@ -1,5 +1,6 @@ package io.rpg.model.object; +import io.rpg.model.data.Inventory; import io.rpg.model.data.Position; import io.rpg.view.GameObjectView; import javafx.geometry.Point2D; @@ -20,6 +21,7 @@ public class Player extends GameObject { private boolean downPressed; private GameObjectView gameObjectView; private int points; + private final Inventory inventory; private final Set defeatedOpponents; @@ -33,6 +35,7 @@ public Player(@NotNull String tag, @NotNull Position position, @NotNull String a this.downPressed = false; this.strength = 0; this.defeatedOpponents = new LinkedHashSet<>(); + this.inventory = new Inventory(); } public void updateStrength(int value) { @@ -99,8 +102,16 @@ public void addPoints(int value) { points += value; } + public void removePoints(int value) { + points += value; + } + public int getStrength() { return strength; + } + + public Inventory getInventory() { + return inventory; } public void addDefeatedOpponent(@NotNull String tag) { diff --git a/src/main/java/io/rpg/util/ActionFactory.java b/src/main/java/io/rpg/util/ActionFactory.java index 2cc6bdc2..c982978e 100644 --- a/src/main/java/io/rpg/util/ActionFactory.java +++ b/src/main/java/io/rpg/util/ActionFactory.java @@ -46,6 +46,9 @@ private static Action actionByType(ActionConfigBundle config) { case Battle -> { return battleActionFromConfig(config); } + case Collect -> { + return collectActionFromConfig(config); + } default -> { throw new IllegalArgumentException("Unexpected action type!"); } @@ -92,4 +95,8 @@ private static void initBeforeAndAfterActions(Action action, ActionConfigBundle action.setAfterAction(actionByType(config.getAfterAction())); } } + + private static CollectAction collectActionFromConfig(ActionConfigBundle config) { + return new CollectAction(config.getAssetPath(), ConditionFactory.fromConfig(config.getCondition())); + } } diff --git a/src/main/java/io/rpg/util/GameObjectFactory.java b/src/main/java/io/rpg/util/GameObjectFactory.java index f2840a77..173134db 100644 --- a/src/main/java/io/rpg/util/GameObjectFactory.java +++ b/src/main/java/io/rpg/util/GameObjectFactory.java @@ -4,6 +4,7 @@ import io.rpg.config.model.PlayerConfig; import io.rpg.model.actions.Action; import io.rpg.model.actions.BattleAction; +import io.rpg.model.actions.CollectAction; import io.rpg.model.actions.ShowDescriptionAction; import io.rpg.model.object.GameObject; import io.rpg.model.object.Player; diff --git a/src/main/java/io/rpg/view/BattlePopup.java b/src/main/java/io/rpg/view/BattlePopup.java new file mode 100644 index 00000000..30a53b7e --- /dev/null +++ b/src/main/java/io/rpg/view/BattlePopup.java @@ -0,0 +1,173 @@ +package io.rpg.view; + +import io.rpg.model.object.Player; +import javafx.application.Platform; +import javafx.event.ActionEvent; +import javafx.event.EventHandler; +import javafx.scene.Group; +import javafx.scene.Scene; +import javafx.scene.control.Button; +import javafx.scene.control.ContentDisplay; +import javafx.scene.control.Label; +import javafx.scene.image.Image; +import javafx.scene.image.ImageView; +import javafx.scene.input.KeyCode; +import javafx.scene.paint.Color; + +import java.util.EventListener; +import java.util.Random; +import java.util.Timer; +import java.util.TimerTask; + +public class BattlePopup extends Scene { + + final int SPACING = 25; + final int POINTS_PER_SECOND = 50; + final int PENALTY=-10; + private char [] singleMove={'W','A','S','D'}; + private Random random; + private String sequence; + private int sequenceLength =5; + private Label[] characterLabels; + private ImageView[] timerDots; + private Label isOk; + private int currentSequencePosition; + private ImageView swordIcon; + private Timer timer; + private int timeToCountDown; + private Player player; + private Button button; + + + public BattlePopup(Player player){ + + super(new Group(), Color.TRANSPARENT); + this.player=player; + this.timer= new java.util.Timer(); + this.timeToCountDown=5; + this.random=new Random(); + this.timerDots=new ImageView[timeToCountDown]; + this.sequence=generateRandomSequence(sequenceLength); + this.button=new Button("OK"); + + + Group group = new Group(); + //TODO: load asset path from config + ImageView imageView = new ImageView(GameObjectView.resolvePathToJFXFormat("assets/popup-background.png")); + + this.swordIcon=new ImageView(GameObjectView.resolvePathToJFXFormat("assets/sword6.png")); + imageView.setX(0); + imageView.setY(0); + + this.characterLabels=new Label[sequenceLength]; + double centerX=getX()+getWidth()/2; + double centerY=getY()+getHeight()/2; + int singleLabelWidth=25; + double allLabelsWidth=sequenceLength*singleLabelWidth+(sequenceLength-1)*SPACING; + this.currentSequencePosition=0; +// this.isOk=new Label(); +// this.isOk.setLayoutX(200); +// this.isOk.setLayoutY(250); + ImageView imageViewButton=new ImageView(GameObjectView.resolvePathToJFXFormat("assets/button-image.png")); + button.setLayoutX(imageView.getImage().getWidth()/2-imageViewButton.getImage().getWidth()/2); + button.setLayoutY(imageView.getImage().getHeight()-imageViewButton.getImage().getHeight()/2); + button.setGraphic(imageViewButton); + button.setContentDisplay(ContentDisplay.CENTER); + button.setStyle("-fx-background-color: transparent;"); + group.getChildren().add(imageView); + group.getChildren().add(button); + for(int i=0;i<5;i++){ + timerDots[i] = new ImageView(GameObjectView.resolvePathToJFXFormat("assets/button-image.png")); + timerDots[i].setLayoutX(i*SPACING+i*singleLabelWidth+ imageView.getImage().getWidth()/2-allLabelsWidth/2); + timerDots[i].setLayoutY(centerY+ imageView.getImage().getHeight()/2+50); + timerDots[i].setScaleX(0.5); + timerDots[i].setScaleY(0.5); + group.getChildren().add(timerDots[i]); + } + group.getChildren().add(swordIcon); + + for(int i=0;i{ + String str=event.getCode().getChar(); + if(str.equals(String.valueOf(sequence.charAt(currentSequencePosition)))){ + this.characterLabels[currentSequencePosition].setStyle("-fx-font-family: Monospaced; -fx-text-fill: #2bee1e; -fx-font-weight: bold; -fx-font-size: " + 18); + currentSequencePosition++; + if(this.currentSequencePosition==sequenceLength){ + win(); + this.isOk.setText("OK"); + group.getChildren().add(this.isOk); + } + }else{ + this.characterLabels[currentSequencePosition].setStyle("-fx-font-family: Monospaced; -fx-text-fill: #fa2902; -fx-font-weight: bold; -fx-font-size: " + 18); + currentSequencePosition++; + } + }); + + timer.schedule(new TimerTask() { + public void run() { + Platform.runLater(new Runnable() { + public void run() { + timerTick(); + } + }); + } + },1000,1000); + button.setOnAction((event)->{ + + }); + } + + public String generateRandomSequence(int length){ + String str=""; + for(int i=0;i value){ + button.setOnAction(value); + } + +} diff --git a/src/main/java/io/rpg/view/GameObjectView.java b/src/main/java/io/rpg/view/GameObjectView.java index 5aad20e4..b76bb74e 100644 --- a/src/main/java/io/rpg/view/GameObjectView.java +++ b/src/main/java/io/rpg/view/GameObjectView.java @@ -20,6 +20,7 @@ public class GameObjectView extends ImageView private Path path; private final Set onClickedObservers; private final SimpleObjectProperty position; + GameObject boundObject; public GameObjectView(@NotNull Path assetPath, @NotNull Position position) { @@ -36,7 +37,6 @@ private void setLayoutUpdateOnPositionChange() { if (Objects.equals(oldValue, newValue)) { return; } - ImageViewHelper.geomChanged(this); }); } @@ -53,7 +53,8 @@ public void emitOnMouseClickedEvent(MouseClickedEvent event) { } public void bindToGameObject(GameObject gameObject) { - this.position.bind(gameObject.getExactPositionProperty()); + this.position.bind(gameObject.getExactPositionProperty()); + this.boundObject = gameObject; } public Point2D getPosition() { @@ -75,4 +76,8 @@ public void onGameObjectStateChange(GameObjectStateChange event) { // TODO: implement update logic here or create view model class but it // is even more boilerplate } + + public GameObject getBoundObject() { + return boundObject; + } } diff --git a/src/main/java/io/rpg/view/InventoryGameObjectView.java b/src/main/java/io/rpg/view/InventoryGameObjectView.java new file mode 100644 index 00000000..aa803bf7 --- /dev/null +++ b/src/main/java/io/rpg/view/InventoryGameObjectView.java @@ -0,0 +1,15 @@ +package io.rpg.view; + +import io.rpg.model.object.GameObject; +import javafx.scene.image.Image; +import javafx.scene.image.ImageView; + +public class InventoryGameObjectView extends ImageView { + GameObject collectibleGameObject; + + public InventoryGameObjectView(GameObject collectibleGameObject, String assetPath) { + this.collectibleGameObject = collectibleGameObject; + Image image = new Image(GameObjectView.resolvePathToJFXFormat(assetPath)); + setImage(image); + } +} diff --git a/src/main/java/io/rpg/view/InventoryPopup.java b/src/main/java/io/rpg/view/InventoryPopup.java new file mode 100644 index 00000000..7465c47c --- /dev/null +++ b/src/main/java/io/rpg/view/InventoryPopup.java @@ -0,0 +1,97 @@ +package io.rpg.view; + +import io.rpg.model.data.Inventory; +import io.rpg.model.data.Position; +import io.rpg.model.object.Player; +import io.rpg.viewmodel.InventoryPopupViewModel; +import io.rpg.viewmodel.TextPopupViewModel; +import javafx.event.EventHandler; +import javafx.fxml.FXML; +import javafx.fxml.FXMLLoader; +import javafx.scene.Group; +import javafx.scene.Parent; +import javafx.scene.Scene; +import javafx.scene.control.Label; +import javafx.scene.image.Image; +import javafx.scene.image.ImageView; +import javafx.scene.input.MouseEvent; +import javafx.scene.paint.Color; +import javafx.scene.shape.Rectangle; + +import java.io.IOException; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +public class InventoryPopup extends Scene { + final int PADDING_LEFT = 25; + final int PADDING_TOP = 20; + @FXML + private Label label; + + @FXML + private Label strengthLabel; + + @FXML + private Label pointsLabel; + + public InventoryPopup(Inventory inventory, Player player) { + + super(new Group(), Color.TRANSPARENT); + Group group = new Group(); + //TODO: load asset path from config + ImageView imageView = new ImageView(GameObjectView.resolvePathToJFXFormat("assets/popup-background.png")); + imageView.setX(0); + imageView.setY(0); + this.pointsLabel = new Label(); + this.pointsLabel.setText("Points :" + String.valueOf(player.getPoints())); + this.pointsLabel.setLayoutX(325); + this.pointsLabel.setLayoutY(150); + this.pointsLabel.setStyle("-fx-font-family: Monospaced; -fx-text-fill: white; -fx-font-weight: bold; -fx-font-size: " + 18); + this.strengthLabel=new Label(); + this.strengthLabel.setStyle("-fx-font-family: Monospaced; -fx-text-fill: white; -fx-font-weight: bold; -fx-font-size: " + 18); + this.strengthLabel.setText("Strength :"+String.valueOf(player.getStrength())); + this.strengthLabel.setLayoutX(325); + this.strengthLabel.setLayoutY(200); + label = new Label(); + label.setLayoutX(300); + label.setLayoutY(100); + label.setStyle("-fx-font-family: Monospaced; -fx-text-fill: white; -fx-font-weight: bold; -fx-font-size: " + 18); + group.getChildren().add(imageView); + group.getChildren().add(label); + group.getChildren().add(pointsLabel); + group.getChildren().add(strengthLabel); + + for (int i = 0; i < inventory.items.size(); i++) { +// String assetPath=inventory.items.get(i).getAssetPath(); +// to display objects in the menu +// wrapperClass to store information about object which we display + InventoryGameObjectView imageGameObjectView = inventory.items.get(i); + + imageGameObjectView.setX(i * 50 + PADDING_LEFT); + imageGameObjectView.setY(0 + PADDING_TOP); + imageGameObjectView.setOnMouseEntered(event -> { + InventoryGameObjectView src = (InventoryGameObjectView) event.getSource(); +// System.out.println("over the item "+src.collectibleGameObject.getAssetPath()); + label.setText("mock description"); + }); + + imageGameObjectView.setOnMouseExited(event -> { + label.setText(""); + }); + + imageGameObjectView.setOnMouseClicked(event -> { + + System.out.println("Object clicked"); + InventoryGameObjectView src = (InventoryGameObjectView) event.getSource(); + System.out.println(); + }); + group.getChildren().add(imageGameObjectView); + + } + this.setRoot(group); + this.setFill(Color.TRANSPARENT); + } + +} diff --git a/src/main/java/io/rpg/view/LocationView.java b/src/main/java/io/rpg/view/LocationView.java index 7a343efe..fee4ccfa 100644 --- a/src/main/java/io/rpg/view/LocationView.java +++ b/src/main/java/io/rpg/view/LocationView.java @@ -1,12 +1,15 @@ package io.rpg.view; +import io.rpg.Game; import io.rpg.model.data.KeyboardEvent; import io.rpg.model.data.LocationModelStateChange; import io.rpg.model.location.LocationModel; +import io.rpg.model.object.CollectibleGameObject; import io.rpg.model.object.GameObject; import io.rpg.viewmodel.LocationViewModel; import io.rpg.config.model.LocationConfig; import javafx.fxml.FXMLLoader; +import javafx.scene.Node; import javafx.scene.Parent; import javafx.scene.Scene; import javafx.scene.image.Image; @@ -101,7 +104,6 @@ public void onLocationModelStateChange(LocationModelStateChange event) { List gameObjectViews = new ArrayList<>(); - public void removeChild(GameObjectView view) { viewModel.getForegroundPane().getChildren().remove(view); } @@ -109,4 +111,33 @@ public void removeChild(GameObjectView view) { public void addChild(GameObjectView view) { viewModel.getForegroundPane().getChildren().add(view); } + + public GameObjectView findViewBoundToObject(GameObject gameObject){ + for(Node node : viewModel.getForegroundPane().getChildren()) { + if (node instanceof GameObjectView) { + GameObjectView temp = (GameObjectView) node; + if (temp.getBoundObject() == gameObject) { + return temp; + } + } + } + return null; + } + + public void removeViewBoundToObject(GameObject gameObject){ + GameObjectView view = findViewBoundToObject(gameObject); + if(view != null) { + removeChild(view); + } +// for(Node node : viewModel.getForegroundPane().getChildren()){ +// if(node instanceof GameObjectView){ +// GameObjectView temp = (GameObjectView) node; +// if(temp.getBoundObject() == gameObject){ +// removeChild(temp); +// break; +// } +// } +// } + } + } diff --git a/src/main/java/io/rpg/view/popups/QuestionPopup.java b/src/main/java/io/rpg/view/popups/QuestionPopup.java index b8a3b042..d9ab50a6 100644 --- a/src/main/java/io/rpg/view/popups/QuestionPopup.java +++ b/src/main/java/io/rpg/view/popups/QuestionPopup.java @@ -53,9 +53,11 @@ public static void setBackgroundPath(String backgroundPath) { QuestionPopup.backgroundPath = backgroundPath; } + //TODO check this method,it does not add the points correctly public void answerSelected(char answer) { char correctAnswer = question.getCorrectAnswerChar(); if (answer == correctAnswer){ +// this.successCallback.run(); viewModel.setQuestionLabel("Correct!"); viewModel.setAllButtonsCallback(event -> this.successCallback.run()); this.setOnMouseClicked(event -> this.successCallback.run()); diff --git a/src/main/java/io/rpg/viewmodel/InventoryPopupViewModel.java b/src/main/java/io/rpg/viewmodel/InventoryPopupViewModel.java new file mode 100644 index 00000000..89953c95 --- /dev/null +++ b/src/main/java/io/rpg/viewmodel/InventoryPopupViewModel.java @@ -0,0 +1,42 @@ +package io.rpg.viewmodel; + +import javafx.event.EventHandler; +import javafx.fxml.FXML; +import javafx.scene.control.Button; +import javafx.scene.control.Label; +import javafx.scene.image.Image; +import javafx.scene.image.ImageView; +import javafx.scene.input.MouseEvent; +import javafx.scene.layout.Pane; + +public class InventoryPopupViewModel { + @FXML private Label label; + @FXML private Pane backgroundPane; + @FXML private ImageView backgroundImage; + @FXML private Button okButton; + + public void setText(String text) { + if (text.length() < 50) setTextSize(25); + else if (text.length() < 190) setTextSize(19); + else setTextSize(13); + label.setText(text); + } + + public void setTextSize(int size) { + label.setStyle("-fx-font-family: Monospaced; -fx-text-fill: white; -fx-font-weight: bold; -fx-font-size: " + size); + } + + public void setBackgroundImage(String url) { + Image image = new Image(url); + backgroundImage.setImage(image); + } + + public void setOkButtonImage(String url) { + ImageView imageView = new ImageView(url); + okButton.setGraphic(imageView); + } + + public void setButtonOnClick(EventHandler callback) { + okButton.setOnMouseClicked(callback); + } +}