diff --git a/build.gradle b/build.gradle index 564b133..3bb5a0b 100644 --- a/build.gradle +++ b/build.gradle @@ -34,10 +34,11 @@ javafx { } dependencies { + implementation group: 'com.google.code.gson', name: 'gson', version: '2.8.7' + implementation 'junit:junit:4.13.2' + testImplementation("org.junit.jupiter:junit-jupiter-api:${junitVersion}") testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:${junitVersion}") - - implementation group: 'com.google.code.gson', name: 'gson', version: '2.8.7' } test { diff --git a/src/main/java/fr/sae/terraria/Terraria.java b/src/main/java/fr/sae/terraria/Terraria.java index c6e2d52..7457810 100644 --- a/src/main/java/fr/sae/terraria/Terraria.java +++ b/src/main/java/fr/sae/terraria/Terraria.java @@ -21,7 +21,7 @@ public class Terraria extends Application { - // Constants + // Constantes public static final String SRC_PATH = "src/main/resources/fr/sae/terraria/"; public static final double TARGET_FPS = .017; public static final int DISPLAY_RENDERING_WIDTH = 465; @@ -47,7 +47,7 @@ private FXMLLoader loadFXML(String path) public void start(Stage stage) throws IOException { GameController gameController = new GameController(stage); - MenuController menuController = new MenuController(stage); + MenuController menuController = new MenuController(); FXMLLoader fxmlLoader = this.loadFXML("vue/game.fxml"); fxmlLoader.setController(gameController); @@ -77,29 +77,31 @@ public void start(Stage stage) throws IOException stage.addEventFilter(KeyEvent.KEY_RELEASED, key -> timePressedKey[0] = 1); stage.sizeToScene(); - // Sync les changements du joueur entre les contrôleurs. + // Synchronise les changements du joueur entre les contrôleurs. stage.sceneProperty().addListener(((obs, oldScene, newScene) -> { if (switchScene.get()) { if (!Objects.isNull(menuController.player)) { gameController.player = menuController.player; - menuController.loop.stop(); gameController.environment.getLoop().play(); } } else { if (!Objects.isNull(gameController.player)) { menuController.player = gameController.player; - menuController.loop.play(); + menuController.environment = gameController.environment; gameController.environment.getLoop().stop(); } } })); stage.widthProperty().addListener((obs, oldV, newV) -> { gameController.scaleMultiplicatorWidth = (newV.intValue() / Terraria.DISPLAY_RENDERING_WIDTH); - menuController.scaleMultiplicatorWidth = (newV.intValue() / Terraria.DISPLAY_RENDERING_WIDTH); }); stage.heightProperty().addListener((obs, oldV, newV) -> { gameController.scaleMultiplicatorHeight = ((newV.intValue()-gameController.title.getPrefHeight()) / Terraria.DISPLAY_RENDERING_HEIGHT); - menuController.scaleMultiplicatorHeight = ((newV.intValue()-gameController.title.getPrefHeight()) / Terraria.DISPLAY_RENDERING_HEIGHT); + }); + gameController.environment.getPlayer().pvProperty().addListener((obs, oldV, newV) ->{ + if (newV.longValue() == 0){ + stage.close(); + } }); stage.show(); diff --git a/src/main/java/fr/sae/terraria/controller/GameController.java b/src/main/java/fr/sae/terraria/controller/GameController.java index 024d8e4..db53065 100644 --- a/src/main/java/fr/sae/terraria/controller/GameController.java +++ b/src/main/java/fr/sae/terraria/controller/GameController.java @@ -2,8 +2,9 @@ import fr.sae.terraria.Terraria; import fr.sae.terraria.modele.Environment; +import fr.sae.terraria.modele.GenerateEntity; import fr.sae.terraria.modele.TileMaps; -import fr.sae.terraria.modele.entities.entity.*; +import fr.sae.terraria.modele.entities.entity.ConsumableObjectType; import fr.sae.terraria.modele.entities.player.Player; import fr.sae.terraria.modele.entities.player.inventory.Inventory; import fr.sae.terraria.vue.Camera; @@ -20,7 +21,6 @@ import javafx.stage.Stage; import java.net.URL; -import java.util.Objects; import java.util.ResourceBundle; @@ -86,6 +86,9 @@ private void addKeysEventListener(final Stage stage) this.environment.getGameClock().setMinutes(1_000); if (key.isShiftDown() && key.isControlDown() && key.getCode().equals(KeyCode.J)) this.environment.getGameClock().setMinutes(400); + // Fait apparaitre un slime + if (key.isShiftDown() && key.isControlDown() && key.getCode().equals(KeyCode.P)) + GenerateEntity.slime(this.environment); key.consume(); }); @@ -98,28 +101,15 @@ private void addKeysEventListener(final Stage stage) stage.addEventFilter(MouseEvent.MOUSE_CLICKED, mouse -> { this.player.getMouseInput().put(mouse.getButton(), true); - mouse.consume(); - }); - - stage.addEventFilter(MouseEvent.MOUSE_RELEASED, mouse -> { - this.player.getMouseInput().put(mouse.getButton(), false); - mouse.consume(); - }); - stage.addEventFilter(ScrollEvent.SCROLL, scroll -> { - inventory.setScroll((int) scroll.getDeltaY()); - scroll.consume(); - }); - - stage.addEventFilter(MouseEvent.MOUSE_CLICKED, click -> { final double scaleMultiplicativeWidth = (this.root.getPrefWidth() / Terraria.DISPLAY_RENDERING_WIDTH); final double scaleMultiplicativeHeight = ((this.root.getPrefHeight()-this.title.getPrefHeight()) / Terraria.DISPLAY_RENDERING_HEIGHT); final int tileWidth = (int) (TileMaps.TILE_DEFAULT_SIZE * scaleMultiplicativeWidth); final int tileHeight = (int) (TileMaps.TILE_DEFAULT_SIZE * scaleMultiplicativeHeight); // La position correcte sur le Pane - double mouseX = click.getSceneX()+((Rectangle) this.displayTiledMap.getParent().getClip()).getX(); - double mouseY = (click.getSceneY()-this.title.getPrefHeight())+((Rectangle) this.displayTiledMap.getParent().getClip()).getY(); - // Le bloc où la souris à clicker + double mouseX = mouse.getSceneX()+((Rectangle) this.displayTiledMap.getParent().getClip()).getX(); + double mouseY = (mouse.getSceneY()-this.title.getPrefHeight())+((Rectangle) this.displayTiledMap.getParent().getClip()).getY(); + // Le bloc où la souris à clickée int xBlock = (int) (mouseX/tileWidth); int yBlock = (int) (mouseY/tileHeight); Rectangle2D rectangle = new Rectangle2D(mouseX, mouseY, scaleMultiplicativeWidth, scaleMultiplicativeHeight); @@ -131,42 +121,26 @@ private void addKeysEventListener(final Stage stage) int distanceBetweenBlockPlayerAxisY = Math.abs(yPlayer - yBlock); boolean isOneBlockDistance = distanceBetweenBlockPlayerAxisY >= 0 && distanceBetweenBlockPlayerAxisY <= Player.BREAK_BLOCK_DISTANCE && distanceBetweenBlockPlayerAxisX >= 0 && distanceBetweenBlockPlayerAxisX <= Player.BREAK_BLOCK_DISTANCE; - if (this.player.getStackSelected() instanceof EatableObjectType) { - ((EatableObjectType) this.player.getStackSelected()).eat(); + if (this.player.getStackSelected() != null && this.player.getStackSelected().getItem() instanceof ConsumableObjectType) { + ((ConsumableObjectType) this.player.getStackSelected().getItem()).consumes(); } else if (isOneBlockDistance) { - if (click.getButton().equals(MouseButton.PRIMARY)) - this.breakBlock(rectangle); - if (click.getButton().equals(MouseButton.SECONDARY)) - this.placeBlock(xBlock, yBlock); + if (mouse.getButton().equals(MouseButton.PRIMARY)) + this.player.interactWithBlock(rectangle); + if (mouse.getButton().equals(MouseButton.SECONDARY)) + this.player.placeBlock(xBlock, yBlock); } - }); - } - private void breakBlock(final Rectangle2D rectangle) - { - // Commence a cherché l'entité ciblée - for (Entity entity : this.environment.getEntities()) if (entity.getRect().collideRect(rectangle)) { - if (entity instanceof BreakableObjectType) - ((BreakableObjectType) entity).breaks(); - if (entity instanceof CollapsibleObjectType) // TODO TEMP, à déplacer - ((CollapsibleObjectType) entity).hit(); - - // Quand tous c'est bien déroulés, aprés avoir trouvé l'entité et l'objet sur l'écran, il arrête de chercher d'autre entité d'où le break - break; - } - } - - private void placeBlock(int xBlock, int yBlock) - { - boolean haveAnItemOnHand = !Objects.isNull(this.player.getStackSelected()); - boolean goodPlace = this.environment.getTileMaps().getTile(xBlock, yBlock) == TileMaps.SKY; + mouse.consume(); + }); - if (haveAnItemOnHand && goodPlace) { - if (!(this.player.getStackSelected().getItem() instanceof PlaceableObjectType) && !(this.player.getStackSelected() instanceof EatableObjectType)) - return; + stage.addEventFilter(MouseEvent.MOUSE_RELEASED, mouse -> { + this.player.getMouseInput().put(mouse.getButton(), false); + mouse.consume(); + }); - if (this.player.getStackSelected().getItem() instanceof PlaceableObjectType) - ((PlaceableObjectType) this.player.getStackSelected().getItem()).place(xBlock, yBlock); - } + stage.addEventFilter(ScrollEvent.SCROLL, scroll -> { + inventory.setScroll((int) scroll.getDeltaY()); + scroll.consume(); + }); } } \ No newline at end of file diff --git a/src/main/java/fr/sae/terraria/controller/MenuController.java b/src/main/java/fr/sae/terraria/controller/MenuController.java index e8c3855..5d523b4 100644 --- a/src/main/java/fr/sae/terraria/controller/MenuController.java +++ b/src/main/java/fr/sae/terraria/controller/MenuController.java @@ -1,57 +1,95 @@ package fr.sae.terraria.controller; -import fr.sae.terraria.Terraria; +import fr.sae.terraria.modele.Environment; import fr.sae.terraria.modele.entities.player.Player; -import javafx.animation.Animation; -import javafx.animation.KeyFrame; -import javafx.animation.Timeline; +import fr.sae.terraria.modele.entities.player.craft.Craft; +import fr.sae.terraria.modele.entities.tools.MaterialSet; +import javafx.event.Event; import javafx.fxml.FXML; import javafx.fxml.Initializable; import javafx.scene.layout.HBox; -import javafx.scene.layout.Pane; -import javafx.stage.Stage; -import javafx.util.Duration; import java.net.URL; -import java.util.Objects; import java.util.ResourceBundle; public class MenuController implements Initializable { - @FXML public Pane root; - @FXML public Pane displayInventory; - @FXML public Pane displayLexique; - @FXML public HBox HBoxText; + @FXML public HBox recipeRock; + @FXML public HBox recipeTorch; - public Timeline loop; - private Stage stage; - public Player player = null; - public double scaleMultiplicatorWidth; - public double scaleMultiplicatorHeight; + @FXML public HBox recipeWoodPickaxe; + @FXML public HBox recipeStonePickaxe; + @FXML public HBox recipeIronPickaxe; + @FXML public HBox recipeWoodAxe; + @FXML public HBox recipeStoneAxe; + @FXML public HBox recipeIronAxe; + + @FXML public HBox recipeWoodSword; + @FXML public HBox recipeStoneSword; + @FXML public HBox recipeIronSword; + + public Environment environment = null; + public Player player = null; - public MenuController(final Stage stage) - { - super(); - this.stage = stage; - } @Override public void initialize(URL location, ResourceBundle resources) { - this.scaleMultiplicatorWidth = (this.root.getPrefWidth() / Terraria.DISPLAY_RENDERING_WIDTH); - this.scaleMultiplicatorHeight = ((this.root.getPrefHeight()-this.HBoxText.getPrefHeight()) / Terraria.DISPLAY_RENDERING_HEIGHT); + // Craft de la roche à partir de 3 pierres + this.recipeRock.addEventFilter(Event.ANY, event -> { + if (event.getEventType().getName().equalsIgnoreCase("MOUSE_PRESSED")) + this.player.pickup(Craft.rock(this.environment)); + }); + + this.recipeTorch.addEventFilter(Event.ANY, event -> { + if (event.getEventType().getName().equalsIgnoreCase("MOUSE_PRESSED")) + this.player.pickup(Craft.torch(this.environment)); + }); + + + // LES PIOCHES + this.recipeWoodPickaxe.addEventFilter(Event.ANY, event -> { + if (event.getEventType().getName().equalsIgnoreCase("MOUSE_PRESSED")) + this.player.pickup(Craft.pickaxe(this.environment, MaterialSet.WOOD)); + }); + + this.recipeStonePickaxe.addEventFilter(Event.ANY, event -> { + if (event.getEventType().getName().equalsIgnoreCase("MOUSE_PRESSED")) + this.player.pickup(Craft.pickaxe(this.environment, MaterialSet.STONE)); + }); + + this.recipeIronPickaxe.addEventFilter(Event.ANY, event -> { + if (event.getEventType().getName().equalsIgnoreCase("MOUSE_PRESSED")) + this.player.pickup(Craft.pickaxe(this.environment, MaterialSet.IRON)); + }); + + + // LES HACHES + this.recipeWoodAxe.addEventFilter(Event.ANY, event -> { + + }); + + this.recipeStoneAxe.addEventFilter(Event.ANY, event -> { + + }); + + this.recipeIronAxe.addEventFilter(Event.ANY, event -> { + + }); + + + // LES EPEES + this.recipeWoodSword.addEventFilter(Event.ANY, event -> { + + }); + + this.recipeStoneSword.addEventFilter(Event.ANY, event -> { - this.loop = new Timeline(); - this.loop.setCycleCount(Animation.INDEFINITE); + }); - KeyFrame keyFrame = new KeyFrame(Duration.seconds(Terraria.TARGET_FPS), (ev -> { - if (!Objects.isNull(this.player)) { - System.out.println(this.player.getInventory()); - } - })); + this.recipeIronSword.addEventFilter(Event.ANY, event -> { - this.loop.getKeyFrames().add(keyFrame); - this.loop.play(); + }); } } diff --git a/src/main/java/fr/sae/terraria/modele/Clock.java b/src/main/java/fr/sae/terraria/modele/Clock.java index a15c226..6849256 100644 --- a/src/main/java/fr/sae/terraria/modele/Clock.java +++ b/src/main/java/fr/sae/terraria/modele/Clock.java @@ -1,5 +1,6 @@ package fr.sae.terraria.modele; +import javafx.beans.property.SimpleDoubleProperty; import javafx.beans.property.SimpleIntegerProperty; @@ -11,12 +12,13 @@ public class Clock private final SimpleIntegerProperty minutes; private final SimpleIntegerProperty days; + private final SimpleDoubleProperty opacityNightFilter; public Clock() { super(); - + opacityNightFilter = new SimpleDoubleProperty(.0); this.minutes = new SimpleIntegerProperty(Clock.EIGHT_AM_INGAME); this.days = new SimpleIntegerProperty(1); } @@ -29,15 +31,30 @@ public void updates(int ticks) this.days.setValue(getDays()+1); this.minutes.setValue(0); } else this.minutes.setValue(getMinutes()+1); + updateOpacity(); } } public SimpleIntegerProperty minutesProperty() { return this.minutes; } public SimpleIntegerProperty daysProperty() { return this.days; } + private void updateOpacity() + { + if (this.getMinutes() > Clock.MINUTES_IN_A_DAY/2) + this.opacityNightFilter.set(((this.getMinutes()*(2. /* Compensation temps */))/Clock.MINUTES_IN_A_DAY) - (1.1 /* Décallage */)); + else this.opacityNightFilter.set(((Clock.MINUTES_IN_A_DAY - (this.getMinutes()*(4. /* Compensation temps */)))/Clock.MINUTES_IN_A_DAY) - (.1 /* Décallage */)); + } public int getMinutes() { return this.minutes.get(); } public int getDays() { return this.days.get(); } + public double getOpacityNightFilter() { + return opacityNightFilter.get(); + } + + public SimpleDoubleProperty opacityNightFilterProperty() { + return opacityNightFilter; + } + public void setMinutes(int newMinutes) { this.minutes.set(newMinutes); } } diff --git a/src/main/java/fr/sae/terraria/modele/Environment.java b/src/main/java/fr/sae/terraria/modele/Environment.java index 1943e2d..f9a1282 100644 --- a/src/main/java/fr/sae/terraria/modele/Environment.java +++ b/src/main/java/fr/sae/terraria/modele/Environment.java @@ -3,13 +3,15 @@ import fr.sae.terraria.Terraria; import fr.sae.terraria.modele.entities.Rabbit; import fr.sae.terraria.modele.entities.Slime; -import fr.sae.terraria.modele.entities.blocks.Torch; -import fr.sae.terraria.modele.entities.entity.CollideObjectType; +import fr.sae.terraria.modele.entities.blocks.Block; +import fr.sae.terraria.modele.entities.blocks.Tree; import fr.sae.terraria.modele.entities.entity.Entity; import fr.sae.terraria.modele.entities.entity.ReproductiveObjectType; -import fr.sae.terraria.modele.entities.items.Meat; +import fr.sae.terraria.modele.entities.items.Vodka; import fr.sae.terraria.modele.entities.player.Player; -import fr.sae.terraria.modele.entities.tools.Pickaxe; +import fr.sae.terraria.modele.entities.tools.MaterialSet; +import fr.sae.terraria.modele.entities.tools.Tool; +import fr.sae.terraria.modele.entities.tools.ToolSet; import javafx.animation.Animation; import javafx.animation.KeyFrame; import javafx.animation.Timeline; @@ -29,13 +31,15 @@ public class Environment { - // Permet d'update toutes les entités en une seule boucle. + private final ObservableList trees; + private final ObservableList blocks; + // Permet d'update toutes les entités avec une seule boucle. private final ObservableList entities; - // Range des entities en plus pour permettre facilement de savoir combien son t-il sur la carte pour limiter leur apparition + // Range des entitiés en plus pour avoir le nombre d'entités sur la carte et limiter leurs apparitions private final ObservableList rabbits; private final ObservableList slimes; - // Permet update facilement les lumières des torches sur le filtre - private final ObservableList torches; + // Permet d'update facilement les lumières des torches sur le filtre + private final ObservableList torches; private final TileMaps tileMaps; private final Player player; @@ -71,24 +75,26 @@ public Environment(double scaleMultiplicatorWidth, double scaleMultiplicatorHeig this.rabbits = FXCollections.observableArrayList(); this.slimes = FXCollections.observableArrayList(); this.torches = FXCollections.observableArrayList(); + this.blocks = FXCollections.observableArrayList(); + this.trees = FXCollections.observableArrayList(); + // Fait apparaitre le joueur. this.player = new Player(this); this.player.setVelocity(5); this.player.setPv(4); this.player.spawn(5*widthTile, 3*heightTile); - // Détecte si le joueur n'est pas dans un bloc lorsque qu'il met un block au sol - this.entities.addListener((ListChangeListener) c -> { + // Détecte si le joueur n'est pas dans un bloc lorsqu'il met un block au sol + this.blocks.addListener((ListChangeListener) c -> { while (c.next()) if (c.wasAdded()) { - Entity entity = c.getList().get(0); - - if (!Objects.isNull(entity.getRect())) { + Block block = c.getAddedSubList().get(0); + if (!Objects.isNull(block.getRect())) { // Si on le pose sur le joueur - boolean isIntoABlock = player.getRect().collideRect(entity.getRect()); - - if (entity instanceof CollideObjectType && isIntoABlock) { + boolean isIntoABlock = player.getRect().collideRect(block.getRect()); + boolean isCollideBlock = Block.isDirt(block) || Block.isRock(block) || Block.isFloorLeft(block) || Block.isFloorRight(block) || Block.isFloorTop(block); + if (isCollideBlock && isIntoABlock) { // Place le joueur au-dessus du block posé. - player.setY(entity.getY() - player.getRect().getHeight()); + player.setY(block.getY() - player.getRect().getHeight()); player.getGravity().yInit = player.getY(); player.getGravity().xInit = player.getX(); } @@ -113,18 +119,19 @@ private void gameLoop() KeyFrame keyFrame = new KeyFrame(Duration.seconds(Terraria.TARGET_FPS), (ev -> { // TODO TEST if (!caught[0]) { - Torch torch = new Torch(this, 0, 0); - this.player.pickup(torch); - Meat meat = new Meat(this); - this.player.pickup(meat); + this.player.pickup(new Tool(ToolSet.PICKAXE, MaterialSet.IRON)); + this.player.pickup(new Vodka(this)); + this.player.pickup(new Tool(ToolSet.SWORD, MaterialSet.IRON)); - this.player.pickup(new Pickaxe()); caught[0] = true; } // Ajoute les entités ReproductiveObjectType - for (Entity entity : entitiesAtAdded) - this.entities.add(0, entity); + for (Entity entity : entitiesAtAdded) { + this.entities.add(entity); + if (entity instanceof Block) + this.blocks.add((Block) entity); + } entitiesAtAdded.clear(); // Génère aléatoirement des entités @@ -132,13 +139,13 @@ private void gameLoop() boolean nightTime = this.clock.getMinutes() > (Clock.MINUTES_IN_A_DAY)/2; boolean weHaveChangedDay = this.previousDays != this.clock.getDays(); if (weHaveChangedDay) - for (int i = 0; i < 3; i++) // Génère par jour, 3 arbres - GenerateEntity.tree(this); + for (int i = 0; i < 15; i++) // Génère par jour, 3 arbres + GenerateEntity.treeRandomly(this); if (dayTime) { // Génère certaines entités uniquement pendant le jour - GenerateEntity.rabbit(this); - GenerateEntity.tallGrass(this); - } else if (nightTime) // Génère certaines entités uniquement pendant le soir - GenerateEntity.slime(this); + GenerateEntity.rabbitRandomly(this); + GenerateEntity.tallGrassRandomly(this); + } else if (nightTime) // Génère certaines entités uniquement pendant le soir et la nuit + GenerateEntity.slimeRandomly(this); // Updates toutes les entités for (Entity entity : this.entities) { @@ -168,7 +175,7 @@ public static Clip playSound(String path, boolean loop) } catch (Exception e) { e.printStackTrace(); } if (!Objects.isNull(clip)) { - clip.loop((loop) ? Clip.LOOP_CONTINUOUSLY : 0); + clip.loop(loop ? Clip.LOOP_CONTINUOUSLY : 0); clip.start(); } @@ -176,10 +183,12 @@ public static Clip playSound(String path, boolean loop) } + public ObservableList getBlocks() { return this.blocks; } + public ObservableList getTrees() { return this.trees; } public ObservableList getEntities() { return this.entities; } - public ObservableList getRabbits() { return rabbits; } - public ObservableList getTorches() { return torches; } - public ObservableList getSlimes() { return slimes; } + public ObservableList getRabbits() { return this.rabbits; } + public ObservableList getTorches() { return this.torches; } + public ObservableList getSlimes() { return this.slimes; } public TileMaps getTileMaps() { return this.tileMaps; } public Player getPlayer() { return this.player; } public Clock getGameClock() { return this.clock; } diff --git a/src/main/java/fr/sae/terraria/modele/GenerateEntity.java b/src/main/java/fr/sae/terraria/modele/GenerateEntity.java index 2e96b57..f2494ac 100644 --- a/src/main/java/fr/sae/terraria/modele/GenerateEntity.java +++ b/src/main/java/fr/sae/terraria/modele/GenerateEntity.java @@ -17,12 +17,15 @@ import static fr.sae.terraria.modele.entities.Slime.WHEN_SPAWN_A_SLIME; import static fr.sae.terraria.modele.entities.blocks.TallGrass.TALL_GRASS_SPAWN_RATE; import static fr.sae.terraria.modele.entities.blocks.TallGrass.WHEN_SPAWN_A_TALL_GRASS; -import static fr.sae.terraria.modele.entities.blocks.Tree.TREE_SPAWN_RATE; -import static fr.sae.terraria.modele.entities.blocks.Tree.WHEN_SPAWN_A_TREE; +/** + *

Generate Entity

+ *

Une classe qui permet de générer aléatoirement des entités

+ */ public class GenerateEntity { + private static final double TREE_SPAWN_RATE = .1; public static final int MAX_SPAWN_RABBIT = 100; public static final int MAX_SPAWN_SLIME = 100; private static final Random random = new Random(); @@ -31,26 +34,26 @@ public class GenerateEntity public GenerateEntity() { super(); } /** - * Génère une entité selon de quand il spawn et du pourcent de change qu'il spawn réellement. + * Génère une entité selon le momnt ou il est sensé apparaitre et son pourcentage de chances d'apparaitre. * * @param e L'entité concernée * @param whenSpawn Le nombre qui determine quand il doit spawn sur la carte - * @param spawnRate Le pourcentage de chance qu'il spawn réellement à l'endroit qu'on souhaite le placer + * @param spawnRate Le pourcentage de chance qu'il spawn réellement à l'endroit où l'on souhaite le placer */ private static void generateAnEntity(Environment environment, SpawnableObjectType e, int whenSpawn, double spawnRate) { List entities = environment.getEntities(); - TileMaps maps = environment.getTileMaps(); + TileMaps tileMaps = environment.getTileMaps(); int widthTile = environment.widthTile; int heightTile = environment.heightTile; int ticks = environment.getTicks(); // Fréquence d'apparition if (ticks%whenSpawn == 0) - for (int y = 0; y < maps.getHeight(); y++) + for (int y = 0; y < tileMaps.getHeight(); y++) // Est-ce que l'arbre doit spawn sur ce 'y' if (Math.random() < spawnRate) { - List locFloorsOnAxisX = findFloors(maps, y); + List locFloorsOnAxisX = findFloors(tileMaps, y); // Si il y a du sol sur la ligne if (!locFloorsOnAxisX.isEmpty()) { int onWhichFloor = random.nextInt(locFloorsOnAxisX.size()); @@ -58,7 +61,7 @@ private static void generateAnEntity(Environment environment, SpawnableObjectTyp int xEntity = targetFloor * widthTile; int yEntity = ((y == 0) ? y : (y - 1)) * heightTile; // Verifies au cas où si le tile au-dessus de lui est bien une casse vide (Du ciel) - if (maps.getTile(targetFloor, y - 1) == TileMaps.SKY) { + if (tileMaps.isSkyTile(targetFloor, y-1)) { for (Entity entity : entities) // Une entité est déjà present ? Il ne le génère pas et arrête complétement la fonction if (xEntity == entity.getX() && yEntity == entity.getY()) @@ -73,35 +76,34 @@ private static void generateAnEntity(Environment environment, SpawnableObjectTyp } /** Range les positions du sol sur la ligne 'y' */ - private static List findFloors(TileMaps maps, int y) + private static List findFloors(TileMaps tileMaps, int y) { - List localisation = new ArrayList<>(); - for (int x = 0; x < maps.getWidth(); x++) { - int targetTile = maps.getTile(x, y); + List loc = new ArrayList<>(); + for (int x = 0; x < tileMaps.getWidth(); x++) + if (tileMaps.isFloorTopTile(x, y) || tileMaps.isFloorRightTile(x, y) || tileMaps.isFloorLeftTile(x, y)) + loc.add(x); - if (targetTile == TileMaps.FLOOR_TOP || targetTile == TileMaps.FLOOR_RIGHT || targetTile == TileMaps.FLOOR_LEFT) - localisation.add(x); - } - - return localisation; + return loc; } /** À un certain moment, grace au tick, il va générer des arbres +/- grand uniquement sur un sol */ - public static void tree(Environment environment) { generateAnEntity(environment, new Tree(environment), WHEN_SPAWN_A_TREE, TREE_SPAWN_RATE); } + public static void treeRandomly(Environment environment) { generateAnEntity(environment, new Tree(environment), 1, TREE_SPAWN_RATE); } /** À un certain moment, grace au tick, il va générer des hautes herbes sur un sol */ - public static void tallGrass(Environment environment) { generateAnEntity(environment, new TallGrass(environment), WHEN_SPAWN_A_TALL_GRASS, TALL_GRASS_SPAWN_RATE); } + public static void tallGrassRandomly(Environment environment) { generateAnEntity(environment, new TallGrass(environment), WHEN_SPAWN_A_TALL_GRASS, TALL_GRASS_SPAWN_RATE); } /** À un certain moment, grace au tick et à l'horloge du jeu, il va générer des lapins sur un sol */ - public static void rabbit(Environment environment) + public static void rabbitRandomly(Environment environment) { if (environment.getRabbits().size() < MAX_SPAWN_RABBIT) generateAnEntity(environment, new Rabbit(environment), WHEN_SPAWN_A_RABBIT, RABBIT_SPAWN_RATE); } - /** À un certain moment, grace au tick et à l'horloge du jeu, il va générer des lapins sur un sol */ - public static void slime(Environment environment) + /** À un certain moment, grace au tick et à l'horloge du jeu, il va générer des slimes sur un sol */ + public static void slimeRandomly(Environment environment) { if (environment.getSlimes().size() < MAX_SPAWN_SLIME) generateAnEntity(environment, new Slime(environment), WHEN_SPAWN_A_SLIME, SLIME_SPAWN_RATE); } + + public static void slime(Environment environment) { generateAnEntity(environment, new Slime(environment), 1, 1); } } diff --git a/src/main/java/fr/sae/terraria/modele/TileMaps.java b/src/main/java/fr/sae/terraria/modele/TileMaps.java index 2a7f312..0479e4c 100644 --- a/src/main/java/fr/sae/terraria/modele/TileMaps.java +++ b/src/main/java/fr/sae/terraria/modele/TileMaps.java @@ -5,16 +5,18 @@ import java.io.FileReader; +/** + *

Tile maps

+ *

Génère à l'écran la carte tuilé

+ *

Description:

+ *

Cette classes permet à partir d'un fichier .json de chargé les données de la carte

+ *

Il est conservé dans la variable maps

+ * + * @author CHRZASZCZ Naulan + */ public class TileMaps { - // Constantes public static final int TILE_DEFAULT_SIZE = 16; - public static final int SKY = 0; - public static final int STONE = 1; - public static final int DIRT = 2; - public static final int FLOOR_TOP = 3; - public static final int FLOOR_LEFT = 4; - public static final int FLOOR_RIGHT = 5; // Qui concerne la carte private int[][] maps; @@ -84,10 +86,24 @@ public void load(final String path) } catch (Exception e) { e.printStackTrace(); } } + public boolean isDirtTile(double x, double y) { return this.getTile((int) x, (int) y) == TileSet.DIRT.ordinal(); } + public boolean isSkyTile(double x, double y) { return this.getTile((int) x, (int) y) == TileSet.SKY.ordinal(); } + public boolean isRockTile(double x, double y) { return this.getTile((int) x, (int) y) == TileSet.ROCK.ordinal(); } + public boolean isFloorTopTile(double x, double y) { return this.getTile((int) x, (int) y) == TileSet.FLOOR_TOP.ordinal(); } + public boolean isFloorRightTile(double x, double y) { return this.getTile((int) x, (int) y) == TileSet.FLOOR_RIGHT.ordinal(); } + public boolean isFloorLeftTile(double x, double y) { return this.getTile((int) x, (int) y) == TileSet.FLOOR_LEFT.ordinal(); } + public int getHeight() { return this.maps.length; } public int getWidth() { return this.maps[0].length; } public int getTile(int x, int y) { return this.maps[y][x]; } + /** + * Remplace grâce aux coordonnées entrées, un tile par celui qui est mis dans l'argument + * + * @param tileIndex Le tile qui doit remplacer une autre. + * @param x la position horizontal de là où le tile doit être écrit + * @param y la position vertical de là où le tile doit être écrit + */ public void setTile(int tileIndex, int y, int x) { this.maps[y][x] = tileIndex; } } diff --git a/src/main/java/fr/sae/terraria/modele/TileSet.java b/src/main/java/fr/sae/terraria/modele/TileSet.java new file mode 100644 index 0000000..2a0a3f6 --- /dev/null +++ b/src/main/java/fr/sae/terraria/modele/TileSet.java @@ -0,0 +1,43 @@ +package fr.sae.terraria.modele; + +import fr.sae.terraria.modele.entities.blocks.BlockSet; + + +public enum TileSet +{ + SKY, + ROCK, + DIRT, + FLOOR_TOP, + FLOOR_LEFT, + FLOOR_RIGHT, + TALL_GRASS, + TREE; + + + public static boolean isSkyTile(TileSet item) { return item == TileSet.SKY; } + public static boolean isRockTile(TileSet item) { return item == TileSet.ROCK; } + public static boolean isDirtTile(TileSet item) { return item == TileSet.DIRT; } + public static boolean isFloorTopTile(TileSet item) { return item == TileSet.FLOOR_TOP; } + public static boolean isFloorRightTile(TileSet item) { return item == TileSet.FLOOR_RIGHT; } + public static boolean isFloorLeftTile(TileSet item) { return item == TileSet.FLOOR_LEFT; } + + public static TileSet getTileSet(BlockSet blockSet) + { + if (blockSet == BlockSet.DIRT) + return TileSet.DIRT; + if (blockSet == BlockSet.ROCK) + return TileSet.ROCK; + if (blockSet == BlockSet.FLOOR_LEFT) + return TileSet.FLOOR_LEFT; + if (blockSet == BlockSet.FLOOR_RIGHT) + return TileSet.FLOOR_RIGHT; + if (blockSet == BlockSet.FLOOR_TOP) + return TileSet.FLOOR_TOP; + if (blockSet == BlockSet.TALL_GRASS) + return TileSet.TALL_GRASS; + if (blockSet == BlockSet.TREE) + return TileSet.TREE; + return null; + } +} diff --git a/src/main/java/fr/sae/terraria/modele/entities/Arrow.java b/src/main/java/fr/sae/terraria/modele/entities/Arrow.java index 40b9b46..d85ea7b 100644 --- a/src/main/java/fr/sae/terraria/modele/entities/Arrow.java +++ b/src/main/java/fr/sae/terraria/modele/entities/Arrow.java @@ -2,20 +2,17 @@ import fr.sae.terraria.modele.Environment; import fr.sae.terraria.modele.entities.entity.CollideObjectType; -import fr.sae.terraria.modele.entities.entity.Entity; -import fr.sae.terraria.modele.entities.entity.MovableObjectType; +import fr.sae.terraria.modele.entities.entity.EntityMovable; import fr.sae.terraria.modele.entities.entity.StowableObjectType; -public class Arrow extends Entity implements StowableObjectType, MovableObjectType, CollideObjectType +public class Arrow extends EntityMovable implements StowableObjectType, CollideObjectType { - private final Environment environment; public Arrow(final Environment environment, int x, int y, int velocity) { - super(x, y); - this.environment = environment; + super(environment, x, y); this.velocity = velocity; } @@ -23,10 +20,4 @@ public Arrow(final Environment environment, int x, int y, int velocity) @Override public void updates() { /* TODO document why this method is empty */ } @Override public void move() { /* TODO document why this method is empty */ } @Override public void collide() { /* TODO document why this method is empty */ } - - @Override public void moveRight() { super.moveRight(); } - @Override public void moveLeft() { super.moveLeft(); } - @Override public void jump() { /* UNE FLECHE NE PEUT SAUTER */ } - @Override public void fall() { super.fall(); } - @Override public void worldLimit() { super.worldLimit(this.environment); } } diff --git a/src/main/java/fr/sae/terraria/modele/entities/Rabbit.java b/src/main/java/fr/sae/terraria/modele/entities/Rabbit.java index 8d8d32f..e0bc584 100644 --- a/src/main/java/fr/sae/terraria/modele/entities/Rabbit.java +++ b/src/main/java/fr/sae/terraria/modele/entities/Rabbit.java @@ -12,7 +12,7 @@ import java.util.Objects; -public class Rabbit extends Entity implements CollideObjectType, ReproductiveObjectType, MovableObjectType, CollapsibleObjectType, SpawnableObjectType +public class Rabbit extends EntityMovable implements CollideObjectType, ReproductiveObjectType, CollapsibleObjectType, SpawnableObjectType { public static final int WHEN_SPAWN_A_RABBIT = 2_500; public static final double RABBIT_SPAWN_RATE = .2; @@ -21,14 +21,12 @@ public class Rabbit extends Entity implements CollideObjectType, ReproductiveObj public static final double LUCK_OF_JUMPING = .5; public static final int JUMP_FREQUENCY = 50; - private final Environment environment; private final Animation animation; public Rabbit(final Environment environment, int x, int y) { - super(x, y); - this.environment = environment; + super(environment, x, y); this.setPv(3); this.animation = new Animation(); @@ -41,7 +39,7 @@ public Rabbit(final Environment environment, int x, int y) @Override public void updates() { - if (this.offset[1] == Entity.IDLE && !this.air) { + if (this.isIDLEonY() && !this.air) { this.gravity.xInit = this.x.get(); this.gravity.yInit = this.y.get(); this.gravity.vInit = this.velocity; @@ -61,15 +59,16 @@ public Rabbit(final Environment environment, int x, int y) @Override public void move() { - this.setX(this.x.get() + this.offset[0] * this.velocity); + TileMaps tileMaps = this.environment.getTileMaps(); + this.setX(this.x.get() + this.getOffsetMoveX() * this.velocity); - if (this.offset[1] == Entity.IDLE && this.offset[0] != Entity.IDLE) { - int xProbablyVoid = (int) ((getX()+((this.offset[0] == Entity.IS_MOVING_LEFT) ? 0 : this.environment.widthTile)) / this.environment.widthTile); + if (this.isIDLEonY() && this.isMoving()) { + int xProbablyVoid = (int) ((getX()+((this.isMovingLeft()) ? 0 : this.environment.widthTile)) / this.environment.widthTile); int yProbablyVoid = (int) (getY() / environment.heightTile); // Si du vide risque d'y avoir lors de son déplacement - if (environment.getTileMaps().getTile(xProbablyVoid, yProbablyVoid + 2) == TileMaps.SKY) { - this.offset[0] = (-1) * this.offset[0]; + if (tileMaps.isSkyTile(xProbablyVoid, yProbablyVoid+2)) { + this.offset[0] = (-1) * this.getOffsetMoveX(); } else { boolean mustJump = this.environment.getTicks() % Rabbit.JUMP_FREQUENCY == 0; if (mustJump) { @@ -99,7 +98,7 @@ public Rabbit(final Environment environment, int x, int y) if (!whereCollide.isEmpty()) { if (whereCollide.get("left").equals(Boolean.TRUE) || whereCollide.get("right").equals(Boolean.TRUE)) - this.offset[0] = (-1) * this.offset[0]; + this.offset[0] = (-1) * this.getOffsetMoveX(); } } @@ -125,23 +124,15 @@ public Rabbit(final Environment environment, int x, int y) this.getGravity().setXInit(x); this.getGravity().setYInit(y); this.setRect(environment.widthTile, environment.heightTile); + this.environment.getEntities().add(0, this); - this.environment.getRabbits().add(0, this); + this.environment.getRabbits().add(this); } - /** Modifie l'offset qui permet de le déplacer vers la droite */ - @Override public void moveRight() { super.moveRight(); } - /** Modifie l'offset qui permet de le déplacer vers la gauche */ - @Override public void moveLeft() { super.moveLeft(); } - /** Modifie l'offset qui permet de le faire sauter */ - @Override public void jump() { super.jump(); } - /** Modifie l'offset qui permet de tomber */ - @Override public void fall() { super.fall(); } - - @Override public void worldLimit() + public void worldLimit() { if (super.worldLimit(this.environment)) - this.offset[0] = (-1) * this.offset[0]; + this.offset[0] = (-1) * this.getOffsetMoveX(); } diff --git a/src/main/java/fr/sae/terraria/modele/entities/Slime.java b/src/main/java/fr/sae/terraria/modele/entities/Slime.java index 721fd28..c2318be 100644 --- a/src/main/java/fr/sae/terraria/modele/entities/Slime.java +++ b/src/main/java/fr/sae/terraria/modele/entities/Slime.java @@ -2,23 +2,23 @@ import fr.sae.terraria.modele.Environment; import fr.sae.terraria.modele.entities.entity.*; +import fr.sae.terraria.modele.entities.player.Player; +import fr.sae.terraria.modele.entities.player.inventory.Stack; +import fr.sae.terraria.modele.entities.tools.Tool; import java.util.Map; import java.util.Objects; -public class Slime extends Entity implements CollideObjectType, MovableObjectType, CollapsibleObjectType, SpawnableObjectType +public class Slime extends EntityMovable implements CollideObjectType, CollapsibleObjectType, SpawnableObjectType { public static final int WHEN_SPAWN_A_SLIME = 2_500; public static final double SLIME_SPAWN_RATE = .2; - private final Environment environment; - public Slime(Environment environment, int x, int y) { - super(x, y); - this.environment = environment; + super(environment, x, y); this.velocity = 2; this.setPv(3); @@ -30,8 +30,9 @@ public Slime(Environment environment, int x, int y) public Slime(Environment environment) { this(environment, 0, 0); } - @Override public void updates() { - if (this.offset[1] == Entity.IDLE && !this.air) { + @Override public void updates() + { + if (this.isIDLEonY() && !this.air) { this.gravity.xInit = this.x.get(); this.gravity.yInit = this.y.get(); this.gravity.vInit = this.velocity; @@ -39,16 +40,16 @@ public Slime(Environment environment, int x, int y) this.gravity.timer = .0; } - this.offset[0] = Entity.IDLE; - if (this.offset[1] == Entity.IS_JUMPING) { - if (environment.getPlayer().getX() > this.x.getValue()) - this.offset[0] = Entity.IS_MOVING_RIGHT; + this.idleOnX(); + if (this.isJumping()) { + if (this.environment.getPlayer().getX() > this.x.getValue()) + this.moveRight(); else if (environment.getPlayer().getX() < this.x.getValue()) - this.offset[0] = Entity.IS_MOVING_LEFT; + this.moveLeft(); } this.move(); - this.collide(); // FIXME: 08/06/2022 : idk pourquoi le collide pose probleme pour le saut du slime + this.collide(); this.worldLimit(); if (!Objects.isNull(this.rect)) @@ -56,24 +57,49 @@ else if (environment.getPlayer().getX() < this.x.getValue()) this.animation.loop(); } - @Override public void collide() { + @Override public void collide() + { Map whereCollide = super.collide(this.environment); if (!whereCollide.isEmpty()) if (whereCollide.get("left").equals(Boolean.TRUE) || whereCollide.get("right").equals(Boolean.TRUE)) - this.offset[0] = Entity.IDLE; + this.idleOnX(); + + if (environment.getPlayer().getRect().collideRect(this.getRect()) && !environment.getPlayer().getHit()){ + environment.getPlayer().hit(); + environment.getPlayer().setInvisibilityFrame(this.environment.getTicks()); + } + + if (environment.getPlayer().getHit() && this.environment.getTicks() - environment.getPlayer().getInvisibilityFrame() == Player.TIME_BEFORE_HITTING_AGAIN_THE_PLAYER) + environment.getPlayer().setHit(false); } @Override public void move() { if (((int) (this.animation.getFrame()) == 3)) - if (this.offset[1] != Entity.IS_FALLING) this.jump(); - this.setX(this.getX() + (this.offset[0] * this.velocity)); + if (this.isNotFalling()) this.jump(); + + this.setX(this.getX() + (this.getOffsetMoveX() * this.velocity)); } @Override public void hit() { Environment.playSound("sound/daggerswipe.wav", false); + + if (this.getPv() <= 0) { + // this.environment.getPlayer().pickup(new SlimeBall()); + + this.environment.getSlimes().remove(this); + this.environment.getEntities().remove(this); + } + + Stack stack = this.environment.getPlayer().getStackSelected(); + if (!Objects.isNull(stack)) { + if (stack.getItem() instanceof Tool && Tool.isSword((Tool) stack.getItem())) { + Tool tool = (Tool) stack.getItem(); + this.setPv(this.getPv() - tool.damage()); + } + } else this.setPv(this.getPv() - .5); } @Override public void spawn(int x, int y) @@ -83,17 +109,10 @@ else if (environment.getPlayer().getX() < this.x.getValue()) this.getGravity().setXInit(x); this.getGravity().setYInit(y); this.setRect(environment.widthTile, environment.heightTile); - this.environment.getEntities().add(0, this); - this.environment.getSlimes().add(0, this); - } - - @Override public void moveRight() { super.moveRight(); } - @Override public void moveLeft() { super.moveLeft(); } - - @Override public void jump() { super.jump(); } - - @Override public void fall() { super.fall(); } + this.environment.getEntities().add(this); + this.environment.getSlimes().add(this); + } - @Override public void worldLimit() { super.worldLimit(this.environment); } + public void worldLimit() { super.worldLimit(this.environment); } } diff --git a/src/main/java/fr/sae/terraria/modele/entities/blocks/Block.java b/src/main/java/fr/sae/terraria/modele/entities/blocks/Block.java index 90b82ba..e50455e 100644 --- a/src/main/java/fr/sae/terraria/modele/entities/blocks/Block.java +++ b/src/main/java/fr/sae/terraria/modele/entities/blocks/Block.java @@ -2,23 +2,50 @@ import fr.sae.terraria.Terraria; import fr.sae.terraria.modele.Environment; +import fr.sae.terraria.modele.TileSet; import fr.sae.terraria.modele.entities.entity.BreakableObjectType; import fr.sae.terraria.modele.entities.entity.Entity; +import fr.sae.terraria.modele.entities.entity.PlaceableObjectType; +import fr.sae.terraria.modele.entities.entity.StowableObjectType; +import fr.sae.terraria.modele.entities.items.Item; +import fr.sae.terraria.modele.entities.items.Vodka; +import fr.sae.terraria.modele.entities.player.Player; +import fr.sae.terraria.modele.entities.player.inventory.Inventory; +import fr.sae.terraria.modele.entities.player.inventory.Stack; +import fr.sae.terraria.modele.entities.tools.Tool; import javafx.animation.KeyFrame; import javafx.animation.Timeline; import javafx.util.Duration; +import java.util.Objects; -public abstract class Block extends Entity implements BreakableObjectType + +public class Block extends Entity implements BreakableObjectType, PlaceableObjectType, StowableObjectType { + public static final int ROCK_NB_LOOTS = 3; + + private final Environment environment; + private final BlockSet typeOfBlock; + private final double xOrigin; + private final double yOrigin; - protected Block(int x, int y) + + public Block(final BlockSet typeOfBlock, final Environment environment, int x, int y) { super(x, y); + this.typeOfBlock = typeOfBlock; + this.environment = environment; + + this.xOrigin = x; + this.yOrigin = y; + + this.pv.set(typeOfBlock.getDurability()); } - protected void breakAnimation(final Environment environment, final Block block, double xOrigin, double yOrigin) + public Block(final BlockSet typeOfBlock, final Environment environment) { this(typeOfBlock, environment, 0, 0); } + + private void breakAnimation() { Timeline timeline = new Timeline(); int animationCycleCount = 5; @@ -26,19 +53,132 @@ protected void breakAnimation(final Environment environment, final Block block, // Animation de cassure du bloc timeline.setCycleCount(animationCycleCount); KeyFrame keyFrame = new KeyFrame(Duration.seconds(Terraria.TARGET_FPS), (ev -> { - block.setX(xOrigin + (Math.cos(time[0])*environment.scaleMultiplicatorWidth)); - block.setY(yOrigin + (-Math.sin(time[0]*environment.scaleMultiplicatorHeight))); + this.setX(xOrigin + (Math.cos(time[0])*environment.scaleMultiplicatorWidth)); + this.setY(yOrigin + (-Math.sin(time[0]*environment.scaleMultiplicatorHeight))); time[0]++; })); timeline.getKeyFrames().add(keyFrame); - // Faire revenir le bloc à sa position initiale lorsque l'animation est arrêté + // Faire revenir le bloc à sa position initiale lorsque l'animation est terminée timeline.statusProperty().addListener(c -> { - block.setX(xOrigin); - block.setY(yOrigin); + this.setX(xOrigin); + this.setY(yOrigin); }); timeline.play(); } - @Override public abstract void updates(); + private void loots() + { + Player player = this.environment.getPlayer(); + + if (Block.isFloorTop(this) || Block.isFloorLeft(this) || Block.isFloorRight(this) || Block.isDirt(this)) { + player.pickup(new Block(BlockSet.FLOOR_TOP, this.environment)); + } else if (Block.isRock(this)) { + for (int loot = 0; loot < Block.ROCK_NB_LOOTS; loot++) + player.pickup(Item.STONE); + + if (Math.random() > .5) + player.pickup(Item.COAL); + if (Math.random() < .05) + player.pickup(Item.IRON); + } else if (Block.isTallGrass(this)) { + for (int loot = (int) (Math.random()*3)+1; loot <= TallGrass.LOOTS_FIBRE_MAX; loot++) + player.pickup(Item.FIBER); + + boolean mustDropVodka = Math.random() < Vodka.DROP_RATE; + if (mustDropVodka) + player.pickup(new Vodka(this.environment)); + } else if (Block.isTorch(this)) { + player.pickup(new Block(BlockSet.TORCH, this.environment)); + } else if (Block.isTree(this)) { + player.pickup(Item.WOOD); + for (int i = 0; i < Tree.STICKS_DROP; i++) + player.pickup(Item.STICK); + } + } + + private void playSound() + { + if (Block.isRock(this)) + Environment.playSound("sound/brick" + ((int) (Math.random()*2)+1) + ".wav", false); + else if (Block.isTallGrass(this)) + Environment.playSound("sound/cut.wav", false); + else if (Block.isTree(this)) + Environment.playSound("sound/treeHit.wav", false); + else Environment.playSound("sound/grassyStep.wav", false); + } + + @Override public void updates() { } + + @Override public void breaks() + { + this.playSound(); + this.breakAnimation(); + + if (this.getPv() <= 0) { + this.loots(); + + int yIndexTile = (int) (getY()/environment.heightTile); + int xIndexTile = (int) (getX()/environment.widthTile); + this.environment.getTileMaps().setTile(TileSet.SKY.ordinal(), yIndexTile, xIndexTile); + + this.environment.getEntities().remove(this); + this.environment.getBlocks().remove(this); + if (Block.isTorch(this)) + this.environment.getTorches().remove(this); + if (Block.isTree(this)) + this.environment.getTrees().remove(this); + } + + if (Block.isRock(this)) { + Stack item = this.environment.getPlayer().getStackSelected(); + if (!Objects.isNull(item) && item.getItem() instanceof Tool) { + Tool tool = (Tool) item.getItem(); + if (Tool.isPickaxe(tool)) + this.setPv(this.getPv() - 1); + tool.use(); + } + } else this.setPv(this.getPv() - 1); + } + + @Override public void place(final int x, final int y) + { + Environment.playSound("sound/axchop.wav", false); + int widthTile = this.environment.widthTile; + int heightTile = this.environment.heightTile; + + Player player = this.environment.getPlayer(); + Inventory inventory = player.getInventory(); + if (!Objects.isNull(player.getStackSelected())) + inventory.get().get(inventory.getPosCursor()).remove(); + + Block block; + if (Block.isDirt(this) || Block.isFloorTop(this) || Block.isFloorLeft(this) || Block.isFloorRight(this)) + block = new Block(BlockSet.FLOOR_TOP, this.environment, x*widthTile, y*heightTile); + else block = new Block(this.typeOfBlock, this.environment, x*widthTile, y*heightTile); + block.setRect(widthTile, heightTile); + + TileSet tile = TileSet.getTileSet(this.typeOfBlock); + if (!Objects.isNull(tile)) + this.environment.getTileMaps().setTile(tile.ordinal(), y, x); + + this.environment.getEntities().add(block); + this.environment.getBlocks().add(block); + if (Block.isTree(this)) + this.environment.getTrees().add((Tree) block); + if (Block.isTorch(this)) + this.environment.getTorches().add(block); + } + + public static boolean isFloorTop(final Block block) { return block.getTypeOfBlock() == BlockSet.FLOOR_TOP; } + public static boolean isFloorLeft(final Block block) { return block.getTypeOfBlock() == BlockSet.FLOOR_LEFT; } + public static boolean isFloorRight(final Block block) { return block.getTypeOfBlock() == BlockSet.FLOOR_RIGHT; } + public static boolean isDirt(final Block block) { return block.getTypeOfBlock() == BlockSet.DIRT; } + public static boolean isRock(final Block block) { return block.getTypeOfBlock() == BlockSet.ROCK; } + public static boolean isTallGrass(final Block block) { return block.getTypeOfBlock() == BlockSet.TALL_GRASS; } + public static boolean isTorch(final Block block) { return block.getTypeOfBlock() == BlockSet.TORCH; } + public static boolean isTree(final Block block) { return block.getTypeOfBlock() == BlockSet.TREE; } + + + public BlockSet getTypeOfBlock() { return this.typeOfBlock; } } diff --git a/src/main/java/fr/sae/terraria/modele/entities/blocks/BlockSet.java b/src/main/java/fr/sae/terraria/modele/entities/blocks/BlockSet.java new file mode 100644 index 0000000..10be91e --- /dev/null +++ b/src/main/java/fr/sae/terraria/modele/entities/blocks/BlockSet.java @@ -0,0 +1,24 @@ +package fr.sae.terraria.modele.entities.blocks; + + +public enum BlockSet +{ + FLOOR_TOP(3), + FLOOR_RIGHT(3), + FLOOR_LEFT(3), + DIRT(3), + ROCK(5), + TALL_GRASS(2), + TORCH(1), + TREE(4); + + private final int durability; + + + BlockSet(final int durability) + { + this.durability = durability; + } + + public int getDurability() { return this.durability; } +} diff --git a/src/main/java/fr/sae/terraria/modele/entities/blocks/Dirt.java b/src/main/java/fr/sae/terraria/modele/entities/blocks/Dirt.java deleted file mode 100644 index 8cf8f06..0000000 --- a/src/main/java/fr/sae/terraria/modele/entities/blocks/Dirt.java +++ /dev/null @@ -1,73 +0,0 @@ -package fr.sae.terraria.modele.entities.blocks; - -import fr.sae.terraria.modele.Environment; -import fr.sae.terraria.modele.TileMaps; -import fr.sae.terraria.modele.entities.entity.CollideObjectType; -import fr.sae.terraria.modele.entities.entity.Entity; -import fr.sae.terraria.modele.entities.entity.PlaceableObjectType; -import fr.sae.terraria.modele.entities.entity.StowableObjectType; -import fr.sae.terraria.modele.entities.player.Player; -import fr.sae.terraria.modele.entities.player.inventory.Inventory; - -import java.util.Objects; - - -public class Dirt extends Block implements StowableObjectType, CollideObjectType, PlaceableObjectType -{ - public static final int BREAK_RESISTANCE = 2; - - private final Environment environment; - - private final double xOrigin; - private final double yOrigin; - - - public Dirt(Environment environment, int x, int y) - { - super(x, y); - this.environment = environment; - - this.xOrigin = x; - this.yOrigin = y; - - this.pv.set(Dirt.BREAK_RESISTANCE); - } - - @Override public void updates() { /* TODO document why this method is empty */ } - - @Override public void collide() { /* NE RIEN REMPLIR */ } - - @Override public void breaks() - { - Environment.playSound("sound/grassyStep.wav", false); - this.breakAnimation(environment, this, xOrigin, yOrigin); - - if (this.getPv() <= 0) { - this.environment.getPlayer().pickup(this); - - int yIndexTile = (int) (getY()/environment.heightTile); - int xIndexTile = (int) (getX()/environment.widthTile); - this.environment.getTileMaps().setTile(TileMaps.SKY, yIndexTile, xIndexTile); - this.environment.getEntities().remove(this); - } - this.setPv(this.getPv() - 1); - } - - @Override public void place(final int x, final int y) - { - Environment.playSound("sound/axchop.wav", false); - int widthTile = this.environment.widthTile; - int heightTile = this.environment.heightTile; - - Entity entity = new Dirt(this.environment, x*widthTile, y*heightTile); - entity.setRect(widthTile, heightTile); - - Player player = this.environment.getPlayer(); - Inventory inventory = player.getInventory(); - if (!Objects.isNull(player.getStackSelected())) - inventory.get().get(inventory.getPosCursor()).remove(); - - this.environment.getTileMaps().setTile(TileMaps.DIRT, y, x); - this.environment.getEntities().add(0, entity); - } -} diff --git a/src/main/java/fr/sae/terraria/modele/entities/blocks/Grass.java b/src/main/java/fr/sae/terraria/modele/entities/blocks/Grass.java deleted file mode 100644 index 7e07df6..0000000 --- a/src/main/java/fr/sae/terraria/modele/entities/blocks/Grass.java +++ /dev/null @@ -1,17 +0,0 @@ -package fr.sae.terraria.modele.entities.blocks; - -import fr.sae.terraria.modele.Environment; - -public class Grass extends Block -{ - - - public Grass(int x, int y) { super(x, y); } - - @Override public void updates() { /* TODO document why this method is empty */ } - - @Override public void breaks() - { - Environment.playSound("sound/grassyStep.wav", false); - } -} diff --git a/src/main/java/fr/sae/terraria/modele/entities/blocks/Stone.java b/src/main/java/fr/sae/terraria/modele/entities/blocks/Stone.java deleted file mode 100644 index c96fb32..0000000 --- a/src/main/java/fr/sae/terraria/modele/entities/blocks/Stone.java +++ /dev/null @@ -1,84 +0,0 @@ -package fr.sae.terraria.modele.entities.blocks; - -import fr.sae.terraria.modele.Environment; -import fr.sae.terraria.modele.TileMaps; -import fr.sae.terraria.modele.entities.entity.CollideObjectType; -import fr.sae.terraria.modele.entities.entity.Entity; -import fr.sae.terraria.modele.entities.entity.PlaceableObjectType; -import fr.sae.terraria.modele.entities.entity.StowableObjectType; -import fr.sae.terraria.modele.entities.player.Player; -import fr.sae.terraria.modele.entities.player.inventory.Inventory; -import fr.sae.terraria.modele.entities.player.inventory.Stack; -import fr.sae.terraria.modele.entities.tools.Pickaxe; -import fr.sae.terraria.modele.entities.tools.Tool; - -import java.util.Objects; - - -public class Stone extends Block implements StowableObjectType, CollideObjectType, PlaceableObjectType -{ - public static final int BREAK_RESISTANCE = 5; - - private final Environment environment; - - private final double xOrigin; - private final double yOrigin; - - - public Stone(Environment environment, int x, int y) - { - super(x, y); - this.environment = environment; - - this.xOrigin = x; - this.yOrigin = y; - - this.pv.set(Stone.BREAK_RESISTANCE); - } - - @Override public void updates() { /* TODO document why this method is empty */ } - - @Override public void collide() { /* NE RIEN REMPLIR */ } - - @Override public void breaks() - { - Environment.playSound("sound/brick" + ((int) (Math.random()*2)+1) + ".wav", false); - this.breakAnimation(this.environment, this, this.xOrigin, this.yOrigin); - - // Une fois le bloc détruit, il donne la pierre et le supprime de la TileMaps - Player player = this.environment.getPlayer(); - if (this.getPv() <= 0) { - player.pickup(this); - - int yIndexTile = (int) (getY()/this.environment.heightTile); - int xIndexTile = (int) (getX()/this.environment.widthTile); - this.environment.getTileMaps().setTile(TileMaps.SKY, yIndexTile, xIndexTile); - this.environment.getEntities().remove(this); - } - - // S'il utilise le bon outil, il commencera à casser le bloc sinon use l'outil sans casser le bloc. - Stack stack = player.getStackSelected(); - if (stack.getItem() instanceof Pickaxe) - this.setPv(this.getPv() - 1); - if (stack.getItem() instanceof Tool) - ((Tool) stack.getItem()).use(); - } - - @Override public void place(int x, int y) - { - Environment.playSound("sound/axchop.wav", false); - int widthTile = this.environment.widthTile; - int heightTile = this.environment.heightTile; - - Entity entity = new Stone(this.environment, x*widthTile, y*heightTile); - entity.setRect(widthTile, heightTile); - - Player player = this.environment.getPlayer(); - Inventory inventory = player.getInventory(); - if (!Objects.isNull(player.getStackSelected())) - inventory.get().get(inventory.getPosCursor()).remove(); - - this.environment.getTileMaps().setTile(TileMaps.STONE, y, x); - this.environment.getEntities().add(0, entity); - } -} diff --git a/src/main/java/fr/sae/terraria/modele/entities/blocks/TallGrass.java b/src/main/java/fr/sae/terraria/modele/entities/blocks/TallGrass.java index 9fd6929..2311f99 100644 --- a/src/main/java/fr/sae/terraria/modele/entities/blocks/TallGrass.java +++ b/src/main/java/fr/sae/terraria/modele/entities/blocks/TallGrass.java @@ -5,7 +5,6 @@ import fr.sae.terraria.modele.entities.entity.Entity; import fr.sae.terraria.modele.entities.entity.ReproductiveObjectType; import fr.sae.terraria.modele.entities.entity.SpawnableObjectType; -import fr.sae.terraria.modele.entities.items.Fiber; import javafx.beans.property.DoubleProperty; import javafx.beans.property.SimpleDoubleProperty; @@ -16,9 +15,9 @@ public class TallGrass extends Block implements ReproductiveObjectType, SpawnableObjectType { public static final int WHEN_SPAWN_A_TALL_GRASS = 2_500; - public static final double TALL_GRASS_SPAWN_RATE = .3; - public static final double REPRODUCTION_RATE = 500; - public static final double GROWTH_SPEED = .0005; + public static final double TALL_GRASS_SPAWN_RATE = .8; + public static final double REPRODUCTION_RATE = 1_250; + public static final double GROWTH_SPEED = .01; public static final int GROWTH_TALL_GRASS_STEP = 6; public static final int LOOTS_FIBRE_MAX = 3; @@ -27,9 +26,9 @@ public class TallGrass extends Block implements ReproductiveObjectType, Spawnabl private final Environment environment; - public TallGrass(Environment environment, int x, int y) + public TallGrass(final Environment environment, int x, int y) { - super(x, y); + super(BlockSet.TALL_GRASS, environment, x, y); this.environment = environment; this.tallGrassGrowth = new SimpleDoubleProperty(0); @@ -40,37 +39,28 @@ public TallGrass(Environment environment, int x, int y) @Override public void updates() { // L'animation de pousse - if (tallGrassGrowth.get() < GROWTH_TALL_GRASS_STEP) - tallGrassGrowth.set(tallGrassGrowth.get() + GROWTH_SPEED); + if (((int) (tallGrassGrowth.get())) < TallGrass.GROWTH_TALL_GRASS_STEP) + tallGrassGrowth.set(tallGrassGrowth.get() + TallGrass.GROWTH_SPEED); } - /** Joue un son et donne au joueur entre 1 et 3 de fibre */ - @Override public void breaks() - { - Environment.playSound("sound/cut.wav", false); - - for (int loot = (int) (Math.random()*3)+1; loot < LOOTS_FIBRE_MAX; loot++) - this.environment.getPlayer().pickup(new Fiber()); - this.environment.getEntities().remove(this); - } - - /** Reproduit les hautes herbes à gauche et à droite de la haute herbe parente */ + /** Reproduit des hautes herbes à gauche et à droite de celle parente */ @Override public List reproduction(Environment environment) { List children = new ArrayList<>(); boolean tallGrassMustReproduce = environment.getTicks()%TallGrass.REPRODUCTION_RATE == 0; if (tallGrassMustReproduce) { + final TileMaps tileMaps = environment.getTileMaps(); List entities = environment.getEntities(); int heightTile = environment.heightTile; int widthTile = environment.widthTile; - int widthMaps = environment.getTileMaps().getWidth(); - int heightMaps = environment.getTileMaps().getHeight(); + int widthMaps = tileMaps.getWidth(); + int heightMaps = tileMaps.getHeight(); int x = -1; int y = (int) (getY()/heightTile)+1; - // Check si personne à côté + // Check si aucune entité ne se trouve à coté int left = 0; int right = 0; for (Entity entity : entities) { boolean haveAnEntityOnLeft = entity.getX() == (getX() - widthTile) && entity.getY() == getY(); @@ -91,13 +81,15 @@ else if (rightIsAvailable) // La place sur la carte boolean isntOutTheMap = (x >= 0 && x < widthMaps) && (y >= 0 && y < heightMaps); if (isntOutTheMap) { - boolean dontHaveTile = environment.getTileMaps().getTile(x, y) != TileMaps.SKY; + boolean dontHaveTile = !tileMaps.isSkyTile(x, y); if (dontHaveTile) { int xTallGrassChildren = (int) ((left == 0) ? (getX() - widthTile) : (getX() + widthTile)); int yTallGrassChildren = (int) getY(); - children.add(new TallGrass(this.environment, xTallGrassChildren, yTallGrassChildren)); + TallGrass tallGrassChildren = new TallGrass(environment, xTallGrassChildren, yTallGrassChildren); + tallGrassChildren.setRect(widthTile, heightTile); + children.add(tallGrassChildren); } } } @@ -109,7 +101,10 @@ else if (rightIsAvailable) { this.setX(x); this.setY(y); - this.environment.getEntities().add(0, this); + this.setRect(this.environment.widthTile, this.environment.heightTile); + + this.environment.getEntities().add(this); + this.environment.getBlocks().add(this); } diff --git a/src/main/java/fr/sae/terraria/modele/entities/blocks/Torch.java b/src/main/java/fr/sae/terraria/modele/entities/blocks/Torch.java deleted file mode 100644 index 84b5fe2..0000000 --- a/src/main/java/fr/sae/terraria/modele/entities/blocks/Torch.java +++ /dev/null @@ -1,56 +0,0 @@ -package fr.sae.terraria.modele.entities.blocks; - -import fr.sae.terraria.modele.Environment; -import fr.sae.terraria.modele.entities.entity.PlaceableObjectType; -import fr.sae.terraria.modele.entities.entity.StowableObjectType; -import fr.sae.terraria.modele.entities.player.Player; -import fr.sae.terraria.modele.entities.player.inventory.Inventory; - -import java.util.Objects; - - -public class Torch extends Block implements StowableObjectType, PlaceableObjectType -{ - private final Environment environment; - - private double xOrigin; - private double yOrigin; - - - public Torch(Environment environment, int x, int y) - { - super(x, y); - this.environment = environment; - - this.xOrigin = x; - this.yOrigin = y; - } - - @Override public void updates() { /* TODO document why this method is empty */ } - - @Override public void breaks() - { - this.breakAnimation(environment, this, xOrigin, yOrigin); - - this.environment.getPlayer().pickup(this); - - this.environment.getEntities().remove(this); - this.environment.getTorches().remove(this); - } - - @Override public void place(int x, int y) - { - Environment.playSound("sound/axchop.wav", false); - - Torch entity = new Torch(this.environment, x*environment.widthTile, y*environment.heightTile); - entity.setRect(environment.widthTile, environment.heightTile); - - Player player = this.environment.getPlayer(); - Inventory inventory = player.getInventory(); - if (!Objects.isNull(player.getStackSelected())) - inventory.get().get(inventory.getPosCursor()).remove(); - - environment.getEntities().add(0, entity); - environment.getTorches().add(0, entity); - } -} \ No newline at end of file diff --git a/src/main/java/fr/sae/terraria/modele/entities/blocks/Tree.java b/src/main/java/fr/sae/terraria/modele/entities/blocks/Tree.java index 741add5..f48365b 100644 --- a/src/main/java/fr/sae/terraria/modele/entities/blocks/Tree.java +++ b/src/main/java/fr/sae/terraria/modele/entities/blocks/Tree.java @@ -2,38 +2,30 @@ import fr.sae.terraria.modele.Environment; import fr.sae.terraria.modele.entities.entity.SpawnableObjectType; -import fr.sae.terraria.modele.entities.items.Wood; public class Tree extends Block implements SpawnableObjectType { - public static final int WHEN_SPAWN_A_TREE = 5_000; public static final double TREE_SPAWN_RATE = .2; + public static final double TREE_CLUSTER = 10; + public static final int STICKS_DROP = 3; private final Environment environment; - public Tree(Environment environment, int x, int y) + public Tree(final Environment environment, int x, int y) { - super(x, y); + super(BlockSet.TREE, environment, x, y); this.environment = environment; } - public Tree(Environment environment) { this(environment, 0, 0); } - - @Override public void updates() { /* TODO document why this method is empty */ } - - @Override public void breaks() - { - // Environment.playSound("sound/grassyStep.wav", false); - this.environment.getPlayer().pickup(new Wood()); - this.environment.getEntities().remove(this); - } + public Tree(final Environment environment) { this(environment, 0, 0); } @Override public void spawn(int x, int y) { this.setX(x); this.setY(y); - this.environment.getEntities().add(0, this); + this.environment.getEntities().add(this); + this.environment.getTrees().add(this); } } diff --git a/src/main/java/fr/sae/terraria/modele/entities/entity/Animation.java b/src/main/java/fr/sae/terraria/modele/entities/entity/Animation.java index 6a77374..11364ec 100644 --- a/src/main/java/fr/sae/terraria/modele/entities/entity/Animation.java +++ b/src/main/java/fr/sae/terraria/modele/entities/entity/Animation.java @@ -1,5 +1,6 @@ package fr.sae.terraria.modele.entities.entity; +import fr.sae.terraria.vue.entities.PlayerView; import javafx.beans.property.DoubleProperty; import javafx.beans.property.SimpleDoubleProperty; @@ -7,8 +8,8 @@ /** *

Animation

*

Description:

- *

Gére uniquement la valeurs du frame pour que la vue sachent sur quel frame doit afficher l'image.

- * @see fr.sae.terraria.vue.PlayerView + *

Gère uniquement la valeur du frame pour que la vue sache sur quel frame elle doit se placer

+ * @see PlayerView */ public class Animation { @@ -39,8 +40,9 @@ public void loop() public double getFrame() { return this.frame.get(); } + public double getEndFrame() { return this.endFrame; } public DoubleProperty getFrameProperty() { return this.frame; } - /** Spécifie quand l'animation sur le Sprite Sheet doit s'arrêter */ + /** Spécifie à quelle frame l'animation sur le Sprite Sheet doit s'arrêter */ public void setEndFrame(int newEndFrame) { this.endFrame = newEndFrame; } } diff --git a/src/main/java/fr/sae/terraria/modele/entities/entity/BreakableObjectType.java b/src/main/java/fr/sae/terraria/modele/entities/entity/BreakableObjectType.java index c986cc2..ea05aa6 100644 --- a/src/main/java/fr/sae/terraria/modele/entities/entity/BreakableObjectType.java +++ b/src/main/java/fr/sae/terraria/modele/entities/entity/BreakableObjectType.java @@ -5,7 +5,7 @@ *

Breakable Object Type

*

Interface utile à un objet qui hérite d'Entity

*

Description:

- *

Determine un objet qui est cassable

+ *

Détermine un objet cassable

* * @see Entity * @author CHRZASCZCZ Naulan @@ -15,12 +15,8 @@ public interface BreakableObjectType /** - * Fonction appelée lorsqu'une entité tante de casser une autre entité + * Fonction appelée lorsqu'une entité tente de casser une autre entité * Permet de faire des actions personnalisées. - * - * @see fr.sae.terraria.modele.entities.blocks.Dirt - * @see fr.sae.terraria.modele.entities.blocks.TallGrass - * @see fr.sae.terraria.modele.entities.blocks.Stone */ void breaks(); } diff --git a/src/main/java/fr/sae/terraria/modele/entities/entity/CollapsibleObjectType.java b/src/main/java/fr/sae/terraria/modele/entities/entity/CollapsibleObjectType.java index 9d57e40..b9b299f 100644 --- a/src/main/java/fr/sae/terraria/modele/entities/entity/CollapsibleObjectType.java +++ b/src/main/java/fr/sae/terraria/modele/entities/entity/CollapsibleObjectType.java @@ -5,8 +5,8 @@ *

Collapsible Object Type

*

Interface utile à un objet qui hérite d'Entity

*

Description:

- *

Determine les objets qui sont touchable par une autre entité

- *

Il détermine surtout les objets qui sont touchable avec des flèches ou des outils qui inflige des dégâts, qui peuvent en général avoir des dégâts à cause de ses éléments

+ *

Détermine les objets qui sont touchable par d'autres entités

+ *

Il détermine surtout les objets qui sont touchable avec des flèches ou des outils qui infligent des dégâts, qui peuvent en général avoir des dégâts à cause de ces éléments

* * @see Entity * @author CHRZASZCZ Naulan @@ -16,8 +16,8 @@ public interface CollapsibleObjectType /** - * Fonction qui est appelée lorsqu'une entité touche un autre par n'importe quel manière en excluent les collisions entre collision - * Permet de faire des actions personnalisées par entité lorsque une entitée touche un autre + * Fonction qui est appelée lorsqu'une entité est touchée par une autre entité par n'importe quel moyen en excluant les collisions entre collision + * Permet de faire des actions personnalisées par entité lorsque une entité en touche une autre * * @see fr.sae.terraria.modele.entities.Rabbit */ diff --git a/src/main/java/fr/sae/terraria/modele/entities/entity/CollideObjectType.java b/src/main/java/fr/sae/terraria/modele/entities/entity/CollideObjectType.java index 89efdb9..66a8d12 100644 --- a/src/main/java/fr/sae/terraria/modele/entities/entity/CollideObjectType.java +++ b/src/main/java/fr/sae/terraria/modele/entities/entity/CollideObjectType.java @@ -5,8 +5,8 @@ *

CollideObjectType

*

Interface utile à un objet qui hérite d'Entity

*

Description:

- *

Permet de discerner les entités qui ne sont pas des objects qui doit rentré en collisions avec d'autre entité

- *

Cela peut êtres utile sur les elements qui doit êtres au premier plan et d'autre element qui doit êtres à l'arrière plan

+ *

Permet de discerner les entités qui ne sont pas des objects et qui ont des collisions avec d'autres entités

+ *

Cela peut être utile sur les elements qui doivent êtres au premier plan et d'autre element qui doit êtres à l'arrière plan

* * @see Entity * @author CHRZASZCZ Naulan @@ -18,8 +18,8 @@ public interface CollideObjectType /** * Permet d'appliquer des collisions à l'entité qui l'utilise sur son environment. - * Pour pouvoir être fonctionnel, il doit faire appelle à "super.collide()" est de la rangé dans une variable - * de type Map pour permettre d'avoir des données relatif sur où il entre en collision + * Pour pouvoir être fonctionnelle, elle doit faire appel à "super.collide()" et de ranger son return dans une variable + * de type Map pour permettre d'avoir des données relatives sur les endroit ou l'entité entre en collision avec une autre * * @see Entity */ diff --git a/src/main/java/fr/sae/terraria/modele/entities/entity/EatableObjectType.java b/src/main/java/fr/sae/terraria/modele/entities/entity/ConsumableObjectType.java similarity index 65% rename from src/main/java/fr/sae/terraria/modele/entities/entity/EatableObjectType.java rename to src/main/java/fr/sae/terraria/modele/entities/entity/ConsumableObjectType.java index 5293bd8..88c107b 100644 --- a/src/main/java/fr/sae/terraria/modele/entities/entity/EatableObjectType.java +++ b/src/main/java/fr/sae/terraria/modele/entities/entity/ConsumableObjectType.java @@ -2,23 +2,22 @@ /** - *

Eatable Object Type

+ *

Consumable Object Type

*

Interface utile sur les objets de type rangeable dans l'inventaire

*

Description:

- *

Permet de discerner les objets qui sont mangeable par une entité ou ceux qui ne le sont pas

+ *

Permet de discerner les objets qui sont consommable par une entité ou ceux qui ne le sont pas

* * @see fr.sae.terraria.modele.entities.items.Item + * * @author CHRZASZCZ Naulan */ -public interface EatableObjectType +public interface ConsumableObjectType { /** * Permet d'appliquer des actions lorsque qu'il mange l'aliment qui est dans la main de l'entité. * Permet de faire des actions personnalisées lorsque l'action manger est activé. - * - * @see fr.sae.terraria.modele.entities.items.Meat */ - void eat(); + void consumes(); } diff --git a/src/main/java/fr/sae/terraria/modele/entities/entity/Entity.java b/src/main/java/fr/sae/terraria/modele/entities/entity/Entity.java index f96fd29..272702a 100644 --- a/src/main/java/fr/sae/terraria/modele/entities/entity/Entity.java +++ b/src/main/java/fr/sae/terraria/modele/entities/entity/Entity.java @@ -1,43 +1,22 @@ package fr.sae.terraria.modele.entities.entity; -import fr.sae.terraria.modele.Environment; -import fr.sae.terraria.modele.TileMaps; -import fr.sae.terraria.modele.entities.Slime; import javafx.beans.property.DoubleProperty; import javafx.beans.property.SimpleDoubleProperty; -import java.util.HashMap; -import java.util.Map; - /** *

La classes Entity

*

Description:

- * *

Correspond à un element physique qui doit avoir des coordonnées sur un environment.

- *

contient des fonctions privates qui peuvent êtres implémenter grâce au interface mise à disposition au sain du même package

- *

- *

C'est interfaces agissent comme une sorte de pâte à modelé, ils permettent surtout de - * rendre public les fonctions de Entity qui sont eux protected

* - *

Comment l'utiliser ?

- *

Il suffit d'extend des objects qui vous souhaitez êtres des entitées

- *

Exemple de code qui hérite de Entity:

- * - *

Donc sur cette exemple dans le jeu, le lapin est considèrer comme une entités.

- *

- *

Toutes les méthodes/fonctions protected sont appelable vers l'extérieur d'un classes qui l'hérite grâce à des interfaces.

- *

Donc pour avoir correctement les fonctions:

- * - *

Sont implementable grâce à l'interface MovableObjectType

* @see CollideObjectType - * @see MovableObjectType * @see ReproductiveObjectType * @see StowableObjectType * @see BreakableObjectType * @see CollapsibleObjectType * @see PlaceableObjectType - * @see EatableObjectType + * @see ConsumableObjectType + * * * @author CHRZASZCZ Naulan */ @@ -53,14 +32,10 @@ public abstract class Entity protected final DoubleProperty x; protected final DoubleProperty y; - protected final Gravity gravity = new Gravity(); protected Animation animation = null; protected Rect rect = null; - protected double velocity; protected double pvMax; - protected boolean air; - public int[] offset; /** @@ -76,146 +51,29 @@ protected Entity(int x, int y) this.pv = new SimpleDoubleProperty(0); this.pvMax = this.pv.get(); - this.air = false; - this.offset = new int[2]; - this.velocity = 1; } protected Entity() { this(0, 0); } /** * Il permet à chaque passage de la boucle du jeu, de faire diverses fonctions liée à l'Entité. - * Certaine fonction qui sera implementé grâce à des interfaces sera probablement obligatoirement mise dans cette fonction. + * Certaine fonction qui seront implementés grâce à des interfaces seront obligatoirement mise dans cette fonction. */ public abstract void updates(); - /** - * Permet de detectés les collisions sur la carte et de son environment. - * - * @param environment Permet de savoir les tailles des tiles et d'avoir la matrixe de données de la carte. - * @return Il vas retourner une HashMap qui ne contiendra pas de clé ou 4 clés maximum - * left, right, top, bottom sera les clés qui peuvent être present lors d'une detection de collision. - * Il permettra de faire des actions personnalisées les actions faites par l'entité suivant d'où il rentre en collision avec son environment. - */ - protected Map collide(final Environment environment) - { - - int widthTile = environment.widthTile; int heightTile = environment.heightTile; - TileMaps tileMaps = environment.getTileMaps(); - Map whereCollide = new HashMap<>(); - - // Detection vide en dessous - int yBottom = (int) (this.getY()+getRect().getHeight()-CollideObjectType.COLLISION_TOLERANCE)/heightTile; - int posX = (int) ((this.getX()+((this.offset[0] < 0) ? CollideObjectType.COLLISION_TOLERANCE : -CollideObjectType.COLLISION_TOLERANCE)) + ((this.offset[0] > 0) ? getRect().getWidth() : 0))/widthTile; - - boolean footInTheVoid = tileMaps.getTile(posX, yBottom) == TileMaps.SKY; - if (footInTheVoid) - this.air = true; - - // Detection collision gauche droite - if (this.offset[0] != Entity.IDLE) { - int yTop = (int) (getY()+CollideObjectType.COLLISION_TOLERANCE)/heightTile; - int futurePositionXLeft = (int) ((getX()+CollideObjectType.COLLISION_TOLERANCE)+(velocity*offset[0]))/widthTile; - int futurePositionXRight = (int) ((getX()+(-CollideObjectType.COLLISION_TOLERANCE)+(velocity*offset[0])) + (getRect().getWidth()))/widthTile; - - whereCollide.put("right", tileMaps.getTile(futurePositionXRight, yTop) != TileMaps.SKY || tileMaps.getTile(futurePositionXRight, yBottom) != TileMaps.SKY); - whereCollide.put("left", tileMaps.getTile(futurePositionXLeft, yTop) != TileMaps.SKY || tileMaps.getTile(futurePositionXLeft, yBottom) != TileMaps.SKY); - } - - // Detection collision en bas et en haut - if (this.offset[1] != Entity.IDLE) { - int xLeft = (int) (getX()+CollideObjectType.COLLISION_TOLERANCE)/widthTile; - int xRight = (int) ((getX()+getRect().getWidth())-CollideObjectType.COLLISION_TOLERANCE)/widthTile; - - - // Tombe - if (this.offset[1] == Entity.IS_FALLING) { - this.gravity.degInit = 0; - double futurePositionY = gravity.formulaOfTrajectory() ; - boolean isCollideBottom = tileMaps.getTile(xLeft, (int) (futurePositionY + this.rect.getHeight())/heightTile) != TileMaps.SKY || tileMaps.getTile(xRight, (int) (futurePositionY + CollideObjectType.COLLISION_TOLERANCE +this.rect.getHeight())/heightTile) != TileMaps.SKY; - if (isCollideBottom) { - this.gravity.setJumpPosInit(this); - this.gravity.timer = 0; - this.offset[1] = Entity.IDLE; - } else setY(futurePositionY); - // Saute - } else if (this.offset[1] == Entity.IS_JUMPING) { - double futurePositionY = gravity.formulaOfTrajectory(); - - boolean isCollideTop = tileMaps.getTile(xLeft, (int) (futurePositionY + CollideObjectType.COLLISION_TOLERANCE)/heightTile) != TileMaps.SKY || tileMaps.getTile(xRight, (int) (futurePositionY + CollideObjectType.COLLISION_TOLERANCE)/heightTile) != TileMaps.SKY; - // Quand le joueur monte - if (this.gravity.flightTime >= this.gravity.timer ) { - if (isCollideTop) { - this.fall(); - this.gravity.timer = 0; - this.gravity.setJumpPosInit(this); - } else this.setY(futurePositionY); - // Quand le joueur decent - } else { - boolean isCollideBottom = tileMaps.getTile(xLeft, (int) ((futurePositionY + this.rect.getHeight()) - CollideObjectType.COLLISION_TOLERANCE)/heightTile) != TileMaps.SKY || tileMaps.getTile(xRight,(int) ((futurePositionY + this.rect.getHeight()) - CollideObjectType.COLLISION_TOLERANCE)/heightTile) != TileMaps.SKY; - - if (isCollideTop) { - this.fall(); - } else if (isCollideBottom) { - this.gravity.setJumpPosInit(this); - this.gravity.timer = 0; - this.offset[1] = Entity.IDLE; - this.air = false; - } else this.setY(futurePositionY); - } - } - } else if (this.air) { - this.gravity.degInit = 0; - int xLeft = (int) (getX()+CollideObjectType.COLLISION_TOLERANCE)/widthTile; - int xRight = (int) (getX()-CollideObjectType.COLLISION_TOLERANCE+getRect().getWidth())/widthTile; - double futurePositionY = this.gravity.formulaOfTrajectory() + this.rect.getHeight(); - - boolean isCollideBottom = tileMaps.getTile(xLeft, (int) (futurePositionY - CollideObjectType.COLLISION_TOLERANCE)/heightTile) != TileMaps.SKY || tileMaps.getTile(xRight, (int) (futurePositionY - CollideObjectType.COLLISION_TOLERANCE)/heightTile) != TileMaps.SKY; - if (isCollideBottom) { - this.offset[1] = Entity.IDLE; - this.air = false; - this.gravity.setJumpPosInit(this); - } else setY(futurePositionY - this.rect.getHeight()); - } - - return whereCollide; - } - - protected void moveRight() { this.offset[0] = Entity.IS_MOVING_RIGHT; } - protected void moveLeft() { this.offset[0] = Entity.IS_MOVING_LEFT; } - protected void jump() { this.offset[1] = Entity.IS_JUMPING; } - protected void fall() { this.offset[1] = Entity.IS_FALLING; } - - /** - * Lorsque le joueur sort de l'ecran et/ou de la carte, la fonction retourne une valeurs boolean qui sera manipulable sur les classes qui l'héritera. - * @param environment Permet d'avoir les informations naicessaire sur la carte et l'écran pour que l'entité ne sorte pas. - * - * @return false = ne sort pas | true = sort de l'écran soit vers la droite ou soit vers le bas - */ - protected boolean worldLimit(final Environment environment) - { - double widthMap = (environment.getTileMaps().getWidth()*environment.scaleMultiplicatorWidth*TileMaps.TILE_DEFAULT_SIZE) ; - - boolean exceedsScreenOnLeft = offset[0] == Entity.IS_MOVING_LEFT && getX() < 0; - boolean exceedsScreenOnRight = offset[0] == Entity.IS_MOVING_RIGHT && getX() > (widthMap - getRect().getWidth()); - return (exceedsScreenOnLeft || exceedsScreenOnRight); - } + public DoubleProperty pvProperty() { return this.pv; } + public DoubleProperty xProperty() { return this.x; } + public DoubleProperty yProperty(){ return this.y; } - public DoubleProperty getPvProperty() { return this.pv; } - public DoubleProperty getXProperty() { return this.x; } - public DoubleProperty getYProperty(){ return this.y; } public Animation getAnimation() { return this.animation; } - public Gravity getGravity() { return this.gravity; } public Rect getRect() { return this.rect; } - public double getVelocity() { return this.velocity; } - public double getPvMax() { return this.pv.get(); } + public double getPvMax() { return this.pvMax; } public double getPv() { return this.pv.get(); } public double getX() { return this.x.get(); } public double getY() { return this.y.get(); } public void setRect(int width, int height) { this.rect = new Rect(x.get(), y.get(), width, height); } - public void setVelocity(double velocity) { this.velocity = velocity; } public void setPv(double pv) { this.pv.set(pv); this.pvMax = pv;} public void setX(double x) { this.x.set(x); } public void setY(double y) { this.y.set(y); } diff --git a/src/main/java/fr/sae/terraria/modele/entities/entity/EntityMovable.java b/src/main/java/fr/sae/terraria/modele/entities/entity/EntityMovable.java new file mode 100644 index 0000000..1f58418 --- /dev/null +++ b/src/main/java/fr/sae/terraria/modele/entities/entity/EntityMovable.java @@ -0,0 +1,169 @@ +package fr.sae.terraria.modele.entities.entity; + +import fr.sae.terraria.modele.Environment; +import fr.sae.terraria.modele.TileMaps; +import fr.sae.terraria.modele.TileSet; + +import java.util.HashMap; +import java.util.Map; + + +public abstract class EntityMovable extends Entity +{ + protected final Environment environment; + protected final Gravity gravity; + + public final int[] offset; + + protected double velocity; + protected boolean air; + + + protected EntityMovable(final Environment environment, int x, int y) + { + super(x, y); + this.environment = environment; + + this.gravity = new Gravity(); + this.offset = new int[2]; + this.air = false; + this.velocity = 1; + } + + protected EntityMovable(final Environment environment) { this(environment, 0, 0); } + + @Override public abstract void updates(); + public abstract void move(); + + /** + * Permet de detectéer les collisions avec son environnement. + * + * @param environment Permet de savoir les tailles des tiles et d'avoir la matrixe de données de la carte. + * @return Elle va retourner une HashMap qui ne contiendra pas de clé ou 4 clés maximum + * left, right, top, bottom seront les clés qui peuvent être presentes lors d'une detection de collision. + * Elle permettra de faire des actions personnalisées selon l'endroit où l'entité rentre en collision. + */ + public Map collide(final Environment environment) + { + int widthTile = environment.widthTile; int heightTile = environment.heightTile; + TileMaps tileMaps = environment.getTileMaps(); + Map whereCollide = new HashMap<>(); + + // Detection vide en dessous + int yBottom = (int) (this.getY()+getRect().getHeight()-CollideObjectType.COLLISION_TOLERANCE)/heightTile; + int posX = (int) ((this.getX()+((this.offset[0] < 0) ? CollideObjectType.COLLISION_TOLERANCE : -CollideObjectType.COLLISION_TOLERANCE)) + ((this.offset[0] > 0) ? getRect().getWidth() : 0))/widthTile; + + boolean footInTheVoid = tileMaps.getTile(posX, yBottom) == TileSet.SKY.ordinal(); + if (footInTheVoid) + this.air = true; + + // Detection collision gauche droite + if (this.isMoving()) { + int yTop = (int) (getY()+CollideObjectType.COLLISION_TOLERANCE)/heightTile; + int futurPosXLeft = (int) ((getX()+CollideObjectType.COLLISION_TOLERANCE)+(velocity*offset[0]))/widthTile; + int futurPosXRight = (int) ((getX()+(-CollideObjectType.COLLISION_TOLERANCE)+(velocity*offset[0])) + (getRect().getWidth()))/widthTile; + + whereCollide.put("right", !tileMaps.isSkyTile(futurPosXRight, yTop) || !tileMaps.isSkyTile(futurPosXRight, yBottom)); + whereCollide.put("left", !tileMaps.isSkyTile(futurPosXLeft, yTop) || !tileMaps.isSkyTile(futurPosXLeft, yBottom)); + } + + // Detection collision bas et haut + if (this.offset[1] != Entity.IDLE) { + int xLeft = (int) (getX()+CollideObjectType.COLLISION_TOLERANCE)/widthTile; + int xRight = (int) ((getX()+getRect().getWidth())-CollideObjectType.COLLISION_TOLERANCE)/widthTile; + + // Tombe + if (this.isFalling()) { + this.gravity.degInit = 0; + double futurPosY = gravity.formulaOfTrajectory() ; + + boolean isCollideBottom = !tileMaps.isSkyTile(xLeft, (futurPosY + this.rect.getHeight())/heightTile) || !tileMaps.isSkyTile(xRight, (futurPosY + CollideObjectType.COLLISION_TOLERANCE +this.rect.getHeight())/heightTile); + if (isCollideBottom) { + this.gravity.setJumpPosInit(this); + this.gravity.timer = 0; + this.idleOnY(); + } else setY(futurPosY); + // Saute + } else if (this.isJumping()) { + double futurPosY = gravity.formulaOfTrajectory(); + + boolean isCollideTop = !tileMaps.isSkyTile(xLeft, (futurPosY + CollideObjectType.COLLISION_TOLERANCE)/heightTile) || !tileMaps.isSkyTile(xRight, (futurPosY + CollideObjectType.COLLISION_TOLERANCE)/heightTile); + // Quand le joueur monte + if (this.gravity.flightTime >= this.gravity.timer) { + if (isCollideTop) { + this.fall(); + this.gravity.timer = 0; + this.gravity.setJumpPosInit(this); + } else this.setY(futurPosY); + // Quand le joueur descends + } else { + boolean isCollideBottom = !tileMaps.isSkyTile(xLeft, ((futurPosY + this.rect.getHeight()) - CollideObjectType.COLLISION_TOLERANCE)/heightTile) || !tileMaps.isSkyTile(xRight, ((futurPosY + this.rect.getHeight()) - CollideObjectType.COLLISION_TOLERANCE)/heightTile); + + if (isCollideTop) { + this.fall(); + } else if (isCollideBottom) { + this.gravity.setJumpPosInit(this); + this.gravity.timer = 0; + this.idleOnY(); + this.air = false; + } else this.setY(futurPosY); + } + } + } else if (this.air) { + this.gravity.degInit = 0; + int xLeft = (int) (getX()+CollideObjectType.COLLISION_TOLERANCE)/widthTile; + int xRight = (int) (getX()-CollideObjectType.COLLISION_TOLERANCE+getRect().getWidth())/widthTile; + double futurPosY = this.gravity.formulaOfTrajectory() + this.rect.getHeight(); + + boolean isCollideBottom = !tileMaps.isSkyTile(xLeft, (futurPosY - CollideObjectType.COLLISION_TOLERANCE)/heightTile) || !tileMaps.isSkyTile(xRight, (futurPosY - CollideObjectType.COLLISION_TOLERANCE)/heightTile); + if (isCollideBottom) { + this.idleOnY(); + this.air = false; + this.gravity.setJumpPosInit(this); + } else setY(futurPosY - this.rect.getHeight()); + } + + return whereCollide; + } + + public void moveRight() { this.offset[0] = Entity.IS_MOVING_RIGHT; } + public void moveLeft() { this.offset[0] = Entity.IS_MOVING_LEFT; } + public void jump() { this.offset[1] = Entity.IS_JUMPING; } + public void fall() { this.offset[1] = Entity.IS_FALLING; } + public void idleOnX() { this.offset[0] = Entity.IDLE; } + public void idleOnY() { this.offset[1] = Entity.IDLE; } + + public boolean isMovingRight() { return this.offset[0] == Entity.IS_MOVING_RIGHT; } + public boolean isMovingLeft() { return this.offset[0] == Entity.IS_MOVING_LEFT; } + public boolean isMoving() { return this.offset[0] != Entity.IDLE; } + public boolean isJumping() { return this.offset[1] == Entity.IS_JUMPING; } + public boolean isFalling() { return this.offset[1] == Entity.IS_FALLING; } + public boolean isNotFalling() { return this.offset[1] != Entity.IS_FALLING; } + /** Quand l'entité ne bouge plus sur l'axes des X */ + public boolean isIDLEonX() { return this.offset[0] == Entity.IDLE; } + /** Quand l'entité ne bouge plus sur l'axes des Y */ + public boolean isIDLEonY() { return this.offset[1] == Entity.IDLE; } + + /** + * Lorsque le joueur sort de l'ecran et/ou de la carte, la fonction retourne une valeur boolean qui sera manipulable sur les classes qui heriteront EntityMovable. + * @param environment Permet d'avoir les informations nécessaires sur la carte et l'écran pour que l'entité ne sorte pas. + * + * @return false = ne sort pas | true = sort de l'écran soit vers la droite ou la gauche + */ + public boolean worldLimit(final Environment environment) + { + double widthMap = (environment.getTileMaps().getWidth()*environment.scaleMultiplicatorWidth*TileMaps.TILE_DEFAULT_SIZE) ; + + boolean exceedsScreenOnLeft = this.isMovingLeft() && this.getX() < 0; + boolean exceedsScreenOnRight = this.isMovingRight() && this.getX()+CollideObjectType.COLLISION_TOLERANCE+this.velocity + this.getRect().getWidth() + 3 >= widthMap; + return (exceedsScreenOnLeft || exceedsScreenOnRight); + } + + + public double getVelocity() { return this.velocity; } + public Gravity getGravity() { return this.gravity; } + public int getOffsetMoveX() { return this.offset[0]; } + public int getOffsetMoveY() { return this.offset[1]; } + + public void setVelocity(double velocity) { this.velocity = velocity; } +} diff --git a/src/main/java/fr/sae/terraria/modele/entities/entity/Gravity.java b/src/main/java/fr/sae/terraria/modele/entities/entity/Gravity.java index d97b70d..5009fb8 100644 --- a/src/main/java/fr/sae/terraria/modele/entities/entity/Gravity.java +++ b/src/main/java/fr/sae/terraria/modele/entities/entity/Gravity.java @@ -36,7 +36,7 @@ private double calcFlightTime() return ((this.vInit * this.amplitude) * Math.sin(this.degInit)) / Gravity.VALUE; } - /** Modifie le xInit et le yInit pour modifier le point de départ du saut ou de là où il tombe */ + /** Modifie le xInit et le yInit pour modifier le point de départ du saut ou de l'endroit où il tombe */ protected void setJumpPosInit(final Entity entity) { this.xInit = entity.getX(); this.yInit = entity.getY(); } diff --git a/src/main/java/fr/sae/terraria/modele/entities/entity/MovableObjectType.java b/src/main/java/fr/sae/terraria/modele/entities/entity/MovableObjectType.java deleted file mode 100644 index 3202f79..0000000 --- a/src/main/java/fr/sae/terraria/modele/entities/entity/MovableObjectType.java +++ /dev/null @@ -1,66 +0,0 @@ -package fr.sae.terraria.modele.entities.entity; - - -/** - *

Movable Object Type

- *

Interface utile à un objet qui hérite d'Entity

- * - *

Description:

- *

Il permet d'implementer les fonctions qui correspond à une entité qui doit ou qui peut bouger.

- *

Il permet surtout de rendre public les functions qui sont en protected donc pas accessible à l'extérieur de la classe

- * @see Entity - * - * @author CHRZASZCZ Naulan - */ -public interface MovableObjectType -{ - - - /** - * Permet que l'entité bouge grâce aux offset modifier à chaque passage de la boucle du jeu. - * Donc, il doit être appelé dans "updates()" pour que le joueur puisse être déplacé. - * - * @see Entity - */ - void move(); - - /** - * Permet que l'entité lors de ses déplacements, qui ne sortent pas de la carte et aussi nis de l'écran. - * Pour l'utilisé dans une classe que vous avez récemment créé, vous devez appeler la fonction dans Entité grâce à "super.worldLimit()". - * - * @see Entity - */ - void worldLimit(); - - /** - * Modifie l'indice 0 dans la variable offset qui permet de le déplacer l'entité vers la droite. - * Pour l'utilisé dans une classe que vous avez récemment créé, vous devez appeler la fonction dans Entité grâce à "super.moveRight()". - * - * @see Entity - */ - void moveRight(); - - /** - * Modifie l'indice 0 dans la variable offset qui permet de le déplacer l'entité vers la gauche. - * Pour l'utilisé dans une classe que vous avez récemment créé, vous devez appeler la fonction dans Entité grâce à "super.moveLeft()". - * - * @see Entity - */ - void moveLeft(); - - /** - * Modifie l'indice 1 dans la variable offset qui permet d'informer l'entité qui est en train de sauter - * Pour l'utilisé dans une classe que vous avez récemment créé, vous devez appeler la fonction dans Entité grâce à "super.jump()". - * - * @see Entity - */ - void jump(); - - /** - * Modifie l'indice 1 dans la variable offset qui permet d'informer l'entité qui est en train de tomber - * Pour l'utilisé dans une classe que vous avez récemment créé, vous devez appeler la fonction dans Entité grâce à "super.fall()". - * - * @see Entity - */ - void fall(); -} diff --git a/src/main/java/fr/sae/terraria/modele/entities/entity/PlaceableObjectType.java b/src/main/java/fr/sae/terraria/modele/entities/entity/PlaceableObjectType.java index c3a99df..8c66ebf 100644 --- a/src/main/java/fr/sae/terraria/modele/entities/entity/PlaceableObjectType.java +++ b/src/main/java/fr/sae/terraria/modele/entities/entity/PlaceableObjectType.java @@ -3,11 +3,11 @@ /** *

Placeable Object Type

- *

Interface utile sur les objets qui hérite de block

+ *

Interface utile sur les objets qui héritent de block

*

Description:

- *

Permet de savoir si un block sera possable sur un sol ou non

+ *

Permet de savoir si un block sera posable sur un sol ou non

* - * @see fr.sae.terraria.modele.entities.blocks.Stone + * @see Rock * @author CHRZASZCZ Naulan */ public interface PlaceableObjectType @@ -15,11 +15,11 @@ public interface PlaceableObjectType /** - * Permet d'appliquer des actions lorsque qu'il tante de poser un block + * Permet d'appliquer des actions lorsque qu'il tente de poser un block * * @param x Les coordonnées du block en x lorsqu'il va êtres poser au sol * @param y Les coordonnées du block en y lorsqu'il va êtres poser au sol - * @see fr.sae.terraria.modele.entities.blocks.Stone + * @see Rock */ void place(final int x, final int y); } diff --git a/src/main/java/fr/sae/terraria/modele/entities/entity/ReproductiveObjectType.java b/src/main/java/fr/sae/terraria/modele/entities/entity/ReproductiveObjectType.java index 66818ec..329b155 100644 --- a/src/main/java/fr/sae/terraria/modele/entities/entity/ReproductiveObjectType.java +++ b/src/main/java/fr/sae/terraria/modele/entities/entity/ReproductiveObjectType.java @@ -9,7 +9,7 @@ *

Reproduction Object Type

*

Interface utile à un objet qui hérite d'Entity

*

Description:

- *

Il permet de savoir si l'entité qui implementer cette interface est une entité qui peut se reproduire entre eux.

+ *

Il permet de savoir si l'entité qui implémente cette interface est une entité qui peut se reproduire ou non

* * @see fr.sae.terraria.modele.entities.Rabbit * @see fr.sae.terraria.modele.entities.blocks.TallGrass diff --git a/src/main/java/fr/sae/terraria/modele/entities/items/Coal.java b/src/main/java/fr/sae/terraria/modele/entities/items/Coal.java deleted file mode 100644 index 217ff53..0000000 --- a/src/main/java/fr/sae/terraria/modele/entities/items/Coal.java +++ /dev/null @@ -1,4 +0,0 @@ -package fr.sae.terraria.modele.entities.items; - - -public class Coal extends Item { } diff --git a/src/main/java/fr/sae/terraria/modele/entities/items/Fiber.java b/src/main/java/fr/sae/terraria/modele/entities/items/Fiber.java deleted file mode 100644 index e817b90..0000000 --- a/src/main/java/fr/sae/terraria/modele/entities/items/Fiber.java +++ /dev/null @@ -1,4 +0,0 @@ -package fr.sae.terraria.modele.entities.items; - - -public class Fiber extends Item { } diff --git a/src/main/java/fr/sae/terraria/modele/entities/items/Iron.java b/src/main/java/fr/sae/terraria/modele/entities/items/Iron.java deleted file mode 100644 index 4d6796e..0000000 --- a/src/main/java/fr/sae/terraria/modele/entities/items/Iron.java +++ /dev/null @@ -1,4 +0,0 @@ -package fr.sae.terraria.modele.entities.items; - - -public class Iron extends Item { } diff --git a/src/main/java/fr/sae/terraria/modele/entities/items/Item.java b/src/main/java/fr/sae/terraria/modele/entities/items/Item.java index 31c59cf..8ca86e9 100644 --- a/src/main/java/fr/sae/terraria/modele/entities/items/Item.java +++ b/src/main/java/fr/sae/terraria/modele/entities/items/Item.java @@ -3,4 +3,24 @@ import fr.sae.terraria.modele.entities.entity.StowableObjectType; -public class Item implements StowableObjectType { } +public enum Item implements StowableObjectType +{ + COAL, + FIBER, + IRON, + SILEX, + STONE, + WOOD, + STICK, + MEAT; + + + public static boolean isCoal(StowableObjectType obj) { return obj == Item.COAL; } + public static boolean isFiber(StowableObjectType obj) { return obj == Item.FIBER; } + public static boolean isIron(StowableObjectType obj) { return obj == Item.IRON; } + public static boolean isStone(StowableObjectType obj) { return obj == Item.STONE; } + public static boolean isSilex(StowableObjectType obj) { return obj == Item.SILEX; } + public static boolean isWood(StowableObjectType obj) { return obj == Item.WOOD; } + public static boolean isStick(StowableObjectType obj) { return obj == Item.STICK; } + public static boolean isMeat(StowableObjectType obj) { return obj == Item.MEAT; } +} diff --git a/src/main/java/fr/sae/terraria/modele/entities/items/Meat.java b/src/main/java/fr/sae/terraria/modele/entities/items/Meat.java index 63b1137..d5e8e8f 100644 --- a/src/main/java/fr/sae/terraria/modele/entities/items/Meat.java +++ b/src/main/java/fr/sae/terraria/modele/entities/items/Meat.java @@ -1,12 +1,13 @@ package fr.sae.terraria.modele.entities.items; import fr.sae.terraria.modele.Environment; -import fr.sae.terraria.modele.entities.entity.EatableObjectType; +import fr.sae.terraria.modele.entities.entity.ConsumableObjectType; +import fr.sae.terraria.modele.entities.entity.StowableObjectType; import fr.sae.terraria.modele.entities.player.Player; import fr.sae.terraria.modele.entities.player.inventory.Inventory; -public class Meat extends Item implements EatableObjectType +public class Meat implements ConsumableObjectType, StowableObjectType { private final Environment environment; @@ -17,15 +18,15 @@ public Meat(final Environment environment) this.environment = environment; } - @Override public void eat() + @Override public void consumes() { - Player player = environment.getPlayer(); - - if (player.getPv() < player.getPvMax()) { - Inventory inventory = player.getInventory(); + Environment.playSound("sound/eat.wav", false); + Player player = this.environment.getPlayer(); + if (player.getPv() < player.getPvMax()) player.setPv(player.getPv() + 1); - inventory.get().get(inventory.getPosCursor()).remove(); - } + + Inventory inventory = player.getInventory(); + inventory.get().get(inventory.getPosCursor()).remove(); } } diff --git a/src/main/java/fr/sae/terraria/modele/entities/items/Pierre.java b/src/main/java/fr/sae/terraria/modele/entities/items/Pierre.java deleted file mode 100644 index c481a70..0000000 --- a/src/main/java/fr/sae/terraria/modele/entities/items/Pierre.java +++ /dev/null @@ -1,4 +0,0 @@ -package fr.sae.terraria.modele.entities.items; - - -public class Pierre extends Item { } diff --git a/src/main/java/fr/sae/terraria/modele/entities/items/Silex.java b/src/main/java/fr/sae/terraria/modele/entities/items/Silex.java deleted file mode 100644 index 0efd689..0000000 --- a/src/main/java/fr/sae/terraria/modele/entities/items/Silex.java +++ /dev/null @@ -1,4 +0,0 @@ -package fr.sae.terraria.modele.entities.items; - - -public class Silex extends Item { } diff --git a/src/main/java/fr/sae/terraria/modele/entities/items/Vodka.java b/src/main/java/fr/sae/terraria/modele/entities/items/Vodka.java new file mode 100644 index 0000000..bb4871c --- /dev/null +++ b/src/main/java/fr/sae/terraria/modele/entities/items/Vodka.java @@ -0,0 +1,38 @@ +package fr.sae.terraria.modele.entities.items; + +import fr.sae.terraria.modele.Environment; +import fr.sae.terraria.modele.entities.entity.ConsumableObjectType; +import fr.sae.terraria.modele.entities.entity.StowableObjectType; +import fr.sae.terraria.modele.entities.player.Player; +import fr.sae.terraria.modele.entities.player.inventory.Inventory; + + +/** + *

EasterEgg

+ *

Description:

+ *

Se drop lorsque le joueur casse des hautes herbes et une fois bu, l'écran sera troublé

+ */ +public class Vodka implements ConsumableObjectType, StowableObjectType +{ + public static final int DRUNK_EFFECT_TIME = 600; + public static final double DROP_RATE = .1; + + private final Environment environment; + + + public Vodka(final Environment environment) + { + super(); + this.environment = environment; + } + + @Override public void consumes() + { + Environment.playSound("sound/eat.wav", false); + + Player player = environment.getPlayer(); + Inventory inventory = player.getInventory(); + inventory.get().get(inventory.getPosCursor()).remove(); + player.drunkProperty().set(true); + } +} diff --git a/src/main/java/fr/sae/terraria/modele/entities/items/Wood.java b/src/main/java/fr/sae/terraria/modele/entities/items/Wood.java deleted file mode 100644 index 1a43066..0000000 --- a/src/main/java/fr/sae/terraria/modele/entities/items/Wood.java +++ /dev/null @@ -1,3 +0,0 @@ -package fr.sae.terraria.modele.entities.items; - -public class Wood extends Item { } diff --git a/src/main/java/fr/sae/terraria/modele/entities/player/Player.java b/src/main/java/fr/sae/terraria/modele/entities/player/Player.java index d4bbf6d..4006313 100644 --- a/src/main/java/fr/sae/terraria/modele/entities/player/Player.java +++ b/src/main/java/fr/sae/terraria/modele/entities/player/Player.java @@ -1,12 +1,14 @@ package fr.sae.terraria.modele.entities.player; import fr.sae.terraria.modele.Environment; +import fr.sae.terraria.modele.TileMaps; import fr.sae.terraria.modele.entities.entity.*; import fr.sae.terraria.modele.entities.player.inventory.Inventory; import fr.sae.terraria.modele.entities.player.inventory.Stack; import fr.sae.terraria.vue.View; -import javafx.beans.property.ObjectProperty; -import javafx.beans.property.SimpleObjectProperty; +import javafx.beans.property.BooleanProperty; +import javafx.beans.property.SimpleBooleanProperty; +import javafx.geometry.Rectangle2D; import javafx.scene.image.Image; import javafx.scene.input.KeyCode; import javafx.scene.input.MouseButton; @@ -16,34 +18,34 @@ import java.util.Objects; -public class Player extends Entity implements CollideObjectType, MovableObjectType, CollapsibleObjectType, SpawnableObjectType +public class Player extends EntityMovable implements CollideObjectType, CollapsibleObjectType, SpawnableObjectType { + public static final int TIME_BEFORE_HITTING_AGAIN_THE_PLAYER = 100; public static final int BREAK_BLOCK_DISTANCE = 1; private final EnumMap keysInput; private final EnumMap mouseInput; - private final ObjectProperty objectWasPickup; - - - private final Environment environment; + private final BooleanProperty drunk; + private final BooleanProperty hit; private final Inventory inventory; private Stack stackSelected; + private int invisibilityFrame; + public Player(final Environment environment) { - super(); - this.environment = environment; + super(environment, 0, 0); + this.invisibilityFrame = 0; + this.hit = new SimpleBooleanProperty(false); + this.drunk = new SimpleBooleanProperty(false); this.inventory = new Inventory(this); this.animation = new Animation(); this.keysInput = new EnumMap<>(KeyCode.class); this.mouseInput = new EnumMap<>(MouseButton.class); - - this.objectWasPickup = new SimpleObjectProperty(null); - this.objectWasPickup.addListener((obs, oldObject, newObject) -> this.inventory.put((StowableObjectType) newObject)); } @Override public void updates() @@ -51,7 +53,7 @@ public Player(final Environment environment) // Applique les déplacements selon les valeurs de l'offset // this.setX(this.x.get() + this.offset[0] * this.velocity); - if (this.offset[1] == Entity.IDLE && !air) { + if (this.isIDLEonY() && !air) { this.gravity.xInit = this.x.get(); this.gravity.yInit = this.y.get(); this.gravity.vInit = this.velocity; @@ -60,7 +62,7 @@ public Player(final Environment environment) this.gravity.timer = .0; } - this.offset[0] = Entity.IDLE; + this.idleOnX(); this.eventInput(); this.collide(); this.worldLimit(); @@ -71,7 +73,7 @@ public Player(final Environment environment) this.animation.loop(); } - @Override public void move() { this.setX(this.getX() + this.offset[0] * this.getVelocity()); } + @Override public void move() { this.setX(this.getX() + this.getOffsetMoveX() * this.getVelocity()); } @Override public void collide() { @@ -79,37 +81,73 @@ public Player(final Environment environment) if (!whereCollide.isEmpty()) { if (whereCollide.get("left").equals(Boolean.TRUE) || whereCollide.get("right").equals(Boolean.TRUE)) - this.offset[0] = Entity.IDLE; + this.idleOnX(); } } - @Override public void hit() { } + @Override public void hit() + { + this.pv.set(this.getPv() - 1); + this.hit.set(true); + } @Override public void spawn(int x, int y) { this.setX(x); this.setY(y); - Image image = View.loadAnImage("sprites/player/player_idle.png", environment.scaleMultiplicatorWidth, environment.scaleMultiplicatorHeight); - this.setRect((int) image.getWidth(), (int) image.getHeight()); - image.cancel(); + Image img = View.loadAnImage("sprites/player/player_idle.png", environment.scaleMultiplicatorWidth, environment.scaleMultiplicatorHeight); + if (!Objects.isNull(img)) { + this.setRect((int) img.getWidth(), (int) img.getHeight()); + img.cancel(); + } else this.setRect(10, 10); this.getGravity().setXInit(x); this.getGravity().setYInit(y); } - @Override public void moveRight() { super.moveRight(); } - @Override public void moveLeft() { super.moveLeft(); } - @Override public void jump() { super.jump(); } - @Override public void fall() { super.fall(); } - - @Override public void worldLimit() + public void worldLimit() { if (super.worldLimit(this.environment)) - this.offset[0] = Entity.IDLE; + this.idleOnX(); } - /** Lie les inputs au clavier à une ou des actions. */ + public void interactWithBlock(final Rectangle2D rectangle) + { + int i = 0; + + Entity entity = this.environment.getEntities().get(i); + while (!entity.getRect().collideRect(rectangle) && i < this.environment.getEntities().size() ) { + entity = this.environment.getEntities().get(i); + i++; + } + + if (entity.getRect().collideRect(rectangle)) { + if (entity instanceof BreakableObjectType) + ((BreakableObjectType) entity).breaks(); + if (entity instanceof CollapsibleObjectType) + ((CollapsibleObjectType) entity).hit(); + this.inventory.refreshStack(); + } + } + + public void placeBlock(int xBlock, int yBlock) + { + TileMaps tileMaps = this.environment.getTileMaps(); + boolean haveAnItemOnHand = !Objects.isNull(this.getStackSelected()); + boolean goodPlace = tileMaps.isSkyTile(xBlock, yBlock); + + if (haveAnItemOnHand && goodPlace) { + this.inventory.refreshStack(); + if (!(this.getStackSelected().getItem() instanceof PlaceableObjectType) && !(this.getStackSelected().getItem() instanceof ConsumableObjectType)) + return; + + if (this.getStackSelected().getItem() instanceof PlaceableObjectType) + ((PlaceableObjectType) this.getStackSelected().getItem()).place(xBlock, yBlock); + } + } + + /** Lie les inputs du clavier à une ou des actions. */ public void eventInput() { this.inventory.eventInput(); @@ -117,7 +155,7 @@ public void eventInput() this.keysInput.forEach((key, value) -> { if (Boolean.TRUE.equals(value)) { if (key == KeyCode.Z || key == KeyCode.SPACE) - if (this.offset[1] != Entity.IS_FALLING) this.jump(); + if (this.isNotFalling()) this.jump(); if (key == KeyCode.D) this.moveRight(); @@ -127,13 +165,20 @@ else if (key == KeyCode.Q) }); } - public void pickup(StowableObjectType pickupObject) { this.objectWasPickup.set(pickupObject); } + public void pickup(StowableObjectType pickupObj) { if (!Objects.isNull(pickupObj)) this.inventory.put(pickupObj); } + + public BooleanProperty drunkProperty() { return this.drunk; } + public BooleanProperty hitProperty() { return this.hit; } public Map getMouseInput() { return this.mouseInput; } public Map getKeysInput() { return this.keysInput; } public Stack getStackSelected() { return this.stackSelected; } public Inventory getInventory() { return this.inventory; } + public boolean getHit() { return this.hit.get(); } + public int getInvisibilityFrame() { return invisibilityFrame; } public void setStackSelected(Stack stackSelected) { this.stackSelected = stackSelected; } + public void setHit(boolean b) { this.hit.set(b); } + public void setInvisibilityFrame(int ticks2) { this.invisibilityFrame = ticks2; } } diff --git a/src/main/java/fr/sae/terraria/modele/entities/player/craft/Craft.java b/src/main/java/fr/sae/terraria/modele/entities/player/craft/Craft.java new file mode 100644 index 0000000..906c1df --- /dev/null +++ b/src/main/java/fr/sae/terraria/modele/entities/player/craft/Craft.java @@ -0,0 +1,82 @@ +package fr.sae.terraria.modele.entities.player.craft; + +import fr.sae.terraria.modele.Environment; +import fr.sae.terraria.modele.entities.blocks.Block; +import fr.sae.terraria.modele.entities.blocks.BlockSet; +import fr.sae.terraria.modele.entities.items.Item; +import fr.sae.terraria.modele.entities.player.craft.recipes.Ingredient; +import fr.sae.terraria.modele.entities.player.craft.recipes.PickaxeRecipe; +import fr.sae.terraria.modele.entities.player.craft.recipes.RockRecipe; +import fr.sae.terraria.modele.entities.player.craft.recipes.TorchRecipe; +import fr.sae.terraria.modele.entities.player.inventory.Inventory; +import fr.sae.terraria.modele.entities.player.inventory.Stack; +import fr.sae.terraria.modele.entities.tools.MaterialSet; +import fr.sae.terraria.modele.entities.tools.Tool; +import fr.sae.terraria.modele.entities.tools.ToolSet; + +import java.util.Objects; + + +public class Craft +{ + + + public static Block rock(final Environment environment) + { + Inventory inventory = environment.getPlayer().getInventory(); + + Ingredient rockIngredients = RockRecipe.apply(inventory); + if (!Objects.isNull(rockIngredients)) { + Stack stack = rockIngredients.get()[0]; + stack.removeQuantity(RockRecipe.NB_STONES); + } + + return (!Objects.isNull(rockIngredients)) ? new Block(BlockSet.ROCK, environment) : null; + } + + public static Block torch(final Environment environment) + { + Inventory inventory = environment.getPlayer().getInventory(); + + Ingredient torchIngredients = TorchRecipe.apply(inventory); + if (!Objects.isNull(torchIngredients)) for (int i = 0; i < torchIngredients.get().length; i++) { + Stack stack = torchIngredients.get()[i]; + + if (Item.isStick(stack.getItem())) + stack.removeQuantity(TorchRecipe.NB_STICKS); + if (Item.isCoal(stack.getItem())) + stack.removeQuantity(TorchRecipe.NB_COALS); + } + + return (!Objects.isNull(torchIngredients)) ? new Block(BlockSet.TORCH, environment) : null; + } + + public static Tool pickaxe(final Environment environment, final MaterialSet material) + { + Inventory inventory = environment.getPlayer().getInventory(); + + Ingredient pickaxeIngredients = null; + if (MaterialSet.isWood(material)) + pickaxeIngredients = PickaxeRecipe.WoodRecipe.apply(inventory); + else if (MaterialSet.isStone(material)) + pickaxeIngredients = PickaxeRecipe.StoneRecipe.apply(inventory); + else if (MaterialSet.isIron(material)) + pickaxeIngredients = PickaxeRecipe.IronRecipe.apply(inventory); + + if (!Objects.isNull(pickaxeIngredients)) for (int i = 0; i < pickaxeIngredients.get().length; i++) { + Stack stack = pickaxeIngredients.get()[i]; + + if (Item.isStick(stack.getItem())) + stack.removeQuantity(PickaxeRecipe.NB_STICKS); + + if (MaterialSet.isWood(material) && Item.isWood(stack.getItem())) + stack.removeQuantity(PickaxeRecipe.WoodRecipe.NB_WOODS); + else if (MaterialSet.isStone(material) && Item.isStone(stack.getItem())) + stack.removeQuantity(PickaxeRecipe.StoneRecipe.NB_STONES); + else if (MaterialSet.isIron(material) && Item.isIron(stack.getItem())) + stack.removeQuantity(PickaxeRecipe.IronRecipe.NB_IRONS); + } + + return (!Objects.isNull(pickaxeIngredients)) ? new Tool(ToolSet.PICKAXE, material) : null; + } +} diff --git a/src/main/java/fr/sae/terraria/modele/entities/player/craft/recipes/Ingredient.java b/src/main/java/fr/sae/terraria/modele/entities/player/craft/recipes/Ingredient.java new file mode 100644 index 0000000..6cbe7f3 --- /dev/null +++ b/src/main/java/fr/sae/terraria/modele/entities/player/craft/recipes/Ingredient.java @@ -0,0 +1,29 @@ +package fr.sae.terraria.modele.entities.player.craft.recipes; + +import fr.sae.terraria.modele.entities.player.inventory.Stack; + +import java.util.Objects; + + +public class Ingredient +{ + private final Stack[] ingredients; + + + public Ingredient(final int nbIngredient) { this.ingredients = new Stack[nbIngredient]; } + + public int nbStacks() + { + Stack stack; + int i = 0; + do { + stack = ingredients[i]; + i++; + } while (i < ingredients.length && !Objects.isNull(stack)); + + return i; + } + + + public Stack[] get() { return this.ingredients; } +} diff --git a/src/main/java/fr/sae/terraria/modele/entities/player/craft/recipes/IngredientSet.java b/src/main/java/fr/sae/terraria/modele/entities/player/craft/recipes/IngredientSet.java new file mode 100644 index 0000000..a307d78 --- /dev/null +++ b/src/main/java/fr/sae/terraria/modele/entities/player/craft/recipes/IngredientSet.java @@ -0,0 +1,49 @@ +package fr.sae.terraria.modele.entities.player.craft.recipes; + +import fr.sae.terraria.modele.entities.items.Item; +import fr.sae.terraria.modele.entities.player.inventory.Stack; + + +public class IngredientSet +{ + + + private static boolean putStackIntoIngredientsList(final Ingredient ingredient, final Stack stack) + { + if (ingredient.get().length == 1) + ingredient.get()[0] = stack; + else ingredient.get()[ingredient.nbStacks()-1] = stack; + + return true; + } + + public static boolean sticks(final Ingredient ingredient, final Stack stack, final int nbSticks) + { + boolean haveEnoughSticks = Item.isStick(stack.getItem()) && stack.haveEnoughQuantity(nbSticks); + return haveEnoughSticks && IngredientSet.putStackIntoIngredientsList(ingredient, stack); + } + + public static boolean woods(final Ingredient ingredient, final Stack stack, final int nbWood) + { + boolean haveEnoughWoods = Item.isWood(stack.getItem()) && stack.haveEnoughQuantity(nbWood); + return haveEnoughWoods && IngredientSet.putStackIntoIngredientsList(ingredient, stack); + } + + public static boolean stones(final Ingredient ingredient, final Stack stack, final int nbStones) + { + boolean haveEnoughStones = Item.isStone(stack.getItem()) && stack.haveEnoughQuantity(nbStones); + return haveEnoughStones && IngredientSet.putStackIntoIngredientsList(ingredient, stack); + } + + public static boolean irons(final Ingredient ingredient, final Stack stack, final int nbStones) + { + boolean haveEnoughIrons = Item.isIron(stack.getItem()) && stack.haveEnoughQuantity(nbStones); + return haveEnoughIrons && IngredientSet.putStackIntoIngredientsList(ingredient, stack); + } + + public static boolean coals(final Ingredient ingredient, final Stack stack, final int nbCoals) + { + boolean haveEnoughCoals = Item.isCoal(stack.getItem()) && stack.haveEnoughQuantity(nbCoals); + return haveEnoughCoals && IngredientSet.putStackIntoIngredientsList(ingredient, stack); + } +} diff --git a/src/main/java/fr/sae/terraria/modele/entities/player/craft/recipes/PickaxeRecipe.java b/src/main/java/fr/sae/terraria/modele/entities/player/craft/recipes/PickaxeRecipe.java new file mode 100644 index 0000000..94802a1 --- /dev/null +++ b/src/main/java/fr/sae/terraria/modele/entities/player/craft/recipes/PickaxeRecipe.java @@ -0,0 +1,91 @@ +package fr.sae.terraria.modele.entities.player.craft.recipes; + +import fr.sae.terraria.modele.entities.player.inventory.Inventory; +import fr.sae.terraria.modele.entities.player.inventory.Stack; + + +public class PickaxeRecipe +{ + private static final int NB_INGREDIENTS = 2; + public static final int NB_STICKS = 2; + + + public static final class WoodRecipe + { + public static final int NB_WOODS = 3; + + + public static Ingredient apply(final Inventory inventory) + { + Ingredient ingredient = new Ingredient(PickaxeRecipe.NB_INGREDIENTS); + boolean haveEnoughForPickaxeHandler = false; + boolean haveEnoughForPickaxeHead = false; + + int i = 0; + do { + Stack stack = inventory.get().get(i); + + if (!haveEnoughForPickaxeHead) + haveEnoughForPickaxeHead = IngredientSet.woods(ingredient, stack, NB_WOODS); + if (!haveEnoughForPickaxeHandler) + haveEnoughForPickaxeHandler = IngredientSet.sticks(ingredient, stack, NB_STICKS); + + i++; + } while (i < inventory.get().size() && (!haveEnoughForPickaxeHead || !haveEnoughForPickaxeHandler)); + return (haveEnoughForPickaxeHead && haveEnoughForPickaxeHandler) ? ingredient : null; + } + } + + public static final class StoneRecipe + { + public static final int NB_STONES = 3; + + + public static Ingredient apply(final Inventory inventory) + { + Ingredient ingredient = new Ingredient(PickaxeRecipe.NB_INGREDIENTS); + boolean haveEnoughForPickaxeHandler = false; + boolean haveEnoughForPickaxeHead = false; + + int i = 0; + do { + Stack stack = inventory.get().get(i); + + if (!haveEnoughForPickaxeHead) + haveEnoughForPickaxeHead = IngredientSet.stones(ingredient, stack, NB_STONES); + if (!haveEnoughForPickaxeHandler) + haveEnoughForPickaxeHandler = IngredientSet.sticks(ingredient, stack, NB_STICKS); + + i++; + } while (i < inventory.get().size() && (!haveEnoughForPickaxeHead || !haveEnoughForPickaxeHandler)); + return (haveEnoughForPickaxeHead && haveEnoughForPickaxeHandler) ? ingredient : null; + } + } + + public static final class IronRecipe + { + public static final int NB_IRONS = 3; + + + public static Ingredient apply(final Inventory inventory) + { + Ingredient ingredient = new Ingredient(PickaxeRecipe.NB_INGREDIENTS); + boolean haveEnoughForPickaxeHandler = false; + boolean haveEnoughForPickaxeHead = false; + + int i = 0; + do { + Stack stack = inventory.get().get(i); + + if (!haveEnoughForPickaxeHead) + haveEnoughForPickaxeHead = IngredientSet.irons(ingredient, stack, NB_IRONS); + if (!haveEnoughForPickaxeHandler) + haveEnoughForPickaxeHandler = IngredientSet.sticks(ingredient, stack, NB_STICKS); + + i++; + } while (i < inventory.get().size() && (!haveEnoughForPickaxeHead || !haveEnoughForPickaxeHandler)); + + return (haveEnoughForPickaxeHead && haveEnoughForPickaxeHandler) ? ingredient : null; + } + } +} diff --git a/src/main/java/fr/sae/terraria/modele/entities/player/craft/recipes/RockRecipe.java b/src/main/java/fr/sae/terraria/modele/entities/player/craft/recipes/RockRecipe.java new file mode 100644 index 0000000..ac1e260 --- /dev/null +++ b/src/main/java/fr/sae/terraria/modele/entities/player/craft/recipes/RockRecipe.java @@ -0,0 +1,28 @@ +package fr.sae.terraria.modele.entities.player.craft.recipes; + +import fr.sae.terraria.modele.entities.player.inventory.Inventory; +import fr.sae.terraria.modele.entities.player.inventory.Stack; + + +public class RockRecipe +{ + private static final int NB_INGREDIENTS = 1; + public static final int NB_STONES = 4; + + + public static Ingredient apply(final Inventory inventory) + { + Ingredient ingredient = new Ingredient(RockRecipe.NB_INGREDIENTS); + boolean haveEnoughStone; + + int i = 0; + do { + Stack stack = inventory.get().get(i); + haveEnoughStone = IngredientSet.stones(ingredient, stack, RockRecipe.NB_STONES); + + i++; + } while (i < inventory.get().size() && !haveEnoughStone); + + return haveEnoughStone ? ingredient : null; + } +} diff --git a/src/main/java/fr/sae/terraria/modele/entities/player/craft/recipes/TorchRecipe.java b/src/main/java/fr/sae/terraria/modele/entities/player/craft/recipes/TorchRecipe.java new file mode 100644 index 0000000..b66ec31 --- /dev/null +++ b/src/main/java/fr/sae/terraria/modele/entities/player/craft/recipes/TorchRecipe.java @@ -0,0 +1,33 @@ +package fr.sae.terraria.modele.entities.player.craft.recipes; + +import fr.sae.terraria.modele.entities.player.inventory.Inventory; +import fr.sae.terraria.modele.entities.player.inventory.Stack; + + +public class TorchRecipe +{ + private static final int NB_INGREDIENTS = 2; + public static final int NB_COALS = 1; + public static final int NB_STICKS = 1; + + + public static Ingredient apply(final Inventory inventory) + { + Ingredient ingredient = new Ingredient(TorchRecipe.NB_INGREDIENTS); + boolean haveEnoughCoal = false; + boolean haveEnoughSticks = false; + + int i = 0; + do { + Stack stack = inventory.get().get(i); + + if (!haveEnoughCoal) + haveEnoughCoal = IngredientSet.coals(ingredient, stack, TorchRecipe.NB_COALS); + if (!haveEnoughSticks) + haveEnoughSticks = IngredientSet.sticks(ingredient, stack, TorchRecipe.NB_COALS); + i++; + } while (i < inventory.get().size() && (!haveEnoughCoal || !haveEnoughSticks)); + + return (haveEnoughCoal && haveEnoughSticks) ? ingredient : null; + } +} diff --git a/src/main/java/fr/sae/terraria/modele/entities/player/inventory/Inventory.java b/src/main/java/fr/sae/terraria/modele/entities/player/inventory/Inventory.java index ac39b04..76f4575 100644 --- a/src/main/java/fr/sae/terraria/modele/entities/player/inventory/Inventory.java +++ b/src/main/java/fr/sae/terraria/modele/entities/player/inventory/Inventory.java @@ -36,20 +36,37 @@ public Inventory(final Player player) this.posCursor = new SimpleIntegerProperty(0); - // Change l'item de la main du joueur - this.posCursorProperty().addListener((obs, oldV, newV) -> { - boolean isntOutOfInventoryBar = newV.intValue() >= 0 && newV.intValue() < nbElementOnOneLineOfInventory; - - if (isntOutOfInventoryBar) { - Stack stack = null; - if (this.getPosCursor() < this.get().size()) - stack = this.get().get(this.getPosCursor()); - this.player.setStackSelected(stack); + // Change l'item qui se trouve dans la main du joueur + this.cursorProperty().addListener((obs, oldPos, newPos) -> { + boolean isntOutOfInventoryBar = newPos.intValue() >= 0 && newPos.intValue() < nbElementOnOneLineOfInventory; + + if (isntOutOfInventoryBar) + refreshStack(); + }); + } + + public void refreshStack() + { + Stack stack = null; + if (this.getPosCursor() < this.get().size()) + stack = this.get().get(this.getPosCursor()); + this.player.setStackSelected(stack); + } + + private void createStack(StowableObjectType item) + { + Stack stack = new Stack(); + stack.nbItemsProperty().addListener((observable, oldValue, newValue) -> { + if (newValue.intValue() <= 0) { + this.value.remove(stack); + this.player.setStackSelected(null); } }); + stack.setItem(item); + this.value.add(stack); } - private int nbStacksIntoInventory() { return this.value.size(); } + public int nbStacksIntoInventory() { return this.value.size(); } /** * Place des objets de type rangeable dans l'inventaire. @@ -61,17 +78,7 @@ public void put(StowableObjectType item) if (nbStacksInventory < NB_BOXES_MAX) { if (nbStacksInventory == 0) { - Stack stack = new Stack(); - stack.nbItemsProperty().addListener((observable, oldValue, newValue) -> { - if (newValue.intValue() <= 0) { - this.value.remove(stack); - this.player.setStackSelected(null); - } - }); - stack.setItem(item); - stack.add(); - this.value.add(stack); - this.player.setStackSelected(stack); + this.createStack(item); } else { for (Stack stack : this.value) { int beforeSize = stack.getNbItems(); @@ -83,19 +90,9 @@ public void put(StowableObjectType item) if (beforeSize != afterSize) return; } - // Si tous les stacks present sont pleins ou aucune ne correspond à l'objet qui à étais pris, il crée un nouveau stack - Stack stack = new Stack(); - stack.nbItemsProperty().addListener((observable, oldValue, newValue) -> { - if (newValue.intValue() <= 0) { - this.value.remove(stack); - this.player.setStackSelected(null); - } - }); - stack.setItem(item); - stack.add(); - this.value.add(stack); - this.player.setStackSelected(stack); + if (this.value.size() < (Inventory.NB_BOXES_MAX / Inventory.NB_LINES)) + this.createStack(item); } } } @@ -142,13 +139,14 @@ else if (key.equals(KeyCode.DIGIT9)) this.scroll = 0; } - - public IntegerProperty posCursorProperty() { return this.posCursor; } + public IntegerProperty cursorProperty() { return this.posCursor; } + public Stack getStack() { return this.value.get(this.getPosCursor()); } public int getPosCursor() { return this.posCursor.get(); } public ObservableList get() { return this.value; } public Map getKeysInput() { return this.keysInput; } + public Player getPlayer() { return player; } public void setScroll(int newScroll) { this.scroll = newScroll; } } diff --git a/src/main/java/fr/sae/terraria/modele/entities/player/inventory/Stack.java b/src/main/java/fr/sae/terraria/modele/entities/player/inventory/Stack.java index df3565f..0eaff13 100644 --- a/src/main/java/fr/sae/terraria/modele/entities/player/inventory/Stack.java +++ b/src/main/java/fr/sae/terraria/modele/entities/player/inventory/Stack.java @@ -1,16 +1,11 @@ package fr.sae.terraria.modele.entities.player.inventory; -import fr.sae.terraria.modele.entities.Arrow; -import fr.sae.terraria.modele.entities.blocks.Dirt; -import fr.sae.terraria.modele.entities.blocks.Stone; -import fr.sae.terraria.modele.entities.blocks.TallGrass; -import fr.sae.terraria.modele.entities.blocks.Torch; +import fr.sae.terraria.modele.entities.blocks.Block; import fr.sae.terraria.modele.entities.entity.StowableObjectType; -import fr.sae.terraria.modele.entities.items.*; -import fr.sae.terraria.modele.entities.tools.Axe; -import fr.sae.terraria.modele.entities.tools.Bow; -import fr.sae.terraria.modele.entities.tools.Pickaxe; -import fr.sae.terraria.modele.entities.tools.Sword; +import fr.sae.terraria.modele.entities.items.Item; +import fr.sae.terraria.modele.entities.items.Meat; +import fr.sae.terraria.modele.entities.items.Vodka; +import fr.sae.terraria.modele.entities.tools.Tool; import javafx.beans.property.IntegerProperty; import javafx.beans.property.SimpleIntegerProperty; @@ -19,66 +14,103 @@ *

Stack

*

Objet de données lié à l'objet Inventaire.

*

Description:

- * Cette dataclass est la pour avoir l'information sur combien il y a t-il d'objet du même type sur une case de l'inventaire + * Cette dataclass est présente pour savoir combien d'objets du même type se trouvent sur une case d'inventaire */ public class Stack { public static final int MAX = 16; private StowableObjectType item = null; - private IntegerProperty nbItems; + private final IntegerProperty nbItems; public Stack() { super(); - this.nbItems = new SimpleIntegerProperty(0); + this.nbItems = new SimpleIntegerProperty(1); } - public boolean isSameItem(StowableObjectType object) + public boolean isSameItem(StowableObjectType obj) { - if (object instanceof Dirt && this.item instanceof Dirt) + if (obj instanceof Meat && this.item instanceof Meat) return true; - else if (object instanceof Stone && this.item instanceof Stone) + if (obj instanceof Vodka && this.item instanceof Vodka) return true; - else if (object instanceof TallGrass && this.item instanceof TallGrass) - return true; - else if (object instanceof Torch && this.item instanceof Torch) - return true; - else if (object instanceof Coal && this.item instanceof Coal) - return true; - else if (object instanceof Fiber && this.item instanceof Fiber) - return true; - else if (object instanceof Iron && this.item instanceof Iron) - return true; - else if (object instanceof Meat && this.item instanceof Meat) - return true; - else if (object instanceof Pierre && this.item instanceof Pierre) - return true; - else if (object instanceof Silex && this.item instanceof Silex) - return true; - else if (object instanceof Wood && this.item instanceof Wood) - return true; - else if (object instanceof Axe && this.item instanceof Axe) - return true; - else if (object instanceof Bow && this.item instanceof Bow) - return true; - else if (object instanceof Pickaxe && this.item instanceof Pickaxe) - return true; - else if (object instanceof Sword && this.item instanceof Sword) - return true; - else if (object instanceof Arrow && this.item instanceof Arrow) - return true; - else return false; + + if (obj instanceof Block && this.item instanceof Block) { + if (Block.isDirt((Block) obj) && Block.isDirt((Block) this.item)) + return true; + if (Block.isFloorTop((Block) obj) && Block.isFloorTop((Block) this.item)) + return true; + if (Block.isFloorLeft((Block) obj) && Block.isFloorLeft((Block) this.item)) + return true; + if (Block.isFloorRight((Block) obj) && Block.isFloorRight((Block) this.item)) + return true; + if (Block.isRock((Block) obj) && Block.isRock((Block) this.item)) + return true; + if (Block.isTallGrass((Block) obj) && Block.isTallGrass((Block) this.item)) + return true; + if (Block.isTorch((Block) obj) && Block.isTorch((Block) this.item)) + return true; + } + + if (obj instanceof Tool && this.item instanceof Tool) { + if (Tool.isAxe((Tool) obj) && Tool.isAxe((Tool) this.item)) + return true; + if (Tool.isBow((Tool) obj) && Tool.isBow((Tool) this.item)) + return true; + if (Tool.isPickaxe((Tool) obj) && Tool.isPickaxe((Tool) this.item)) + return true; + if (Tool.isSword((Tool) obj) && Tool.isSword((Tool) this.item)) + return true; + if (Tool.isArrow((Tool) obj) && Tool.isArrow((Tool) this.item)) + return true; + } + + if (obj instanceof Item && this.item instanceof Item) { + if (Item.isCoal(obj) && Item.isCoal(this.item)) + return true; + if (Item.isFiber(obj) && Item.isFiber(this.item)) + return true; + if (Item.isIron(obj) && Item.isIron(this.item)) + return true; + if (Item.isStone(obj) && Item.isStone(this.item)) + return true; + if (Item.isSilex(obj) && Item.isSilex(this.item)) + return true; + if (Item.isWood(obj) && Item.isWood(this.item)) + return true; + if (Item.isStick(obj) && Item.isStick(this.item)) + return true; + } + + return false; } public IntegerProperty nbItemsProperty() { return this.nbItems; } public boolean isFull() { return this.getNbItems() >= Stack.MAX; } + public boolean haveEnoughQuantity(int quantity) { return this.getNbItems() >= quantity; } public void add() { if (this.getNbItems() < Stack.MAX) this.nbItems.set(this.getNbItems() + 1); } public void remove() { if (this.getNbItems() > 0) this.nbItems.set(this.getNbItems() - 1); } + public boolean removeQuantity(int quantity) + { + if (this.getNbItems() >= quantity) { + this.nbItems.set(this.getNbItems() - quantity); + return true; + } + return false; + } + + @Override public String toString() + { + if (item instanceof Block) + return String.valueOf(((Block) item).getTypeOfBlock()); + return item.toString(); + } + public int getNbItems() { return this.nbItems.get(); } public StowableObjectType getItem() { return this.item; } diff --git a/src/main/java/fr/sae/terraria/modele/entities/tools/Axe.java b/src/main/java/fr/sae/terraria/modele/entities/tools/Axe.java deleted file mode 100644 index c8fae8f..0000000 --- a/src/main/java/fr/sae/terraria/modele/entities/tools/Axe.java +++ /dev/null @@ -1,17 +0,0 @@ -package fr.sae.terraria.modele.entities.tools; - - -public class Axe extends Tool -{ - - - public Axe() - { - super(Tool.DEFAULT_DURABILITY); - } - - @Override public void use() - { - - } -} diff --git a/src/main/java/fr/sae/terraria/modele/entities/tools/Bow.java b/src/main/java/fr/sae/terraria/modele/entities/tools/Bow.java deleted file mode 100644 index 4ab6433..0000000 --- a/src/main/java/fr/sae/terraria/modele/entities/tools/Bow.java +++ /dev/null @@ -1,14 +0,0 @@ -package fr.sae.terraria.modele.entities.tools; - - -public class Bow extends Tool -{ - - - protected Bow(int durability) { super(durability); } - - @Override public void use() - { - - } -} diff --git a/src/main/java/fr/sae/terraria/modele/entities/tools/MaterialSet.java b/src/main/java/fr/sae/terraria/modele/entities/tools/MaterialSet.java new file mode 100644 index 0000000..4c03141 --- /dev/null +++ b/src/main/java/fr/sae/terraria/modele/entities/tools/MaterialSet.java @@ -0,0 +1,14 @@ +package fr.sae.terraria.modele.entities.tools; + + +public enum MaterialSet +{ + WOOD, + STONE, + IRON; + + + public static boolean isWood(MaterialSet material) { return material == MaterialSet.WOOD; } + public static boolean isStone(MaterialSet material) { return material == MaterialSet.STONE; } + public static boolean isIron(MaterialSet material) { return material == MaterialSet.IRON; } +} diff --git a/src/main/java/fr/sae/terraria/modele/entities/tools/Pickaxe.java b/src/main/java/fr/sae/terraria/modele/entities/tools/Pickaxe.java deleted file mode 100644 index a79a948..0000000 --- a/src/main/java/fr/sae/terraria/modele/entities/tools/Pickaxe.java +++ /dev/null @@ -1,18 +0,0 @@ -package fr.sae.terraria.modele.entities.tools; - - -public class Pickaxe extends Tool -{ - - - public Pickaxe() - { - super(Tool.DEFAULT_DURABILITY); - } - - @Override public void use() - { - if (this.durability.get() > 0) - this.durability.set(this.durability.get() - 1); - } -} diff --git a/src/main/java/fr/sae/terraria/modele/entities/tools/Sword.java b/src/main/java/fr/sae/terraria/modele/entities/tools/Sword.java deleted file mode 100644 index ba09355..0000000 --- a/src/main/java/fr/sae/terraria/modele/entities/tools/Sword.java +++ /dev/null @@ -1,17 +0,0 @@ -package fr.sae.terraria.modele.entities.tools; - - -public class Sword extends Tool -{ - - - protected Sword() - { - super(Tool.DEFAULT_DURABILITY); - } - - @Override public void use() - { - - } -} diff --git a/src/main/java/fr/sae/terraria/modele/entities/tools/Tool.java b/src/main/java/fr/sae/terraria/modele/entities/tools/Tool.java index 67dcddd..f36e22b 100644 --- a/src/main/java/fr/sae/terraria/modele/entities/tools/Tool.java +++ b/src/main/java/fr/sae/terraria/modele/entities/tools/Tool.java @@ -5,20 +5,58 @@ import javafx.beans.property.SimpleIntegerProperty; -public abstract class Tool implements StowableObjectType +public class Tool implements StowableObjectType { + public static final double CRAFTED_WITH_WOOD = 1.; + public static final double CRAFTED_WITH_IRON = 1.5; + public static final int DEFAULT_DURABILITY = 100; + public static final int DEFAULT_DAMAGE = 1; - protected final IntegerProperty durability; + private final IntegerProperty durability; + private final MaterialSet material; + private final ToolSet tool; - protected Tool(final int durability) + public Tool(final ToolSet tool, final MaterialSet material) { super(); - this.durability = new SimpleIntegerProperty(durability); + this.tool = tool; + this.material = material; + this.durability = new SimpleIntegerProperty(Tool.DEFAULT_DURABILITY); } - /** Use l'outil */ - public abstract void use(); + /** Utilise l'outil */ + public void use() + { + if (this.durability.get() > 0) + this.durability.set(this.durability.get() - 1); + } + + public double damage() + { + if (this.tool == ToolSet.SWORD) { + if (this.material == MaterialSet.WOOD) + return Tool.DEFAULT_DAMAGE * Tool.CRAFTED_WITH_WOOD; + else if (this.material == MaterialSet.IRON) + return Tool.DEFAULT_DAMAGE * Tool.CRAFTED_WITH_IRON; + } else { + if (this.material == MaterialSet.WOOD) + return Tool.DEFAULT_DAMAGE * (Tool.CRAFTED_WITH_WOOD/2); + else if (this.material == MaterialSet.IRON) + return Tool.DEFAULT_DAMAGE * (Tool.CRAFTED_WITH_IRON/2); + } + return Tool.DEFAULT_DAMAGE; + } + + public static boolean isAxe(Tool tool) { return tool.getTypeOfTool() == ToolSet.AXE; } + public static boolean isBow(Tool tool) { return tool.getTypeOfTool() == ToolSet.BOW; } + public static boolean isPickaxe(Tool tool) { return tool.getTypeOfTool() == ToolSet.PICKAXE; } + public static boolean isSword(Tool tool) { return tool.getTypeOfTool() == ToolSet.SWORD; } + public static boolean isArrow(Tool tool) { return tool.getTypeOfTool() == ToolSet.ARROW; } + + + public ToolSet getTypeOfTool() { return this.tool; } + public MaterialSet getMaterial() { return this.material; } } diff --git a/src/main/java/fr/sae/terraria/modele/entities/tools/ToolSet.java b/src/main/java/fr/sae/terraria/modele/entities/tools/ToolSet.java new file mode 100644 index 0000000..93a14b9 --- /dev/null +++ b/src/main/java/fr/sae/terraria/modele/entities/tools/ToolSet.java @@ -0,0 +1,11 @@ +package fr.sae.terraria.modele.entities.tools; + + +public enum ToolSet +{ + AXE, + BOW, + PICKAXE, + SWORD, + ARROW +} \ No newline at end of file diff --git a/src/main/java/fr/sae/terraria/vue/Camera.java b/src/main/java/fr/sae/terraria/vue/Camera.java index bdd0645..8f832ea 100644 --- a/src/main/java/fr/sae/terraria/vue/Camera.java +++ b/src/main/java/fr/sae/terraria/vue/Camera.java @@ -3,7 +3,6 @@ import fr.sae.terraria.Terraria; import fr.sae.terraria.modele.Environment; import fr.sae.terraria.modele.TileMaps; -import fr.sae.terraria.modele.entities.entity.Entity; import fr.sae.terraria.modele.entities.player.Player; import javafx.beans.binding.Bindings; import javafx.scene.layout.StackPane; @@ -39,7 +38,7 @@ public Camera(final Environment environment, final StackPane paneHadCamera) this.clip.xProperty().bind( Bindings.createDoubleBinding( () -> clampRange(player.getX() - this.clip.getWidth()/2, minScrollWidthCamera, maxScrollWidthCamera), - player.getXProperty(), paneHadCamera.widthProperty() + player.xProperty(), paneHadCamera.widthProperty() ) ); @@ -47,10 +46,10 @@ public Camera(final Environment environment, final StackPane paneHadCamera) double midHeightCamera = (this.clip.getHeight()/2); double[] centerPlayerOnYIntoCamera = new double[1]; double[] gap = new double[1]; - player.getYProperty().addListener((obs, oldX, newX) -> { + player.yProperty().addListener((obs, oldX, newX) -> { // Suit le joueur centerPlayerOnYIntoCamera[0] = player.getY() - midHeightCamera; - if (player.offset[1] == Entity.IS_JUMPING) { + if (player.isJumping()) { gap[0] = player.getGravity().yInit - player.getY(); centerPlayerOnYIntoCamera[0] = player.getGravity().yInit - midHeightCamera; if (player.getGravity().timer > player.getGravity().flightTime*2 /* Légère bidouille */) @@ -58,7 +57,7 @@ public Camera(final Environment environment, final StackPane paneHadCamera) } // Décale "proprement" la caméra vers le haut - if (player.offset[1] == Entity.IDLE && gap[0] > 0) { + if (player.isIDLEonY() && gap[0] > 0) { gap[0] /= 2; centerPlayerOnYIntoCamera[0] = (player.getY() + gap[0]) - midHeightCamera; } @@ -68,7 +67,7 @@ public Camera(final Environment environment, final StackPane paneHadCamera) this.clip.yProperty().bind( Bindings.createDoubleBinding( () -> clampRange(centerPlayerOnYIntoCamera[0], minScrollHeightCamera, maxScrollHeightCamera), - player.getYProperty(), paneHadCamera.heightProperty() + player.yProperty(), paneHadCamera.heightProperty() ) ); diff --git a/src/main/java/fr/sae/terraria/vue/DrunkView.java b/src/main/java/fr/sae/terraria/vue/DrunkView.java new file mode 100644 index 0000000..fe16df4 --- /dev/null +++ b/src/main/java/fr/sae/terraria/vue/DrunkView.java @@ -0,0 +1,79 @@ +package fr.sae.terraria.vue; + +import fr.sae.terraria.modele.Environment; +import fr.sae.terraria.modele.entities.items.Vodka; +import javafx.animation.Animation; +import javafx.animation.KeyFrame; +import javafx.animation.Timeline; +import javafx.beans.property.ObjectProperty; +import javafx.beans.property.SimpleObjectProperty; +import javafx.scene.effect.DisplacementMap; +import javafx.scene.effect.FloatMap; +import javafx.scene.layout.StackPane; +import javafx.util.Duration; + +public class DrunkView { + + private static final int WIDTH_COS = 50; + private static final int HEIGHT_COS = 100; + + private FloatMap floatMap; + private ObjectProperty displacementMap; + private int startTick; + Timeline drunkTimeline; + private double timer; + Environment environment; + + public DrunkView(Environment environment, StackPane cameraView) { + this.environment = environment; + this.drunkTimeline = new Timeline(); + this.timer = 0; + this.startTick = 0; + this.floatMap = new FloatMap(); + this.displacementMap = new SimpleObjectProperty<>(); + + + drunkTimeline.setCycleCount(Animation.INDEFINITE); + KeyFrame keyFrame = new KeyFrame(Duration.seconds(0.05), (ev -> { + updateEffect(); + })); + drunkTimeline.getKeyFrames().add(keyFrame); + + floatMap.setWidth(WIDTH_COS); + floatMap.setHeight(HEIGHT_COS); + + cameraView.effectProperty().bind(displacementMap); + + environment.getPlayer().drunkProperty().addListener((o, oldVal, newVal) -> { + if (newVal) { + displacementMap.set(new DisplacementMap()); + displacementMap.getValue().setMapData(floatMap); + startTick = environment.getTicks(); + drunkTimeline.play(); + } else {dissasambleEffect();} + }); + } + + + private void updateEffect() { + + for (int i = 0; i < WIDTH_COS; i++) { + double v = (Math.cos(timer + i / 20.0 * Math.PI) - 0.5) / 40.0; + for (int j = 0; j < HEIGHT_COS; j++) { + floatMap.setSamples(i, j, 0.0f, (float) v); + } + } + timer += 0.03; + + if (startTick+ Vodka.DRUNK_EFFECT_TIME <= environment.getTicks()){ + environment.getPlayer().drunkProperty().set(false); + } + + } + + private void dissasambleEffect() { + drunkTimeline.stop(); + displacementMap.set(null); + } + +} diff --git a/src/main/java/fr/sae/terraria/vue/LightView.java b/src/main/java/fr/sae/terraria/vue/LightView.java index f80be65..c3bd47a 100644 --- a/src/main/java/fr/sae/terraria/vue/LightView.java +++ b/src/main/java/fr/sae/terraria/vue/LightView.java @@ -3,8 +3,7 @@ import fr.sae.terraria.modele.Clock; import fr.sae.terraria.modele.Environment; import fr.sae.terraria.modele.TileMaps; -import fr.sae.terraria.modele.entities.blocks.Torch; -import javafx.beans.property.SimpleDoubleProperty; +import fr.sae.terraria.modele.entities.blocks.Block; import javafx.collections.ListChangeListener; import javafx.collections.ObservableList; import javafx.scene.layout.Pane; @@ -13,6 +12,7 @@ import javafx.scene.shape.Rectangle; import javafx.scene.shape.Shape; + public class LightView { private static final int CIRCLE_RAY = 3; private static final Color NIGHT_COLOR = Color.web("#0d0d38"); @@ -25,8 +25,6 @@ public class LightView { private static int widthMap; private static int tileSize; - private final SimpleDoubleProperty opacityNightAir; - private final SimpleDoubleProperty opacityNightFade; private final Environment environment; private final TileMaps tileMaps; private final Circle torchLight; @@ -47,25 +45,22 @@ public LightView(Clock clock, Pane filterPane, Environment env) { widthMap = (int) (env.scaleMultiplicatorWidth*TileMaps.TILE_DEFAULT_SIZE*tileMaps.getWidth()); delimitationDirtStone = fullStoneArea(); - this.opacityNightAir = new SimpleDoubleProperty(.0); - this.opacityNightFade = new SimpleDoubleProperty(.8143); this.torchLight = new Circle(this.tileSize*CIRCLE_RAY); this.resetShapes(); this.addEffects(); - this.clock.minutesProperty().addListener(((obs, oldV, newV) -> updateOpacity())); this.filterPane.getChildren().addAll(this.actualTunnel, this.actualFade, this.actualAir); - this.initTochListener(env.getTorches()); + this.initTorchListener(env.getTorches()); } - private void initTochListener(ObservableList torches) { - torches.addListener((ListChangeListener) c -> { + private void initTorchListener(ObservableList torches) { + torches.addListener((ListChangeListener) c -> { while(c.next()){ this.filterPane.getChildren().clear(); - addTochLights(); + addTorchLights(); if (c.wasRemoved()){ resetShapes(); @@ -96,14 +91,6 @@ else if (c.wasAdded()){ }}); } - private void updateOpacity() - { - if (this.clock.getMinutes() > Clock.MINUTES_IN_A_DAY/2) - this.opacityNightAir.set(((this.clock.getMinutes()*(2. /* Compensation temps */))/Clock.MINUTES_IN_A_DAY) - (1.1 /* Décallage */)); - else this.opacityNightAir.set(((Clock.MINUTES_IN_A_DAY - (this.clock.getMinutes()*(4. /* Compensation temps */)))/Clock.MINUTES_IN_A_DAY) - (.1 /* Décallage */)); - } - - private int fullStoneArea() { int line = 0; @@ -116,7 +103,7 @@ private int fullStoneArea() column = 0; while (column < this.tileMaps.getWidth() && !found && !wrongLine) { - if (this.tileMaps.getTile(column, line) != TileMaps.STONE) + if (!this.tileMaps.isRockTile(column, line)) wrongLine = true; else if (column == this.tileMaps.getWidth() - 1) found = true; @@ -135,6 +122,7 @@ private void resetShapes() this.actualTunnel.setLayoutY(tileSize*(delimitationDirtStone+1)); this.actualFade.setLayoutY(this.actualTunnel.getLayoutY()-tileSize); + } private void addEffects() @@ -143,12 +131,12 @@ private void addEffects() this.actualAir.setFill(NIGHT_COLOR); this.actualTunnel.setFill(NIGHT_COLOR); - this.actualTunnel.opacityProperty().bind(this.opacityNightFade); - this.actualFade.opacityProperty().bind(this.opacityNightFade); - this.actualAir.opacityProperty().bind(this.opacityNightAir); + this.actualAir.opacityProperty().bind(this.clock.opacityNightFilterProperty()); + this.actualFade.setOpacity(.8); + this.actualTunnel.setOpacity(.8); } - private void addTochLights() + private void addTorchLights() { for (int i = 0; i < this.environment.getTorches().size() ; i ++){ Circle torchLight = new Circle(tileSize*CIRCLE_RAY); diff --git a/src/main/java/fr/sae/terraria/vue/PlayerView.java b/src/main/java/fr/sae/terraria/vue/PlayerView.java deleted file mode 100644 index 6c612ec..0000000 --- a/src/main/java/fr/sae/terraria/vue/PlayerView.java +++ /dev/null @@ -1,70 +0,0 @@ -package fr.sae.terraria.vue; - -import fr.sae.terraria.modele.entities.entity.Entity; -import fr.sae.terraria.modele.entities.player.Player; -import javafx.geometry.Rectangle2D; -import javafx.scene.image.Image; -import javafx.scene.image.ImageView; -import javafx.scene.layout.Pane; - - -public class PlayerView -{ - private final ImageView playerImgView; - - private final Image playerMoveRightImg; - private final Image playerMoveLeftImg; - private final Image playerIdleImg; - - private final Player player; - - private int widthPlayer; - private int heightPlayer; - - - public PlayerView(Player player, double scaleMultiplicatorWidth, double scaleMultiplicatorHeight) - { - this.player = player; - - this.playerIdleImg = View.loadAnImage("sprites/player/player_idle.png", scaleMultiplicatorWidth, scaleMultiplicatorHeight); - this.playerMoveRightImg = View.loadAnImage("sprites/player/player_moveRight.png", scaleMultiplicatorWidth, scaleMultiplicatorHeight); - this.playerMoveLeftImg = View.loadAnImage("sprites/player/player_moveLeft.png", scaleMultiplicatorWidth, scaleMultiplicatorHeight); - - this.widthPlayer = (int) this.playerIdleImg.getWidth(); - this.heightPlayer = (int) this.playerIdleImg.getHeight(); - - this.playerImgView = View.createImageView(player, playerIdleImg); - } - - /** Applique l'animation sur le joueur */ - private void setAnimation() - { - // Change la limite de frame de l'animation selon le sprite sheet chargé - this.playerImgView.imageProperty().addListener((obs, oldImg, newImg) -> { - int newEndFrame = (int) (newImg.getWidth() / widthPlayer); - if (this.player.getAnimation().getFrame() >= newEndFrame) - this.player.getAnimation().reset(); - this.player.getAnimation().setEndFrame(newEndFrame); - }); - - player.getAnimation().getFrameProperty().addListener((obs, oldFrame, newFrame) -> { - this.playerImgView.setViewport(new Rectangle2D(0, 0, widthPlayer, heightPlayer)); - if (player.offset[0] == Entity.IDLE && player.offset[1] == Entity.IDLE) - this.playerImgView.setImage(this.playerIdleImg); - - if (player.offset[0] == Entity.IS_MOVING_RIGHT || player.offset[0] == Entity.IS_MOVING_LEFT) { - Rectangle2D frameRect = new Rectangle2D((newFrame.intValue() * widthPlayer), 0, widthPlayer, heightPlayer); - - this.playerImgView.setViewport(frameRect); - this.playerImgView.setImage((player.offset[0] == -1) ? playerMoveLeftImg : playerMoveRightImg); - } - }); - } - - /** Synchronise les coordonnées en x et y du joueur avec l'image et ensuite l'affiche sur le Pane */ - public void displayPlayer(final Pane display) - { - this.setAnimation(); - display.getChildren().add(playerImgView); - } -} diff --git a/src/main/java/fr/sae/terraria/vue/RabbitView.java b/src/main/java/fr/sae/terraria/vue/RabbitView.java deleted file mode 100644 index 0c9e533..0000000 --- a/src/main/java/fr/sae/terraria/vue/RabbitView.java +++ /dev/null @@ -1,64 +0,0 @@ -package fr.sae.terraria.vue; - -import fr.sae.terraria.modele.TileMaps; -import fr.sae.terraria.modele.entities.Rabbit; -import fr.sae.terraria.modele.entities.entity.Entity; -import javafx.geometry.Rectangle2D; -import javafx.scene.image.Image; -import javafx.scene.image.ImageView; -import javafx.scene.layout.Pane; - - -public class RabbitView -{ - private final ImageView rabbitImgView; - - private final Image rabbitLeftImg; - private final Image rabbitRightImg; - - private final Rabbit rabbit; - - private int widthTile; - private int heightTile; - - - public RabbitView(final Rabbit rabbit, double scaleMultiplicatorWidth, double scaleMultiplicatorHeight) - { - super(); - this.rabbit = rabbit; - - this.widthTile = (int) (scaleMultiplicatorWidth * TileMaps.TILE_DEFAULT_SIZE); - this.heightTile = (int) (scaleMultiplicatorHeight * TileMaps.TILE_DEFAULT_SIZE); - - this.rabbitLeftImg = View.loadAnImage("sprites/rabbit/rabbit_left.png", widthTile*4, heightTile); - this.rabbitRightImg = View.loadAnImage("sprites/rabbit/rabbit_right.png", widthTile*4, heightTile); - this.rabbitImgView = View.createImageView(rabbit, rabbitLeftImg); - } - - private void setAnimation() - { - // Change la limite de frame de l'animation selon le sprite sheet chargé - this.rabbitImgView.imageProperty().addListener((obs, oldImg, newImg) -> { - int newEndFrame = (int) (newImg.getWidth() / this.widthTile); - if (this.rabbit.getAnimation().getFrame() >= newEndFrame) - this.rabbit.getAnimation().reset(); - this.rabbit.getAnimation().setEndFrame(newEndFrame); - }); - - this.rabbit.getAnimation().getFrameProperty().addListener((obs, oldFrame, newFrame) -> { - this.rabbitImgView.setViewport(new Rectangle2D(0, 0, this.widthTile, this.heightTile)); - if (this.rabbit.offset[0] == Entity.IS_MOVING_RIGHT || this.rabbit.offset[0] == Entity.IS_MOVING_LEFT) { - Rectangle2D frameRect = new Rectangle2D((newFrame.intValue() * this.widthTile), 0, this.widthTile, this.heightTile); - - this.rabbitImgView.setViewport(frameRect); - this.rabbitImgView.setImage((this.rabbit.offset[0] == -1) ? this.rabbitLeftImg : this.rabbitRightImg); - } - }); - } - - public void displayRabbit(final Pane display) - { - this.setAnimation(); - display.getChildren().add(this.rabbitImgView); - } -} diff --git a/src/main/java/fr/sae/terraria/vue/SlimeView.java b/src/main/java/fr/sae/terraria/vue/SlimeView.java deleted file mode 100644 index 88df45c..0000000 --- a/src/main/java/fr/sae/terraria/vue/SlimeView.java +++ /dev/null @@ -1,48 +0,0 @@ -package fr.sae.terraria.vue; - -import fr.sae.terraria.modele.TileMaps; -import fr.sae.terraria.modele.entities.Slime; -import fr.sae.terraria.modele.entities.entity.Entity; -import javafx.geometry.Rectangle2D; -import javafx.scene.image.Image; -import javafx.scene.image.ImageView; -import javafx.scene.layout.Pane; - - -public class SlimeView -{ - private final ImageView slimeImgView; - - private final Image slimeImg; - - private final Slime slime; - private int widthTile; - private int heightTile; - - - public SlimeView(final Slime slime, double scaleMultiplicatorWidth, double scaleMultiplicatorHeight) - { - super(); - this.slime = slime; - - this.widthTile = (int) (scaleMultiplicatorWidth * TileMaps.TILE_DEFAULT_SIZE); - this.heightTile = (int) (scaleMultiplicatorHeight * TileMaps.TILE_DEFAULT_SIZE); - - this.slimeImg = View.loadAnImage("sprites/slimes/green_slime.png", widthTile*4, heightTile); - this.slimeImgView = View.createImageView(slime, slimeImg); - } - - private void setAnimation() - { - this.slime.getAnimation().getFrameProperty().addListener((obs, oldV, newV) -> { - Rectangle2D frameRect = new Rectangle2D(newV.intValue() * this.widthTile, 0, this.widthTile, this.heightTile); - this.slimeImgView.setViewport(frameRect); - }); - } - - public void displaySlime(final Pane display) - { - this.setAnimation(); - display.getChildren().add(this.slimeImgView); - } -} diff --git a/src/main/java/fr/sae/terraria/vue/TileMapsView.java b/src/main/java/fr/sae/terraria/vue/TileMapsView.java index eb01e53..811dc87 100644 --- a/src/main/java/fr/sae/terraria/vue/TileMapsView.java +++ b/src/main/java/fr/sae/terraria/vue/TileMapsView.java @@ -4,11 +4,15 @@ import fr.sae.terraria.modele.TileMaps; import fr.sae.terraria.modele.entities.Rabbit; import fr.sae.terraria.modele.entities.Slime; -import fr.sae.terraria.modele.entities.blocks.*; -import fr.sae.terraria.modele.entities.entity.Entity; +import fr.sae.terraria.modele.entities.blocks.Block; +import fr.sae.terraria.modele.entities.blocks.BlockSet; +import fr.sae.terraria.modele.entities.blocks.TallGrass; +import fr.sae.terraria.modele.entities.blocks.Tree; +import fr.sae.terraria.vue.entities.RabbitView; +import fr.sae.terraria.vue.entities.SlimeView; import javafx.collections.ListChangeListener; import javafx.geometry.Rectangle2D; -import javafx.scene.Node; +import javafx.scene.Group; import javafx.scene.image.Image; import javafx.scene.image.ImageView; import javafx.scene.layout.Pane; @@ -18,8 +22,23 @@ import java.util.Objects; +/** + *

Tile maps View

+ *

Une classes qui se gère de l'affichage de la carte et de ces élèments aditionnel

+ *

Description:

+ *

Cette classe permet d'afficher, de supprimer les élèments visible à l'écran

+ * + * @author CHRZASZCZ Naulan + */ public class TileMapsView { + private final List rabbitsView; + private final List blocksView; + private final List slimesView; + // Cette liste marche differement à cause de la classes Group, cette liste conserve un groupe d'images + // La classes Group contient plus ou moins d'images selon du fait de comment il génère l'arbre. + private final List treesView; + private final Image torchImg; private final Image floorTopImg; private final Image floorLeftImg; @@ -29,6 +48,7 @@ public class TileMapsView private final Image dirtImg; private final Image tallGrassImg; + private final Pane displayHostileBeings; private final Pane display; private final Environment environment; @@ -40,7 +60,7 @@ public class TileMapsView /** * @param environment Avoir des infos relatives à son environment * @param displayTileMap Affiche la carte tuilée - * @param displayHostileBeings Affiche les êtres hostile (Animal, Joueur, ...) + * @param displayHostileBeings Affiche les entités mouvantes (Animal, Joueur, ...) */ public TileMapsView(Environment environment, Pane displayTileMap, @@ -51,10 +71,17 @@ public TileMapsView(Environment environment, super(); this.environment = environment; this.display = displayTileMap; + this.displayHostileBeings = displayHostileBeings; this.tileHeight = (int) (TileMaps.TILE_DEFAULT_SIZE * scaleMultiplicatorHeight); this.tileWidth = (int) (TileMaps.TILE_DEFAULT_SIZE * scaleMultiplicatorWidth); + this.rabbitsView = new ArrayList<>(); + this.blocksView = new ArrayList<>(); + this.slimesView = new ArrayList<>(); + this.treesView = new ArrayList<>(); + + // Génération des images this.floorTopImg = View.loadAnImage("tiles/floor-top.png", tileWidth, tileHeight); this.floorLeftImg = View.loadAnImage("tiles/floor-left.png", tileWidth, tileHeight); this.floorRightImg = View.loadAnImage("tiles/floor-right.png", tileWidth, tileHeight); @@ -64,199 +91,224 @@ public TileMapsView(Environment environment, this.treeImg = View.loadAnImage("sprites/tree-sheet.png", scaleMultiplicatorWidth, scaleMultiplicatorHeight); this.tallGrassImg = View.loadAnImage("tiles/tall-grass.png",tileWidth,tileHeight); - // Lorsqu'un élément est ajouté, il le dessine automatiquement à l'écran - environment.getEntities().addListener((ListChangeListener) c -> { - while (c.next()) { - if (c.wasAdded()) { - if (c.getList().get(0) instanceof Tree) - this.createTree((Tree) c.getList().get(0)); - if (c.getList().get(0) instanceof TallGrass) - this.createTallGrass((TallGrass) c.getList().get(0)); - if (c.getList().get(0) instanceof Rabbit) { - RabbitView rabbitView = new RabbitView((Rabbit) c.getList().get(0), scaleMultiplicatorWidth, scaleMultiplicatorHeight); - rabbitView.displayRabbit(displayHostileBeings); - } - if (c.getList().get(0) instanceof Slime) { - SlimeView slimeView = new SlimeView((Slime) c.getList().get(0), scaleMultiplicatorWidth, scaleMultiplicatorHeight); - slimeView.displaySlime(displayHostileBeings); - } + // Ajoute et supprime les elements de l'écran qui concernent les blocks + this.environment.getBlocks().addListener((ListChangeListener) this::updatesBlocksView); + // Ajoute et supprime les elements de l'écran qui concernent les lapins + this.environment.getRabbits().addListener((ListChangeListener) this::updatesRabbitView); + // Ajoute et supprime les elements de l'écran qui concernent les slimes + this.environment.getSlimes().addListener((ListChangeListener) this::updatesSlimeView); + // Ajoute et supprime un groupe d'élèments de l'écran qui concerne les arbres + this.environment.getTrees().addListener((ListChangeListener) this::updatesTreeView); + } - if (c.getList().get(0) instanceof Torch) - createTorch((Torch) c.getList().get(0)); - if (c.getList().get(0) instanceof Dirt) - displayTileMap.getChildren().add(View.createImageView(c.getList().get(0), floorTopImg)); - if (c.getList().get(0) instanceof Stone) - displayTileMap.getChildren().add(View.createImageView(c.getList().get(0), stoneImg)); + /** + * Supprime ou affiche les blocs qui sont ajouté dans la liste d'entité List blocks; + * Une fois affiché, la fonction range l'imageView crée dans la liste List blocksView; de cette classes + * + * @param c Cet argument est present car on passe cette fonction en tant que reference (this::updatesBlocksView), + * l'argument est là pour obtenir les informations concernant les modifications dans liste List blocks; + */ + private void updatesBlocksView(ListChangeListener.Change c) + { + while (c.next()) { + if (c.wasAdded()) { + ImageView blockView = new ImageView(); + Block block = c.getAddedSubList().get(0); + + blockView.setImage(null); + if (Block.isDirt(block)) { + blockView.setImage(this.dirtImg); + } else if (Block.isFloorTop(block)) { + blockView.setImage(this.floorTopImg); + } else if (Block.isFloorLeft(block)) { + blockView.setImage(this.floorLeftImg); + } else if (Block.isFloorRight(block)) { + blockView.setImage(this.floorRightImg); + } else if (Block.isRock(block)) { + blockView.setImage(this.stoneImg); + } else if (Block.isTallGrass(block)) { + blockView.setImage(this.tallGrassImg); + ((TallGrass) block).getTallGrassGrowthProperty().addListener((observable, oldValue, newValue) -> blockView.setViewport(new Rectangle2D(0, ((int) ((this.tallGrassImg.getHeight() / (TallGrass.GROWTH_TALL_GRASS_STEP) * newValue.intValue()) - tallGrassImg.getHeight())), this.tallGrassImg.getWidth(), this.tallGrassImg.getHeight()))); + } else if (Block.isTorch(block)) { + blockView.setImage(this.torchImg); } - if (c.wasRemoved()) { - // La position de l'entité - int xEntity = (int) (c.getRemoved().get(0).getRect().get().getMinX()); - int yEntity = (int) (c.getRemoved().get(0).getRect().get().getMinY()); - - // Tant qu'on n'a pas trouvé l'objet sur le Pane, il continue la boucle. - Node nodeAtDelete = null; int i = 0; - do { - Node node = display.getChildren().get(i); - int xNode = (int) (node.getTranslateX()); - int yNode = (int) (node.getTranslateY()); - - if (xNode == xEntity && yNode == yEntity) { - nodeAtDelete = node; - display.getChildren().remove(nodeAtDelete); - } - i++; - } while (i < display.getChildren().size() && Objects.isNull(nodeAtDelete)); + if (!Objects.isNull(blockView.getImage())) { + blockView.translateXProperty().bind(block.xProperty()); + blockView.translateYProperty().bind(block.yProperty()); + + this.display.getChildren().add(blockView); + this.blocksView.add(blockView); } } - }); - } - /** Decompose la carte pour afficher un à un les tiles à l'écran */ - public void displayMaps(TileMaps tiles) - { - for (int y = 0; y < tiles.getHeight() ; y++) - for (int x = 0 ; x < tiles.getWidth() ; x++) - switch (tiles.getTile(x, y)) - { - case TileMaps.STONE: - this.createStone(x, y); - break; - case TileMaps.DIRT: - this.createDirt(x, y); - break; - case TileMaps.FLOOR_TOP: - case TileMaps.FLOOR_LEFT: - case TileMaps.FLOOR_RIGHT: - this.createFloor(tiles.getTile(x, y), x, y); - break; - default: - this.errorTile(tiles.getTile(x, y)); - break; - } + if (c.wasRemoved()) { + this.display.getChildren().remove(this.blocksView.get(c.getTo())); + this.blocksView.remove(c.getTo()); + } + } } - /** Crée et affiche un block de type arbre, il sera +/- grand */ - private void createTree(final Tree tree) + /** + * Supprime ou affiche les lapins qui sont ajouté dans la liste d'entité List rabbits; + * Une fois affiché, la fonction range l'imageView crée dans la liste List rabbitsView; de cette classe + * + * @param c Cet argument est present car on passe cette fonction en tant que reference (this::updatesRabbitsView), + * l'argument est là pour obtenir les informations concernant les modifications dans liste List rabbits; + */ + private void updatesRabbitView(ListChangeListener.Change c) { - List imagesTree = new ArrayList<>(); - - int nbFoliage = ((int) (Math.random()*2))+1; - int nbTrunk = ((int) (Math.random()*3))+1; - - Rectangle2D viewportFirstFrame = new Rectangle2D(0, 0, this.tileWidth, this.tileHeight); - ImageView firstFrameView = new ImageView(); - firstFrameView.setImage(this.treeImg); - firstFrameView.setViewport(viewportFirstFrame); - imagesTree.add(firstFrameView); - for (int f = 0; f < nbFoliage; f++) { - Rectangle2D viewportSecondFrame = new Rectangle2D(0, this.tileHeight, this.tileWidth, this.tileHeight); - ImageView secondFrameView = new ImageView(); - secondFrameView.setImage(this.treeImg); - secondFrameView.setViewport(viewportSecondFrame); - imagesTree.add(secondFrameView); - } - - if (nbTrunk > 1) { - Rectangle2D viewportEndTrunk = new Rectangle2D(0, (this.tileHeight*2), this.tileWidth, this.tileHeight); - ImageView endTrunkView = new ImageView(); - endTrunkView.setImage(this.treeImg); - endTrunkView.setViewport(viewportEndTrunk); - imagesTree.add(endTrunkView); - - for (int t = 0; t < nbTrunk-1; t++) { - Rectangle2D viewportTrunk = new Rectangle2D(this.tileWidth, (this.tileHeight*2), this.tileWidth, this.tileHeight); - ImageView trunkView = new ImageView(); - trunkView.setImage(this.treeImg); - trunkView.setViewport(viewportTrunk); - imagesTree.add(trunkView); + while (c.next()) { + if (c.wasAdded()) { + RabbitView rabbitView = new RabbitView(c.getAddedSubList().get(0), environment.scaleMultiplicatorWidth, environment.scaleMultiplicatorHeight); + rabbitView.display(this.displayHostileBeings); + this.rabbitsView.add(rabbitView.getImgView()); } - } else { - Rectangle2D viewportTrunk = new Rectangle2D(0, (this.tileHeight*2), this.tileWidth, this.tileHeight); - ImageView trunkView = new ImageView(); - trunkView.setImage(this.treeImg); - trunkView.setViewport(viewportTrunk); - imagesTree.add(trunkView); - } - Rectangle2D viewportTrunkFoot = new Rectangle2D(0, (this.tileHeight*3), this.tileWidth, this.tileHeight); - ImageView trunkFootView = new ImageView(); - trunkFootView.setImage(this.treeImg); - trunkFootView.setViewport(viewportTrunkFoot); - imagesTree.add(trunkFootView); - - for (int i = 0; i < imagesTree.size(); i++) { - ImageView treeView = imagesTree.get(i); - treeView.setY((int) (((tree.getY() + this.tileHeight) + (i * this.tileHeight)) - (this.tileHeight * imagesTree.size()))); - treeView.setX((int) tree.getX()); - - this.display.getChildren().add(treeView); + if (c.wasRemoved()) { + this.displayHostileBeings.getChildren().remove(this.rabbitsView.get(c.getTo())); + this.rabbitsView.remove(c.getTo()); + } } - - tree.setRect(this.tileWidth, (2+nbFoliage+nbTrunk)*this.tileHeight); } /** - * Crée et affiche un block de type Haute Herbe. - * Applique une animation de pousse à la haute herbe + * Supprime ou affiche les slimes qui sont ajoutés dans la liste d'entité List slimes; + * Une fois affiché, la fonction range l'imageView crée dans la liste List slimesView; de cette classe + * + * @param c Cet argument est present car on passe cette fonction en tant que reference (this::updatesSlimesView), + * l'argument est là pour obtenir les informations concernant les modifications dans liste List slimes; */ - private void createTallGrass(final TallGrass tallGrass) + private void updatesSlimeView(ListChangeListener.Change c) { - ImageView tallGrassView = new ImageView(this.tallGrassImg); - tallGrass.setRect(this.tileWidth, this.tileHeight); - tallGrassView.setX(tallGrass.getX()); - tallGrassView.setY(tallGrass.getY()); - - // L'animation de la pousse de la haute herbe - tallGrass.getTallGrassGrowthProperty().addListener(((observable, oldValue, newValue) -> { - tallGrassView.setViewport(new Rectangle2D(0, 0, this.tallGrassImg.getWidth(), (newValue.intValue() < 1) ? 1 : (this.tallGrassImg.getHeight()/TallGrass.GROWTH_TALL_GRASS_STEP)*newValue.intValue())); - tallGrassView.setY((tallGrass.getY() - (this.tallGrassImg.getHeight()/TallGrass.GROWTH_TALL_GRASS_STEP)*newValue.intValue()) + this.tileHeight); - })); - - this.display.getChildren().add(tallGrassView); + while (c.next()) { + if (c.wasAdded()) { + SlimeView slimeView = new SlimeView(c.getAddedSubList().get(0), environment.scaleMultiplicatorWidth, environment.scaleMultiplicatorHeight); + slimeView.display(this.displayHostileBeings); + this.slimesView.add(slimeView.getImgView()); + } + + if (c.wasRemoved()) { + this.displayHostileBeings.getChildren().remove(this.slimesView.get(c.getTo())); + this.slimesView.remove(c.getTo()); + } + } } - /** Crée et affiche un tile de type pierre */ - private void createStone(int x, int y) + /** + * Supprime ou affiche les groupes d'image de l'arbre qui sont ajouté dans la liste d'entité List trees; + * Génère une image plus ou moins grande selon le Math.random obtenue. + * Une fois affiché, la fonction range l'imageView crée dans la liste List treesView; de cette classe + * + * @param c Cet argument est present car on passe cette fonction en tant que reference (this::updatesRabbitsView), + * l'argument est là pour obtenir les informations concernant les modifications dans liste List rabbits; + */ + private void updatesTreeView(ListChangeListener.Change c) { - Stone stoneEntity = new Stone(this.environment, x*this.tileWidth, y*this.tileHeight); - stoneEntity.setRect(this.tileWidth, this.tileHeight); + while (c.next()) { + if (c.wasAdded()) { + Group group = new Group(); + + // La hauteur des feuillages + int nbFoliage = ((int) (Math.random()*2))+1; + // La hauteur du tronc + int nbTrunk = ((int) (Math.random()*3))+1; + + Rectangle2D viewportFirstFrame = new Rectangle2D(0, 0, this.tileWidth, this.tileHeight); + ImageView firstFrameView = new ImageView(); + firstFrameView.setImage(this.treeImg); + firstFrameView.setViewport(viewportFirstFrame); + group.getChildren().add(firstFrameView); + + for (int f = 0; f < nbFoliage; f++) { + Rectangle2D viewportSecondFrame = new Rectangle2D(0, this.tileHeight, this.tileWidth, this.tileHeight); + ImageView secondFrameView = new ImageView(); + secondFrameView.setImage(this.treeImg); + secondFrameView.setViewport(viewportSecondFrame); + group.getChildren().add(secondFrameView); + } - this.display.getChildren().add(View.createImageView(stoneEntity, this.stoneImg)); - this.environment.getEntities().add(stoneEntity); - } + if (nbTrunk > 1) { + Rectangle2D viewportEndTrunk = new Rectangle2D(0, (this.tileHeight*2), this.tileWidth, this.tileHeight); + ImageView endTrunkView = new ImageView(); + endTrunkView.setImage(this.treeImg); + endTrunkView.setViewport(viewportEndTrunk); + group.getChildren().add(endTrunkView); + + for (int t = 0; t < nbTrunk-1; t++) { + Rectangle2D viewportTrunk = new Rectangle2D(this.tileWidth, (this.tileHeight*2), this.tileWidth, this.tileHeight); + ImageView trunkView = new ImageView(); + trunkView.setImage(this.treeImg); + trunkView.setViewport(viewportTrunk); + group.getChildren().add(trunkView); + } + } else { + Rectangle2D viewportTrunk = new Rectangle2D(0, (this.tileHeight*2), this.tileWidth, this.tileHeight); + ImageView trunkView = new ImageView(); + trunkView.setImage(this.treeImg); + trunkView.setViewport(viewportTrunk); + group.getChildren().add(trunkView); + } + Rectangle2D viewportTrunkFoot = new Rectangle2D(0, (this.tileHeight*3), this.tileWidth, this.tileHeight); + ImageView trunkFootView = new ImageView(); + trunkFootView.setImage(this.treeImg); + trunkFootView.setViewport(viewportTrunkFoot); + group.getChildren().add(trunkFootView); + + Tree tree = (Tree) c.getAddedSubList().get(0); + for (int i = 0; i < group.getChildren().size(); i++) { + ImageView treeView = (ImageView) group.getChildren().get(i); + + treeView.setY((int) (((tree.getY() + this.tileHeight) + (i * this.tileHeight)) - (this.tileHeight * group.getChildren().size()))); + treeView.setX((int) tree.getX()); + } + tree.setRect(this.tileWidth, (2+nbFoliage+nbTrunk)*this.tileHeight); + tree.getRect().updates(tree.getX(), tree.getY() - ((2+nbFoliage+nbTrunk)*this.tileHeight) + this.tileHeight); - /** Crée et affiche un block de type Torch */ - private void createTorch(final Torch torch) - { - torch.setRect(this.tileWidth, this.tileHeight); - this.display.getChildren().add(View.createImageView(torch, this.torchImg)); - } + this.display.getChildren().add(group); + this.treesView.add(group); + } - /** Crée et affiche un tile de type terre */ - private void createDirt(int x, int y) - { - Dirt dirtSprite = new Dirt(this.environment, x*this.tileWidth, y*this.tileHeight); - dirtSprite.setRect(this.tileWidth, this.tileHeight); + if (c.wasRemoved()) { + this.display.getChildren().remove(this.treesView.get(c.getTo())); + this.treesView.remove(c.getTo()); + } + } - this.display.getChildren().add(View.createImageView(dirtSprite, this.dirtImg)); - this.environment.getEntities().add(dirtSprite); } - /** - * Crée et affiche un tile de type sol - * @param typeOfFloor Quel face du tile doit être affiché - */ - private void createFloor(int typeOfFloor, int x, int y) + /** Decompose la carte pour afficher une à une les tiles à l'écran */ + public void displayMaps(TileMaps tiles) { - Dirt floorEntity = new Dirt(this.environment, x*this.tileWidth, y*this.tileHeight); - Image floorImg = (typeOfFloor == TileMaps.FLOOR_TOP) ? this.floorTopImg : (typeOfFloor == TileMaps.FLOOR_RIGHT) ? this.floorRightImg : this.floorLeftImg; - floorEntity.setRect(this.tileWidth, this.tileHeight); - - this.display.getChildren().add(View.createImageView(floorEntity, floorImg)); - this.environment.getEntities().add(floorEntity); + for (int y = 0; y < tiles.getHeight() ; y++) + for (int x = 0 ; x < tiles.getWidth() ; x++) { + int xBlock = x * this.tileWidth; + int yBlock = y * this.tileHeight; + + if (tiles.isRockTile(x, y)) { + Block rockEntity = new Block(BlockSet.ROCK, this.environment, xBlock, yBlock); + rockEntity.setRect(this.tileWidth, this.tileHeight); + + this.environment.getEntities().add(rockEntity); + this.environment.getBlocks().add(rockEntity); + } else if (tiles.isDirtTile(x, y)) { + Block dirtSprite = new Block(BlockSet.DIRT, this.environment, xBlock, yBlock); + dirtSprite.setRect(this.tileWidth, this.tileHeight); + + this.environment.getEntities().add(dirtSprite); + this.environment.getBlocks().add(dirtSprite); + } else if (tiles.isFloorTopTile(x, y) || tiles.isFloorLeftTile(x, y) || tiles.isFloorRightTile(x, y)) { + Block floorEntity = null; + if (tiles.isFloorTopTile(x, y)) + floorEntity = new Block(BlockSet.FLOOR_TOP, this.environment, xBlock, yBlock); + else if (tiles.isFloorLeftTile(x, y)) + floorEntity = new Block(BlockSet.FLOOR_LEFT, this.environment, xBlock, yBlock); + else floorEntity = new Block(BlockSet.FLOOR_RIGHT, this.environment, xBlock, yBlock); + floorEntity.setRect(this.tileWidth, this.tileHeight); + + this.environment.getEntities().add(floorEntity); + this.environment.getBlocks().add(floorEntity); + } + } } - - /** Affiche une erreur au cas où si un developer a fait une erreur lors de la saisie d'un tile sur le fichier .json */ - private void errorTile(final int tile) { if (tile != TileMaps.SKY) System.out.println("Le tile '" + tile + "' n'est pas reconnu."); } } diff --git a/src/main/java/fr/sae/terraria/vue/View.java b/src/main/java/fr/sae/terraria/vue/View.java index 8463ccb..9294968 100644 --- a/src/main/java/fr/sae/terraria/vue/View.java +++ b/src/main/java/fr/sae/terraria/vue/View.java @@ -4,6 +4,8 @@ import fr.sae.terraria.controller.GameController; import fr.sae.terraria.modele.Environment; import fr.sae.terraria.modele.entities.entity.Entity; +import fr.sae.terraria.modele.entities.player.Player; +import fr.sae.terraria.vue.entities.PlayerView; import fr.sae.terraria.vue.hud.HUDView; import fr.sae.terraria.vue.hud.MouseCursorView; import javafx.scene.image.Image; @@ -17,18 +19,18 @@ public class View { - private static Environment environment; + private Environment environment; /** * Cette classe lors de l'initialisation, crée et génére toutes les views du jeux - * Contient des fonctions essentiels au chargement des images et des creations de vue + * Contient des fonctions essentielles au chargement des images et des creations de vue */ public View(final GameController gameController) { super(); - environment = gameController.environment; + this.environment = gameController.environment; final Pane displayTiledMap = gameController.displayTiledMap; final Pane displayHostileBeings = gameController.displayHostileBeings; final Pane displayHUD = gameController.displayHUD; @@ -40,10 +42,12 @@ public View(final GameController gameController) TileMapsView tileMapsView = new TileMapsView(environment, displayTiledMap, displayHostileBeings, scaleMultiplicatorWidth, scaleMultiplicatorHeight); tileMapsView.displayMaps(environment.getTileMaps()); - PlayerView playerView = new PlayerView(environment.getPlayer(), scaleMultiplicatorWidth, scaleMultiplicatorHeight); - playerView.displayPlayer(displayHostileBeings); + Player player = this.environment.getPlayer(); + PlayerView playerView = new PlayerView(player, scaleMultiplicatorWidth, scaleMultiplicatorHeight); + playerView.display(displayHostileBeings); LightView lightView = new LightView(environment.getGameClock(),filter,environment); + DrunkView drunkView = new DrunkView(environment,gameController.paneHadCamera); HUDView HUDView = new HUDView(environment.getPlayer(), environment.getGameClock(), displayHUD, scaleMultiplicatorWidth, scaleMultiplicatorHeight); HUDView.display(); @@ -51,7 +55,7 @@ public View(final GameController gameController) new MouseCursorView(displayHUD, displayCursorMouse, scaleMultiplicatorWidth, scaleMultiplicatorHeight); } - /** Essaye de trouver et de charger l'image sinon renvoie null */ + /** Essaye de trouver et de charger l'image, si elle n'est pas trouvée, retourne null */ private static Image foundImage(final String path) { Image img = null; @@ -72,20 +76,23 @@ private static Image foundImage(final String path) public static Image loadAnImage(final String path, double scaleMultiplicatorWidth, double scaleMultiplicatorHeight) { Image img = View.foundImage(path); - double width = img.getWidth(); - double height = img.getHeight(); - img.cancel(); - - double widthScaled = width*scaleMultiplicatorWidth; - double heightScaled = height*scaleMultiplicatorHeight; - return new Image(img.getUrl(), widthScaled, heightScaled, false, false, false); + if (!Objects.isNull(img)) { + double width = img.getWidth(); + double height = img.getHeight(); + img.cancel(); + + double widthScaled = width*scaleMultiplicatorWidth; + double heightScaled = height*scaleMultiplicatorHeight; + return new Image(img.getUrl(), widthScaled, heightScaled, false, false, false); + } + return null; } public static ImageView createImageView(final Entity entity, final Image img) { ImageView imageView = new ImageView(img); - imageView.translateXProperty().bind(entity.getXProperty()); - imageView.translateYProperty().bind(entity.getYProperty()); + imageView.translateXProperty().bind(entity.xProperty()); + imageView.translateYProperty().bind(entity.yProperty()); return imageView; } diff --git a/src/main/java/fr/sae/terraria/vue/entities/EntityView.java b/src/main/java/fr/sae/terraria/vue/entities/EntityView.java new file mode 100644 index 0000000..9a49898 --- /dev/null +++ b/src/main/java/fr/sae/terraria/vue/entities/EntityView.java @@ -0,0 +1,70 @@ +package fr.sae.terraria.vue.entities; + +import fr.sae.terraria.modele.entities.entity.Entity; +import javafx.scene.image.ImageView; +import javafx.scene.layout.Pane; + + +/** + *

Entity View

+ *

Une classe qui permet d'affiché des entités

+ *

Description:

+ *

Cette classe permet simplement grâce à la fonction animation() de codé une animations pour une entité en particulier

+ *

Cette classe gère les choses suivantes:

+ *
    + *
  • Crée une ImageView, pas besoin dans recrée une autre dans les classes qui hériterais cette classes.
  • + *
  • Bindings des positions de l'entité à l'ImageView.
  • + *
  • Change dynamiquement la limite de frame selon l'image utilisé.
  • + *
+ * + * @author CHRZASZCZ Naulan + */ +public abstract class EntityView +{ + protected final ImageView imgView; + protected final Entity entity; + + + protected EntityView(final Entity entity) + { + this.entity = entity; + + this.imgView = new ImageView(); + this.imgView.translateXProperty().bind(entity.xProperty()); + this.imgView.translateYProperty().bind(entity.yProperty()); + } + + /** l'endroit où il va avoir les animations qui vont êtres programmer. */ + protected abstract void animation(int frame); + + /** La fonction qui permet de démarrer les animations des entités */ + private void startAnimation() + { + int widthEntity = this.entity.getRect().getWidth(); + // int heightEntity = this.entity.getRect().getHeight(); + + // Change la limite de frame de l'animation selon le sprite sheet chargé + this.imgView.imageProperty().addListener((obs, oldImg, newImg) -> { + int newEndFrame = (int) (newImg.getWidth() / widthEntity); + if (this.entity.getAnimation().getFrame() >= newEndFrame) + this.entity.getAnimation().reset(); + this.entity.getAnimation().setEndFrame(newEndFrame); + }); + + this.entity.getAnimation().getFrameProperty().addListener((obs, oldFrame, newFrame) -> { + if(newFrame.intValue() >= this.entity.getAnimation().getEndFrame()) + this.animation(oldFrame.intValue()); + else this.animation(newFrame.intValue()); + }); + } + + /** Affiche l'entité à l'écran et démarre l'animation */ + public void display(final Pane display) + { + display.getChildren().add(this.imgView); + this.startAnimation(); + } + + + public ImageView getImgView() { return this.imgView; } +} diff --git a/src/main/java/fr/sae/terraria/vue/entities/PlayerView.java b/src/main/java/fr/sae/terraria/vue/entities/PlayerView.java new file mode 100644 index 0000000..82187d1 --- /dev/null +++ b/src/main/java/fr/sae/terraria/vue/entities/PlayerView.java @@ -0,0 +1,65 @@ +package fr.sae.terraria.vue.entities; + +import fr.sae.terraria.Terraria; +import fr.sae.terraria.modele.entities.player.Player; +import fr.sae.terraria.vue.View; +import javafx.animation.KeyFrame; +import javafx.animation.Timeline; +import javafx.geometry.Rectangle2D; +import javafx.scene.image.Image; +import javafx.util.Duration; + + +public class PlayerView extends EntityView +{ + private final Image playerMoveRightImg; + private final Image playerMoveLeftImg; + private final Image playerIdleImg; + + private int widthPlayer; + private int heightPlayer; + + + public PlayerView(final Player player, double scaleMultiplicatorWidth, double scaleMultiplicatorHeight) + { + super(player); + + this.playerIdleImg = View.loadAnImage("sprites/player/player_idle.png", scaleMultiplicatorWidth, scaleMultiplicatorHeight); + this.playerMoveRightImg = View.loadAnImage("sprites/player/player_moveRight.png", scaleMultiplicatorWidth, scaleMultiplicatorHeight); + this.playerMoveLeftImg = View.loadAnImage("sprites/player/player_moveLeft.png", scaleMultiplicatorWidth, scaleMultiplicatorHeight); + this.imgView.setImage(playerIdleImg); + + this.widthPlayer = (int) this.playerIdleImg.getWidth(); + this.heightPlayer = (int) this.playerIdleImg.getHeight(); + + boolean[] visible = new boolean[] {true}; + player.hitProperty().addListener((obs, oldBool, newBool) -> { + if (newBool.booleanValue()) { + Timeline timeLine = new Timeline(); + timeLine.setCycleCount(8); + + KeyFrame key = new KeyFrame(Duration.seconds((Player.TIME_BEFORE_HITTING_AGAIN_THE_PLAYER * Terraria.TARGET_FPS)/8), b -> { + visible[0] = !visible[0]; + this.imgView.setVisible(visible[0]); + }); + + timeLine.getKeyFrames().add(key); + timeLine.play(); + } + }); + } + + @Override protected void animation(int frame) + { + this.imgView.setViewport(new Rectangle2D(0, 0, this.widthPlayer, this.heightPlayer)); + if (((Player) this.entity).isIDLEonX() && ((Player) this.entity).isIDLEonY()) + this.imgView.setImage(this.playerIdleImg); + + if (((Player) this.entity).isMoving()) { + Rectangle2D frameRect = new Rectangle2D((frame * this.widthPlayer), 0, this.widthPlayer, this.heightPlayer); + + this.imgView.setViewport(frameRect); + this.imgView.setImage((((Player) this.entity).isMovingLeft()) ? this.playerMoveLeftImg : this.playerMoveRightImg); + } + } +} diff --git a/src/main/java/fr/sae/terraria/vue/entities/RabbitView.java b/src/main/java/fr/sae/terraria/vue/entities/RabbitView.java new file mode 100644 index 0000000..abde3b5 --- /dev/null +++ b/src/main/java/fr/sae/terraria/vue/entities/RabbitView.java @@ -0,0 +1,41 @@ +package fr.sae.terraria.vue.entities; + +import fr.sae.terraria.modele.TileMaps; +import fr.sae.terraria.modele.entities.Rabbit; +import fr.sae.terraria.vue.View; +import javafx.geometry.Rectangle2D; +import javafx.scene.image.Image; + + +public class RabbitView extends EntityView +{ + + private final Image rabbitLeftImg; + private final Image rabbitRightImg; + + + private int widthTile; + private int heightTile; + + + public RabbitView(final Rabbit rabbit, double scaleMultiplicatorWidth, double scaleMultiplicatorHeight) + { + super(rabbit); + + this.widthTile = (int) (scaleMultiplicatorWidth * TileMaps.TILE_DEFAULT_SIZE); + this.heightTile = (int) (scaleMultiplicatorHeight * TileMaps.TILE_DEFAULT_SIZE); + + this.rabbitLeftImg = View.loadAnImage("sprites/rabbit/rabbit_left.png", widthTile*4, heightTile); + this.rabbitRightImg = View.loadAnImage("sprites/rabbit/rabbit_right.png", widthTile*4, heightTile); + } + + @Override protected void animation(int frame) { + this.imgView.setViewport(new Rectangle2D(0, 0, this.widthTile, this.heightTile)); + if (((Rabbit) this.entity).isMoving()) { + Rectangle2D frameRect = new Rectangle2D((frame * this.widthTile), 0, this.widthTile, this.heightTile); + + this.imgView.setViewport(frameRect); + this.imgView.setImage((((Rabbit) this.entity).isMovingLeft()) ? this.rabbitLeftImg : this.rabbitRightImg); + } + } +} diff --git a/src/main/java/fr/sae/terraria/vue/entities/SlimeView.java b/src/main/java/fr/sae/terraria/vue/entities/SlimeView.java new file mode 100644 index 0000000..d55105d --- /dev/null +++ b/src/main/java/fr/sae/terraria/vue/entities/SlimeView.java @@ -0,0 +1,33 @@ +package fr.sae.terraria.vue.entities; + +import fr.sae.terraria.modele.TileMaps; +import fr.sae.terraria.modele.entities.Slime; +import fr.sae.terraria.vue.View; +import javafx.geometry.Rectangle2D; +import javafx.scene.image.Image; + + +public class SlimeView extends EntityView +{ + private final Image slimeImg; + + private int widthTile; + private int heightTile; + + + public SlimeView(final Slime slime, double scaleMultiplicatorWidth, double scaleMultiplicatorHeight) + { + super(slime); + + this.widthTile = (int) (scaleMultiplicatorWidth * TileMaps.TILE_DEFAULT_SIZE); + this.heightTile = (int) (scaleMultiplicatorHeight * TileMaps.TILE_DEFAULT_SIZE); + + this.slimeImg = View.loadAnImage("sprites/slimes/green_slime.png", widthTile*4, heightTile); + this.imgView.setImage(slimeImg); + } + + @Override protected void animation(int frame) { + Rectangle2D frameRect = new Rectangle2D(frame * this.widthTile, 0, this.widthTile, this.heightTile); + this.imgView.setViewport(frameRect); + } +} diff --git a/src/main/java/fr/sae/terraria/vue/hud/ClockView.java b/src/main/java/fr/sae/terraria/vue/hud/ClockView.java index e1ccbce..ca74105 100644 --- a/src/main/java/fr/sae/terraria/vue/hud/ClockView.java +++ b/src/main/java/fr/sae/terraria/vue/hud/ClockView.java @@ -29,7 +29,7 @@ public ClockView(Clock gameTime, Pane display, double scaleMultiplicatorWidth, d this.clockCursorImg = View.loadAnImage("clock-cursor.png",scaleMultiplicatorWidth,scaleMultiplicatorHeight); } - /** Affiche une horloge à aiguille visuelle à l'écran. */ + /** Affiche une horloge à aiguille à l'écran. */ private void displayClock(Image inventoryBarImg, double inventoryBarX, double inventoryBarY) { ImageView clockCursorView = new ImageView(clockCursorImg); diff --git a/src/main/java/fr/sae/terraria/vue/hud/HealthBarView.java b/src/main/java/fr/sae/terraria/vue/hud/HealthBarView.java index e50f58d..287d219 100644 --- a/src/main/java/fr/sae/terraria/vue/hud/HealthBarView.java +++ b/src/main/java/fr/sae/terraria/vue/hud/HealthBarView.java @@ -44,10 +44,16 @@ private void displayHealthBar(double inventoryBarX, double inventoryBarY) } // Modifie le cœur selon la vie du joueur - player.getPvProperty().addListener((obs, oldPv, newPv) -> { - if (oldPv.intValue() >= 0) { - ImageView healthView = healths[oldPv.intValue()-1]; + player.pvProperty().addListener((obs, oldPv, newPv) -> { + ImageView healthView; + if (newPv.intValue() > oldPv.intValue()) { + healthView = healths[newPv.intValue()-1]; + Rectangle2D viewPort = new Rectangle2D((healthView.getImage().getWidth()/3)*2, 0, (healthView.getImage().getWidth()/3), healthView.getImage().getHeight()); + healthView.setViewport(viewPort); + } + if (newPv.intValue() < oldPv.intValue()) { + healthView = healths[oldPv.intValue()-1]; Rectangle2D viewPort = new Rectangle2D((healthView.getImage().getWidth()/3)*0, 0, (healthView.getImage().getWidth()/3), healthView.getImage().getHeight()); healthView.setViewport(viewPort); } diff --git a/src/main/java/fr/sae/terraria/vue/hud/InventoryView.java b/src/main/java/fr/sae/terraria/vue/hud/InventoryView.java index 801384c..8145875 100644 --- a/src/main/java/fr/sae/terraria/vue/hud/InventoryView.java +++ b/src/main/java/fr/sae/terraria/vue/hud/InventoryView.java @@ -3,18 +3,14 @@ import fr.sae.terraria.Terraria; import fr.sae.terraria.modele.TileMaps; import fr.sae.terraria.modele.entities.Arrow; -import fr.sae.terraria.modele.entities.blocks.Dirt; -import fr.sae.terraria.modele.entities.blocks.Stone; -import fr.sae.terraria.modele.entities.blocks.TallGrass; -import fr.sae.terraria.modele.entities.blocks.Torch; +import fr.sae.terraria.modele.entities.blocks.Block; import fr.sae.terraria.modele.entities.entity.StowableObjectType; -import fr.sae.terraria.modele.entities.items.*; +import fr.sae.terraria.modele.entities.items.Item; +import fr.sae.terraria.modele.entities.items.Meat; +import fr.sae.terraria.modele.entities.items.Vodka; import fr.sae.terraria.modele.entities.player.inventory.Inventory; import fr.sae.terraria.modele.entities.player.inventory.Stack; -import fr.sae.terraria.modele.entities.tools.Axe; -import fr.sae.terraria.modele.entities.tools.Bow; -import fr.sae.terraria.modele.entities.tools.Pickaxe; -import fr.sae.terraria.modele.entities.tools.Sword; +import fr.sae.terraria.modele.entities.tools.Tool; import fr.sae.terraria.vue.View; import javafx.collections.ListChangeListener; import javafx.scene.image.Image; @@ -77,7 +73,8 @@ public InventoryView(Inventory inventory, Pane display, double scaleMultiplicato /** * Applique une bordure de couleur noire autour de la barre d'inventaire */ - private Rectangle setFrameInventoryBar() { + private Rectangle setFrameInventoryBar() + { frameInventoryBar.setWidth(inventoryBarImg.getWidth() + (2 * scaleMultiplicatorWidth)); frameInventoryBar.setHeight(inventoryBarImg.getHeight() + (2 * scaleMultiplicatorHeight)); frameInventoryBar.setX(inventoryBarImgView.getX() - scaleMultiplicatorWidth); @@ -102,46 +99,58 @@ private void displayItemIntoInventoryBar() Stack stack = c.getAddedSubList().get(0); StowableObjectType item = stack.getItem(); - if (item instanceof Dirt) - view.setImage(View.loadAnImage("tiles/floor-top.png", itemInventoryWidth, itemInventoryHeight)); - else if (item instanceof Stone) - view.setImage(View.loadAnImage("tiles/rock-fill.png", itemInventoryWidth, itemInventoryHeight)); - else if (item instanceof TallGrass) - view.setImage(View.loadAnImage("tiles/tall-grass.png.png", itemInventoryWidth, itemInventoryHeight)); - else if (item instanceof Torch) - view.setImage(View.loadAnImage("tiles/torch.png", itemInventoryWidth, itemInventoryHeight)); - else if (item instanceof Coal) - view.setImage(View.loadAnImage("loots/coal.png", itemInventoryWidth, itemInventoryHeight)); - else if (item instanceof Fiber) - view.setImage(View.loadAnImage("loots/fiber.png", itemInventoryWidth, itemInventoryHeight)); - else if (item instanceof Iron) - view.setImage(View.loadAnImage("loots/iron.png", itemInventoryWidth, itemInventoryHeight)); - else if (item instanceof Meat) + if (item instanceof Meat) view.setImage(View.loadAnImage("loots/meat.png", itemInventoryWidth, itemInventoryHeight)); - else if (item instanceof Pierre) - view.setImage(View.loadAnImage("loots/pierre.png", itemInventoryWidth, itemInventoryHeight)); - else if (item instanceof Silex) - view.setImage(View.loadAnImage("loots/silex.png", itemInventoryWidth, itemInventoryHeight)); - else if (item instanceof Wood) - view.setImage(View.loadAnImage("loots/wood.png", itemInventoryWidth, itemInventoryHeight)); - else if (item instanceof Axe) - view.setImage(null); // TODO - else if (item instanceof Bow) - view.setImage(null); // TODO - else if (item instanceof Pickaxe) - view.setImage(View.loadAnImage("tools/pickaxe.png", itemInventoryWidth, itemInventoryHeight)); - else if (item instanceof Sword) - view.setImage(View.loadAnImage("tools/sword.png", itemInventoryWidth, itemInventoryHeight)); else if (item instanceof Arrow) view.setImage(null); // TODO + else if (item instanceof Vodka) + view.setImage(View.loadAnImage("loots/vodka.png", itemInventoryWidth,itemInventoryHeight)); + + if (item instanceof Block) { + if (Block.isFloorTop((Block) item)) + view.setImage(View.loadAnImage("tiles/floor-top.png", itemInventoryWidth, itemInventoryHeight)); + else if (Block.isRock((Block) item)) + view.setImage(View.loadAnImage("tiles/rock-fill.png", itemInventoryWidth, itemInventoryHeight)); + else if (Block.isTallGrass((Block) item)) + view.setImage(View.loadAnImage("tiles/tall-grass.png.png", itemInventoryWidth, itemInventoryHeight)); + else if (Block.isTorch((Block) item)) + view.setImage(View.loadAnImage("tiles/torch.png", itemInventoryWidth, itemInventoryHeight)); + } + + if (item instanceof Tool) { + if (Tool.isAxe((Tool) item)) + view.setImage(null); // TODO + else if (Tool.isBow((Tool) item)) + view.setImage(null); // TODO + else if (Tool.isPickaxe((Tool) item)) + view.setImage(View.loadAnImage("tools/pickaxe.png", itemInventoryWidth, itemInventoryHeight)); + else if (Tool.isSword((Tool) item)) + view.setImage(View.loadAnImage("tools/sword.png", itemInventoryWidth, itemInventoryHeight)); + } + + if (item instanceof Item) { + if (Item.isCoal(item)) + view.setImage(View.loadAnImage("loots/coal.png", itemInventoryWidth, itemInventoryHeight)); + else if (Item.isFiber(item)) + view.setImage(View.loadAnImage("loots/fiber.png", itemInventoryWidth, itemInventoryHeight)); + else if (Item.isIron(item)) + view.setImage(View.loadAnImage("loots/iron.png", itemInventoryWidth, itemInventoryHeight)); + else if (Item.isStone(item)) + view.setImage(View.loadAnImage("loots/pierre.png", itemInventoryWidth, itemInventoryHeight)); + else if (Item.isSilex(item)) + view.setImage(View.loadAnImage("loots/silex.png", itemInventoryWidth, itemInventoryHeight)); + else if (Item.isWood(item)) + view.setImage(View.loadAnImage("loots/wood.png", itemInventoryWidth, itemInventoryHeight)); + else if (Item.isStick(item)) + view.setImage(View.loadAnImage("loots/stick.png", itemInventoryWidth, itemInventoryHeight)); + } // Actualise le nombre d'item à l'écran - this.texts.get(c.getTo()-1).setText(String.valueOf(stack.getNbItems())); - stack.nbItemsProperty().addListener((obs, oldV, newV) -> this.texts.get(c.getTo()-1).setText(String.valueOf(newV.intValue()))); + this.texts.get(c.getTo()-1).textProperty().bind(c.getAddedSubList().get(0).nbItemsProperty().asString()); if (!Objects.isNull(view.getImage())) { - view.setX(this.inventoryBarImgView.getX() + ((c.getTo()-1) * boxeInventoryWidth)); - view.setY(this.inventoryBarImgView.getY()); + view.setX((this.inventoryBarImgView.getX() + ((c.getTo()-1) * boxeInventoryWidth)) + ((boxeInventoryWidth/2) - (itemInventoryWidth/2))); + view.setY(this.inventoryBarImgView.getY() + ((boxeInventoryWidth/2) - (itemInventoryHeight/2))); this.itemsView.add(view); this.display.getChildren().add(view); @@ -154,6 +163,14 @@ else if (item instanceof Arrow) for (int i = c.getTo(); i < itemsView.size(); i++) this.itemsView.get(i).setX(this.itemsView.get(i).getX() - boxeInventoryWidth); + + for (int i = 0; i < inventory.get().size(); i ++){ + this.texts.get(inventory.get().size()).textProperty().unbind(); + this.texts.get(i).textProperty().bind(inventory.get().get(i).nbItemsProperty().asString()); + } + this.texts.get(inventory.get().size()).textProperty().unbind(); + this.texts.get(inventory.get().size()).setText("0"); + } } }); @@ -178,7 +195,7 @@ private void displayCursorInventoryBar() { this.cursorImgView.setX(((windowWidth - inventoryBarImg.getWidth()) / 2 - scaleMultiplicatorWidth)); this.cursorImgView.setY(((windowHeight - inventoryBarImg.getHeight()) - tileHeight) - scaleMultiplicatorHeight); - this.inventory.posCursorProperty().addListener((obs, oldV, newV) -> this.cursorImgView.setX(((windowWidth - inventoryBarImg.getWidth()) / 2 + ((inventoryBarImg.getWidth() / 9) * newV.intValue() - scaleMultiplicatorWidth)))); + this.inventory.cursorProperty().addListener((obs, oldV, newV) -> this.cursorImgView.setX(((windowWidth - inventoryBarImg.getWidth()) / 2 + ((inventoryBarImg.getWidth() / 9) * newV.intValue() - scaleMultiplicatorWidth)))); this.display.getChildren().add(cursorImgView); } diff --git a/src/main/java/fr/sae/terraria/vue/hud/ItemSelectedView.java b/src/main/java/fr/sae/terraria/vue/hud/ItemSelectedView.java index 3567ec8..94487e5 100644 --- a/src/main/java/fr/sae/terraria/vue/hud/ItemSelectedView.java +++ b/src/main/java/fr/sae/terraria/vue/hud/ItemSelectedView.java @@ -2,27 +2,22 @@ import fr.sae.terraria.modele.TileMaps; import fr.sae.terraria.modele.entities.Arrow; -import fr.sae.terraria.modele.entities.blocks.Dirt; -import fr.sae.terraria.modele.entities.blocks.Stone; -import fr.sae.terraria.modele.entities.blocks.TallGrass; -import fr.sae.terraria.modele.entities.blocks.Torch; +import fr.sae.terraria.modele.entities.blocks.Block; import fr.sae.terraria.modele.entities.entity.StowableObjectType; -import fr.sae.terraria.modele.entities.items.*; +import fr.sae.terraria.modele.entities.items.Item; +import fr.sae.terraria.modele.entities.items.Meat; +import fr.sae.terraria.modele.entities.items.Vodka; import fr.sae.terraria.modele.entities.player.Player; import fr.sae.terraria.modele.entities.player.inventory.Stack; -import fr.sae.terraria.modele.entities.tools.Axe; -import fr.sae.terraria.modele.entities.tools.Bow; -import fr.sae.terraria.modele.entities.tools.Pickaxe; -import fr.sae.terraria.modele.entities.tools.Sword; +import fr.sae.terraria.modele.entities.tools.Tool; import fr.sae.terraria.vue.View; import javafx.collections.ListChangeListener; +import javafx.collections.ObservableList; import javafx.scene.image.Image; import javafx.scene.image.ImageView; import javafx.scene.input.MouseEvent; import javafx.scene.layout.Pane; -import java.util.Objects; - public class ItemSelectedView { @@ -33,18 +28,23 @@ public class ItemSelectedView private final Image coalItemImg; private final Image fibreItemImg; private final Image ironItemImg; - private final Image pierreItemImg; + private final Image rockItemImg; private final Image silexItemImg; private final Image meatItemImg; private final Image woodItemImg; private final Image torchItemImg; private final Image pickaxeItemImg; + private final Image vodkaItemImg; + private final Image swordItemImg; private final Pane display; + private final Player player; + public ItemSelectedView(Pane display, Player player, double scaleMultiplicatorWidth, double scaleMultiplicatorHeight) { + this.player = player; this.display = display; int widthTile = (int) (scaleMultiplicatorWidth * TileMaps.TILE_DEFAULT_SIZE); @@ -53,70 +53,89 @@ public ItemSelectedView(Pane display, Player player, double scaleMultiplicatorWi int heightItem = heightTile/2; this.itemSelectedImgView = new ImageView(); + this.vodkaItemImg = View.loadAnImage("loots/vodka.png",widthItem,heightItem); this.dirtItemImg = View.loadAnImage("tiles/floor-top.png", widthItem, heightItem); - this.stoneItemImg = View.loadAnImage("tiles/rock-fill.png", widthItem, heightItem); + this.rockItemImg = View.loadAnImage("tiles/rock-fill.png", widthItem, heightItem); this.torchItemImg = View.loadAnImage("tiles/torch.png", widthItem, heightItem); this.coalItemImg = View.loadAnImage("loots/coal.png", widthItem, heightItem); this.fibreItemImg = View.loadAnImage("loots/fiber.png", widthItem, heightItem); this.ironItemImg = View.loadAnImage("loots/iron.png", widthItem, heightItem); - this.pierreItemImg = View.loadAnImage("loots/pierre.png", widthItem, heightItem); + this.stoneItemImg = View.loadAnImage("loots/pierre.png", widthItem, heightItem); this.silexItemImg = View.loadAnImage("loots/silex.png", widthItem, heightItem); this.meatItemImg = View.loadAnImage("loots/meat.png", widthItem, heightItem); this.woodItemImg = View.loadAnImage("loots/wood.png", widthItem, heightItem); this.pickaxeItemImg = View.loadAnImage("tools/pickaxe.png", widthItem, heightItem); + this.swordItemImg = View.loadAnImage("tools/sword.png", widthItem, heightItem); // Reset player.getInventory().get().addListener((ListChangeListener) c -> { - while (c.next()) { - if (c.wasRemoved()) - this.itemSelectedImgView.setImage(null); - } + while (c.next()) + refreshView(); }); - player.getInventory().posCursorProperty().addListener((obs, oldItemSelected, newItemSelected) -> { - this.itemSelectedImgView.setImage(null); - if (!Objects.isNull(player.getStackSelected())) { - StowableObjectType item = player.getStackSelected().getItem(); + player.getInventory().cursorProperty().addListener((obs, oldItemSelected, newItemSelected) -> { + refreshView(); + }); - if (item instanceof Dirt) - this.itemSelectedImgView.setImage(this.dirtItemImg); - else if (item instanceof Stone) - this.itemSelectedImgView.setImage(this.stoneItemImg); - else if (item instanceof TallGrass) + display.addEventFilter(MouseEvent.MOUSE_MOVED, mouse -> { + itemSelectedImgView.setX(mouse.getX()); + itemSelectedImgView.setY(mouse.getY()); + }); + } + + private void refreshView(){ + ObservableList inventory = this.player.getInventory().get(); + int posCursor = this.player.getInventory().getPosCursor(); + + this.itemSelectedImgView.setImage(null); + if (posCursor < inventory.size() && posCursor >= 0) { + StowableObjectType item = inventory.get(posCursor).getItem(); + + if (item instanceof Meat) + this.itemSelectedImgView.setImage(this.meatItemImg); + else if (item instanceof Vodka) + this.itemSelectedImgView.setImage(this.vodkaItemImg); + else if (item instanceof Arrow) + this.itemSelectedImgView.setImage(null); + + if (item instanceof Block) + { + if (Block.isFloorTop((Block) item)) + this.itemSelectedImgView.setImage(this.dirtItemImg); + else if (Block.isRock((Block) item)) + this.itemSelectedImgView.setImage(this.rockItemImg); + else if (Block.isTallGrass((Block) item)) + this.itemSelectedImgView.setImage(null); + else if (Block.isTorch((Block) item)) + this.itemSelectedImgView.setImage(this.torchItemImg); + } + + if (item instanceof Tool) { + if (Tool.isAxe((Tool) item)) this.itemSelectedImgView.setImage(null); - else if (item instanceof Torch) - this.itemSelectedImgView.setImage(this.torchItemImg); - else if (item instanceof Coal) + else if (Tool.isBow((Tool) item)) + this.itemSelectedImgView.setImage(null); + else if (Tool.isPickaxe((Tool) item)) + this.itemSelectedImgView.setImage(this.pickaxeItemImg); + else if (Tool.isSword((Tool) item)) + this.itemSelectedImgView.setImage(this.swordItemImg); + } + + if (item instanceof Item) { + if (Item.isCoal(item)) this.itemSelectedImgView.setImage(this.coalItemImg); - else if (item instanceof Fiber) + else if (Item.isFiber(item)) this.itemSelectedImgView.setImage(this.fibreItemImg); - else if (item instanceof Iron) + else if (Item.isIron(item)) this.itemSelectedImgView.setImage(this.ironItemImg); - else if (item instanceof Meat) - this.itemSelectedImgView.setImage(this.meatItemImg); - else if (item instanceof Pierre) - this.itemSelectedImgView.setImage(this.pierreItemImg); - else if (item instanceof Silex) + else if (Item.isStone(item)) + this.itemSelectedImgView.setImage(this.stoneItemImg); + else if (Item.isSilex(item)) this.itemSelectedImgView.setImage(this.silexItemImg); - else if (item instanceof Wood) + else if (Item.isWood(item)) this.itemSelectedImgView.setImage(this.woodItemImg); - else if (item instanceof Axe) - this.itemSelectedImgView.setImage(null); - else if (item instanceof Bow) - this.itemSelectedImgView.setImage(null); - else if (item instanceof Pickaxe) - this.itemSelectedImgView.setImage(this.pickaxeItemImg); - else if (item instanceof Sword) - this.itemSelectedImgView.setImage(null); - else if (item instanceof Arrow) - this.itemSelectedImgView.setImage(null); } - }); - - display.addEventFilter(MouseEvent.MOUSE_MOVED, mouse -> { - itemSelectedImgView.setX(mouse.getX()); - itemSelectedImgView.setY(mouse.getY()); - }); + } } public void display() { display.getChildren().add(itemSelectedImgView); } diff --git a/src/main/java/fr/sae/terraria/vue/hud/MouseCursorView.java b/src/main/java/fr/sae/terraria/vue/hud/MouseCursorView.java index 1a9edf8..8ef2348 100644 --- a/src/main/java/fr/sae/terraria/vue/hud/MouseCursorView.java +++ b/src/main/java/fr/sae/terraria/vue/hud/MouseCursorView.java @@ -20,7 +20,7 @@ public class MouseCursorView /** * Un rectangle rouge qui suit la souris - * Permet de savoir où nous cliquons sur l'écran plus précisément sur quel tile + * Permet de savoir où le joueur clique sur l'écran plus précisément sur quel tile * * @param display L'afficheur qui se gère du HUD * @param scaleMultiplicatorWidth Scaling en largeur diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java index 0b865f5..1676252 100644 --- a/src/main/java/module-info.java +++ b/src/main/java/module-info.java @@ -1,16 +1,15 @@ -module fr.sae.terraria { +module fr.sae.terraria +{ + requires javafx.graphics; requires javafx.controls; requires javafx.fxml; requires com.google.gson; requires java.desktop; - - opens fr.sae.terraria to javafx.fxml; + opens fr.sae.terraria to javafx.graphics; exports fr.sae.terraria; - exports fr.sae.terraria.controller; opens fr.sae.terraria.controller to javafx.fxml; exports fr.sae.terraria.modele; - opens fr.sae.terraria.modele to javafx.fxml; exports fr.sae.terraria.modele.entities; opens fr.sae.terraria.modele.entities to javafx.fxml; exports fr.sae.terraria.modele.entities.entity; @@ -19,4 +18,7 @@ opens fr.sae.terraria.modele.entities.player to javafx.fxml; exports fr.sae.terraria.modele.entities.player.inventory; opens fr.sae.terraria.modele.entities.player.inventory to javafx.fxml; + opens fr.sae.terraria.modele to javafx.fxml, javafx.graphics; + exports fr.sae.terraria.modele.entities.player.craft; + opens fr.sae.terraria.modele.entities.player.craft to javafx.fxml; } \ No newline at end of file diff --git a/src/main/resources/fr/sae/terraria/emojies/confus.png b/src/main/resources/fr/sae/terraria/emojies/confus.png new file mode 100644 index 0000000..9eb95a3 Binary files /dev/null and b/src/main/resources/fr/sae/terraria/emojies/confus.png differ diff --git a/src/main/resources/fr/sae/terraria/loots/stick.png b/src/main/resources/fr/sae/terraria/loots/stick.png new file mode 100644 index 0000000..926af2b Binary files /dev/null and b/src/main/resources/fr/sae/terraria/loots/stick.png differ diff --git a/src/main/resources/fr/sae/terraria/loots/vodka.png b/src/main/resources/fr/sae/terraria/loots/vodka.png new file mode 100644 index 0000000..a33f575 Binary files /dev/null and b/src/main/resources/fr/sae/terraria/loots/vodka.png differ diff --git a/src/main/resources/fr/sae/terraria/sound/hit.wav b/src/main/resources/fr/sae/terraria/sound/hit.wav new file mode 100644 index 0000000..8b0a14f Binary files /dev/null and b/src/main/resources/fr/sae/terraria/sound/hit.wav differ diff --git a/src/main/resources/fr/sae/terraria/sound/treeHit.wav b/src/main/resources/fr/sae/terraria/sound/treeHit.wav new file mode 100644 index 0000000..1836611 Binary files /dev/null and b/src/main/resources/fr/sae/terraria/sound/treeHit.wav differ diff --git a/src/main/resources/fr/sae/terraria/sprites/tree-sheet.png b/src/main/resources/fr/sae/terraria/sprites/tree-sheet.png index 77a150d..3c07ff1 100644 Binary files a/src/main/resources/fr/sae/terraria/sprites/tree-sheet.png and b/src/main/resources/fr/sae/terraria/sprites/tree-sheet.png differ diff --git a/src/main/resources/fr/sae/terraria/tools/pickaxe.png b/src/main/resources/fr/sae/terraria/tools/pickaxe.png index 596520e..ce02b60 100644 Binary files a/src/main/resources/fr/sae/terraria/tools/pickaxe.png and b/src/main/resources/fr/sae/terraria/tools/pickaxe.png differ diff --git a/src/main/resources/fr/sae/terraria/tools/sword.png b/src/main/resources/fr/sae/terraria/tools/sword.png index 599eeea..1b1bcaf 100644 Binary files a/src/main/resources/fr/sae/terraria/tools/sword.png and b/src/main/resources/fr/sae/terraria/tools/sword.png differ diff --git a/src/main/resources/fr/sae/terraria/vue/game.fxml b/src/main/resources/fr/sae/terraria/vue/game.fxml index 7c4c3df..41b20eb 100644 --- a/src/main/resources/fr/sae/terraria/vue/game.fxml +++ b/src/main/resources/fr/sae/terraria/vue/game.fxml @@ -1,10 +1,9 @@ + - - + @@ -8,116 +9,109 @@ - - - + xmlns="http://javafx.com/javafx/11" xmlns:fx="http://javafx.com/fxml/1"> - - + +
- - + + - - + + - +
- - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - + + + + - - - - + + + + - + + + +
- + - - + + - +
- +
diff --git a/src/test/java/fr/sae/terraria/modele/entities/player/PlayerTest.java b/src/test/java/fr/sae/terraria/modele/entities/player/PlayerTest.java new file mode 100644 index 0000000..f1b3e85 --- /dev/null +++ b/src/test/java/fr/sae/terraria/modele/entities/player/PlayerTest.java @@ -0,0 +1,212 @@ +package fr.sae.terraria.modele.entities.player; + +import fr.sae.terraria.modele.Environment; +import fr.sae.terraria.modele.TileMaps; +import fr.sae.terraria.modele.TileSet; +import fr.sae.terraria.modele.entities.Rabbit; +import fr.sae.terraria.modele.entities.blocks.Block; +import fr.sae.terraria.modele.entities.blocks.BlockSet; +import fr.sae.terraria.modele.entities.items.Item; +import fr.sae.terraria.modele.entities.items.Meat; +import fr.sae.terraria.modele.entities.items.Vodka; +import javafx.geometry.Rectangle2D; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + + +public class PlayerTest +{ + private static Environment environment; + private static Player player; + + + public PlayerTest() { super(); } + + @BeforeAll public static void init() + { + environment = new Environment(1., 1.); + player = environment.getPlayer(); + } + + @Test public final void moveTest() + { + double previousPosX; + + previousPosX = player.getX(); + player.moveRight(); + player.move(); + + assertEquals(previousPosX + player.getVelocity(), player.getX(), + "Test: déplacement vers la droite."); + player.idleOnX(); + + + previousPosX = player.getX(); + player.moveLeft(); + player.move(); + + assertEquals(previousPosX - player.getVelocity(), player.getX(), + "Test: déplacement vers la gauche"); + } + + + @Test public final void collideTest() + { + /* + // Le TOP et le BOTTOM est un pet complex à tester dans un JUnit + Dirt dirtLeft = new Dirt(environment, 1, 1); + dirtLeft.setRect(1, 1); + environment.getEntities().add(dirtLeft); + Dirt dirtRight = new Dirt(environment, 5, 1); + dirtRight.setRect(1, 1); + environment.getEntities().add(dirtRight); + player.setRect(1, 1); + player.setVelocity(0); + player.setY(1); + + player.setX(3); + player.moveLeft(); + player.collide(); + + assertTrue(player.isMovingLeft()); + + player.setX(1); + player.moveLeft(); + player.collide(); + + assertTrue(player.isIDLEonX()); + + player.setX(5); + player.moveRight(); + player.collide(); + + assertTrue(player.isIDLEonX()); + */ + } + + @Test public final void hitTest() + { + double previousPv = player.getPv(); + player.hit(); + + assertEquals(previousPv - 1, player.getPv(), + "Vérifie s'il y a bien subit un dégât"); + } + + @Test public final void spawnTest() + { + int spawnLocX = 100; + int spawnLocY = 100; + + player.spawn(spawnLocX, spawnLocY); + + assertEquals(player.getX(), spawnLocX, + "Regarde si la localisation en X est correcte"); + assertEquals(player.getY(), spawnLocY, + "Regarde si la localisation en X est correcte"); + assertEquals(player.getGravity().xInit, spawnLocX, + "Regarde si la localisation au niveau de la gestion de la gravité, en X est correcte"); + assertEquals(player.getGravity().yInit, spawnLocY, + "Regarde si la localisation au niveau de la gestion de la gravité, en X est correcte"); + } + + @Test public final void worldLimitTest() + { + player.setX(2*TileMaps.TILE_DEFAULT_SIZE); + player.moveLeft(); + player.worldLimit(); + + assertTrue(player.isMovingLeft()); + + player.setX(-TileMaps.TILE_DEFAULT_SIZE); + player.moveLeft(); + player.worldLimit(); + + assertTrue(player.isIDLEonX()); + + player.setX(environment.getTileMaps().getWidth()*TileMaps.TILE_DEFAULT_SIZE + TileMaps.TILE_DEFAULT_SIZE); + player.moveRight(); + player.worldLimit(); + + assertTrue(player.isIDLEonX()); + } + + @Test public final void interactWithBlockTest() // TODO: Le nom est probablement mal choisie dans player + { + Rectangle2D blockSelected; + double beforePv; + + Block block = new Block(BlockSet.DIRT, environment, 1, 1); + block.setRect(1, 1); + environment.getEntities().add(block); + blockSelected = new Rectangle2D(1, 1, 1, 1); + + beforePv = block.getPv(); + player.interactWithBlock(blockSelected); + assertEquals(beforePv - 1, block.getPv()); + environment.getEntities().remove(block); + + + Rabbit rabbit = new Rabbit(environment, 10, 10); + rabbit.setRect(1, 1); + environment.getEntities().add(rabbit); + blockSelected = new Rectangle2D(10, 10, 1, 1); + + beforePv = rabbit.getPv(); + player.interactWithBlock(blockSelected); + assertEquals(beforePv - 1, rabbit.getPv()); + } + + @Test public final void placeBlockTest() + { + TileMaps tileMaps = environment.getTileMaps(); + player.pickup(new Block(BlockSet.DIRT, environment)); + + assertEquals(tileMaps.getTile(0, 0), TileSet.SKY.ordinal()); + player.placeBlock(0, 0); + assertEquals(tileMaps.getTile(0, 0), TileSet.DIRT.ordinal()); + + assertNull(player.getStackSelected()); + } + + @Test public final void drunkTest() + { + player.pickup(new Vodka(environment)); + + assertFalse(player.drunkProperty().get(), + "Vérifie si il n'est pas bourré"); + ((Vodka) player.getStackSelected().getItem()).consumes(); + assertTrue(player.drunkProperty().get(), + "Verife si il est bourré"); + } + + @Test public final void pickupTest() + { + player.getInventory().cursorProperty().set(0); + + + // Test avec de la viande + player.pickup(new Meat(environment)); + assertTrue(player.getStackSelected().getItem() instanceof Meat, + "Verifie si le stack est bien de la viande"); + assertEquals(player.getStackSelected().getNbItems(), 1, + "Verifie s'il y a bien 1 objet dans le stack"); + ((Meat) player.getStackSelected().getItem()).consumes(); + player.getStackSelected().remove(); + + assertNull(player.getStackSelected()); + + + // Test avec du charbon + player.pickup(Item.COAL); + assertTrue(Item.isCoal(player.getStackSelected().getItem()), + "Verifie si le stack est bien du charbon"); + assertEquals(player.getStackSelected().getNbItems(), 1, + "Verifie s'il y a bien 1 objet dans le stack"); + player.getStackSelected().remove(); + + assertNull(player.getStackSelected()); + } +} diff --git a/src/test/java/fr/sae/terraria/modele/entities/player/craft/CraftTest.java b/src/test/java/fr/sae/terraria/modele/entities/player/craft/CraftTest.java new file mode 100644 index 0000000..1d8e340 --- /dev/null +++ b/src/test/java/fr/sae/terraria/modele/entities/player/craft/CraftTest.java @@ -0,0 +1,110 @@ +package fr.sae.terraria.modele.entities.player.craft; + +import fr.sae.terraria.modele.Environment; +import fr.sae.terraria.modele.entities.blocks.Block; +import fr.sae.terraria.modele.entities.items.Item; +import fr.sae.terraria.modele.entities.player.Player; +import fr.sae.terraria.modele.entities.player.craft.recipes.IngredientSet; +import fr.sae.terraria.modele.entities.player.craft.recipes.PickaxeRecipe; +import fr.sae.terraria.modele.entities.player.craft.recipes.RockRecipe; +import fr.sae.terraria.modele.entities.player.inventory.Stack; +import fr.sae.terraria.modele.entities.tools.MaterialSet; +import fr.sae.terraria.modele.entities.tools.Tool; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +import java.util.Objects; + +import static org.junit.jupiter.api.Assertions.*; + + +public class CraftTest +{ + private static Environment environment; + private static Player player; + + + public CraftTest() { super(); } + + @BeforeAll public static void init() + { + environment = new Environment(1., 1.); + player = environment.getPlayer(); + } + + @Test public final void stockTest() + { + player.pickup(Item.STONE); + player.pickup(Item.STONE); + player.pickup(Item.STONE); + player.pickup(Item.STONE); + + boolean haveEnoughStones = false; + for (Stack stack : player.getInventory().get()) + if (Item.isStone(stack.getItem()) && stack.haveEnoughQuantity(RockRecipe.NB_STONES)) + haveEnoughStones = true; + assertTrue(haveEnoughStones); + + Block block = Craft.rock(environment); + player.pickup(block); + + boolean haveRock = false; + for (Stack stack : player.getInventory().get()) + if (stack.getItem() instanceof Block && Block.isRock((Block) stack.getItem())) + haveRock = true; + assertTrue(haveRock); + + boolean dontHaveStones = true; + for (Stack stack : player.getInventory().get()) + if (Item.isStone(stack.getItem())) { + dontHaveStones = false; + break; + } + assertTrue(dontHaveStones); + } + + @Test public final void pickaxeTest() + { + player.pickup(Item.WOOD); + player.pickup(Item.WOOD); + player.pickup(Item.WOOD); + player.pickup(Item.STICK); + player.pickup(Item.STICK); + + boolean haveEnoughWoods = false; + boolean haveEnoughSticks = false; + for (Stack stack : player.getInventory().get()) { + if (Item.isWood(stack.getItem()) && stack.haveEnoughQuantity(PickaxeRecipe.WoodRecipe.NB_WOODS)) + haveEnoughWoods = true; + if (Item.isStick(stack.getItem()) && stack.haveEnoughQuantity(PickaxeRecipe.NB_STICKS)) + haveEnoughSticks = true; + } + + assertTrue(haveEnoughWoods); + assertTrue(haveEnoughSticks); + Tool woodPickaxe = Craft.pickaxe(environment, MaterialSet.WOOD); + assertTrue(!Objects.isNull(woodPickaxe) && Tool.isPickaxe(woodPickaxe) && MaterialSet.isWood(woodPickaxe.getMaterial())); + player.pickup(woodPickaxe); + + boolean havePickaxe = false; + for (Stack stack : player.getInventory().get()) + if (Tool.isPickaxe((Tool) stack.getItem())) + havePickaxe = true; + assertTrue(havePickaxe); + + + boolean dontHaveWoods = true; + boolean dontHaveSticks = true; + for (Stack stack : player.getInventory().get()) { + System.out.println(stack.getItem()); + if (!Item.isWood(stack.getItem()) && stack.haveEnoughQuantity(PickaxeRecipe.WoodRecipe.NB_WOODS)) { + dontHaveWoods = false; + break; + } else if (!Item.isStick(stack.getItem()) && stack.haveEnoughQuantity(PickaxeRecipe.NB_STICKS)) { + dontHaveSticks = false; + break; + } + } + assertTrue(dontHaveSticks && dontHaveWoods); + } +} diff --git a/src/test/java/fr/sae/terraria/modele/entities/player/inventory/InventoryTest.java b/src/test/java/fr/sae/terraria/modele/entities/player/inventory/InventoryTest.java new file mode 100644 index 0000000..0e46f39 --- /dev/null +++ b/src/test/java/fr/sae/terraria/modele/entities/player/inventory/InventoryTest.java @@ -0,0 +1,44 @@ +package fr.sae.terraria.modele.entities.player.inventory; + +import fr.sae.terraria.modele.Environment; +import fr.sae.terraria.modele.entities.blocks.Block; +import fr.sae.terraria.modele.entities.blocks.BlockSet; +import fr.sae.terraria.modele.entities.player.Player; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + + +public class InventoryTest +{ + private static Environment environment; + private static Inventory inventory; + + + @BeforeAll public static void init() + { + environment = new Environment(1., 1.); + Player player = environment.getPlayer(); + inventory = player.getInventory(); + } + + @Test public final void nbStacksIntoInventoryTest() + { + for (int i = 0; i < Stack.MAX; i++) + inventory.put(new Block(BlockSet.DIRT, environment)); + assertEquals(2, inventory.nbStacksIntoInventory()); + + for (int i = 0; i < Stack.MAX; i++) + inventory.put(new Block(BlockSet.DIRT, environment)); + assertEquals(3, inventory.nbStacksIntoInventory()); + } + + @Test public final void nbItemsIntoStackTest() + { + inventory.cursorProperty().set(0); + for (int i = 0; i < Stack.MAX; i++) + inventory.put(new Block(BlockSet.DIRT, environment)); + assertEquals(Stack.MAX, inventory.getStack().getNbItems()); + } +}