This repository has been archived by the owner on Nov 21, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #8 from NaulaN/develop
Sprint n°2
- Loading branch information
Showing
72 changed files
with
1,909 additions
and
361 deletions.
There are no files selected for viewing
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
274 changes: 151 additions & 123 deletions
274
src/main/java/fr/sae/terraria/controller/Controller.java
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
package fr.sae.terraria.modele; | ||
|
||
import javafx.beans.property.SimpleIntegerProperty; | ||
|
||
|
||
public class Clock | ||
{ | ||
public static final int ONE_MINUTE_INGAME = 37; | ||
public static final int ONE_DAY_INGAME = 1440; | ||
private final SimpleIntegerProperty minutes; | ||
private final SimpleIntegerProperty days; | ||
|
||
|
||
public Clock() | ||
{ | ||
minutes = new SimpleIntegerProperty(0); | ||
days = new SimpleIntegerProperty(0); | ||
} | ||
|
||
public void updates(int ticks) | ||
{ | ||
// si environ 1 minute passe irl, le timer dans le jeu augmente de 10 minutes | ||
if (ticks%Clock.ONE_MINUTE_INGAME == 0) { | ||
if (getMinutes()+1 == ONE_DAY_INGAME) { | ||
days.setValue(getDays()+1); | ||
minutes.setValue(0); | ||
} else minutes.setValue(getMinutes()+1); | ||
} | ||
} | ||
|
||
public SimpleIntegerProperty minutesProperty() { return minutes; } | ||
public SimpleIntegerProperty daysProperty() { return days; } | ||
|
||
|
||
public int getMinutes() { return minutes.get(); } | ||
public int getDays() { return days.get(); } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,74 +1,138 @@ | ||
package fr.sae.terraria.modele; | ||
|
||
import fr.sae.terraria.modele.entities.*; | ||
import fr.sae.terraria.Terraria; | ||
import fr.sae.terraria.modele.blocks.TallGrass; | ||
import fr.sae.terraria.modele.entities.Player; | ||
import fr.sae.terraria.modele.entities.Rabbit; | ||
import fr.sae.terraria.modele.entities.entity.CollideObjectType; | ||
import fr.sae.terraria.modele.entities.entity.Entity; | ||
import fr.sae.terraria.modele.entities.entity.ReproductiveObjectType; | ||
import fr.sae.terraria.vue.View; | ||
import javafx.animation.Animation; | ||
import javafx.animation.KeyFrame; | ||
import javafx.animation.Timeline; | ||
import javafx.scene.input.KeyCode; | ||
import javafx.collections.FXCollections; | ||
import javafx.collections.ObservableList; | ||
import javafx.scene.image.Image; | ||
import javafx.util.Duration; | ||
|
||
import java.util.ArrayList; | ||
import java.util.HashMap; | ||
import java.util.Map; | ||
|
||
import static javafx.scene.input.KeyCode.D; | ||
import static javafx.scene.input.KeyCode.Q; | ||
import java.util.List; | ||
|
||
|
||
public class Environment | ||
{ | ||
private Player player; | ||
private ArrayList<Entity> entities; | ||
private Map<KeyCode, Boolean> keysInput = new HashMap<>(); | ||
private Clock clock; | ||
private final ObservableList<Entity> entities; | ||
|
||
private final TileMaps tileMaps; | ||
private final Player player; | ||
|
||
public double scaleMultiplicatorWidth; | ||
public double scaleMultiplicatorHeight; | ||
|
||
public int widthTile; | ||
public int heightTile; | ||
private int ticks = 0; | ||
|
||
|
||
public Environment() | ||
public Environment(double scaleMultiplicatorWidth, double scaleMultiplicatorHeight) | ||
{ | ||
entities = new ArrayList<>(); | ||
this.scaleMultiplicatorWidth = scaleMultiplicatorWidth; | ||
this.scaleMultiplicatorHeight = scaleMultiplicatorHeight; | ||
|
||
this.tileMaps = new TileMaps(); | ||
this.tileMaps.load(Terraria.srcPath + "maps/map_0.json"); | ||
|
||
player = new Player(0,0, 3, 1); | ||
player.setPv(20); | ||
player.setVelocity(2); | ||
this.clock = new Clock(); | ||
this.entities = FXCollections.observableArrayList(); | ||
this.widthTile = (int) (scaleMultiplicatorWidth * TileMaps.TILE_DEFAULT_SIZE); | ||
this.heightTile = (int) (scaleMultiplicatorHeight * TileMaps.TILE_DEFAULT_SIZE); | ||
|
||
this.player = new Player(this, (5*widthTile), (3*heightTile)); | ||
this.player.setVelocity(5); | ||
this.player.setPv(4); | ||
Image image = View.loadAnImage("sprites/player/player_idle.png", scaleMultiplicatorWidth, scaleMultiplicatorHeight); | ||
this.player.setRect((int) image.getWidth(), (int) image.getHeight()); | ||
image.cancel(); | ||
|
||
gameLoop(); | ||
} | ||
|
||
private void gameLoop() | ||
/** Evite que l'entité sort de la fenêtre. */ | ||
private void worldLimit(Entity entity) | ||
{ | ||
Timeline loop = new Timeline(); | ||
loop.setCycleCount(Timeline.INDEFINITE); | ||
double widthScreen = (scaleMultiplicatorWidth * Terraria.DISPLAY_RENDERING_WIDTH); | ||
|
||
KeyFrame keyFrame = new KeyFrame(Duration.seconds(0.017), (ev -> { | ||
eventInput(); | ||
getPlayer().updates(); | ||
boolean exceedsScreenOnLeft = entity.offset[0] == Entity.IS_MOVING_LEFT && entity.getX() < 0; | ||
boolean exceedsScreenOnRight = entity.offset[0] == Entity.IS_MOVING_RIGHT && entity.getX() > (widthScreen - entity.getRect().getWidth()); | ||
if (exceedsScreenOnLeft || exceedsScreenOnRight) | ||
entity.offset[0] = (entity instanceof Rabbit) ? ((-1) * entity.offset[0]) : Entity.IDLE; | ||
} | ||
|
||
ticks++; | ||
/** La boucle principale du jeu */ | ||
private void gameLoop() | ||
{ | ||
Timeline loop = new Timeline(); | ||
loop.setCycleCount(Animation.INDEFINITE); | ||
|
||
List<Entity> entitiesAtAdded = new ArrayList<>(); | ||
KeyFrame keyFrame = new KeyFrame(Duration.seconds(Terraria.TARGET_FPS), (ev -> { | ||
this.player.offset[0] = Entity.IDLE; | ||
this.player.eventInput(); | ||
this.worldLimit(this.player); | ||
|
||
// Ajoute les entités ReproductiveObjectType | ||
for (Entity entity : entitiesAtAdded) | ||
this.entities.add(0, entity); | ||
entitiesAtAdded.clear(); | ||
|
||
// Génère aléatoirement des entités | ||
GenerateEntity.tree(this); | ||
GenerateEntity.tallGrass(this); | ||
GenerateEntity.rabbit(this); | ||
|
||
for (Entity entity : entities) | ||
{ | ||
// Fait sauter ou non le lapin | ||
if (entity instanceof Rabbit) { | ||
boolean mustJump = ticks%Rabbit.JUMP_FREQUENCY == 0; | ||
if (mustJump) { | ||
boolean jumpOrNot = Math.random() < Rabbit.LUCK_OF_JUMPING; | ||
if (jumpOrNot && entity.offset[1] != Entity.IS_FALLING) | ||
entity.jump(); | ||
} | ||
} | ||
|
||
if (entity instanceof CollideObjectType) { | ||
this.worldLimit(entity); | ||
((CollideObjectType) entity).collide(); | ||
} | ||
|
||
if (entity instanceof ReproductiveObjectType) { | ||
// Reproduit les hautes herbes | ||
boolean tallGrassMustReproduce = ticks%TallGrass.REPRODUCTION_RATE == 0; | ||
if (entity instanceof TallGrass && tallGrassMustReproduce) | ||
entitiesAtAdded.addAll(((ReproductiveObjectType) entity).reproduction(this)); | ||
} | ||
entity.updates(); | ||
} | ||
|
||
this.player.collide(); | ||
this.player.updates(); | ||
|
||
this.clock.updates(ticks); | ||
this.ticks++; | ||
})); | ||
|
||
loop.getKeyFrames().add(keyFrame); | ||
loop.play(); | ||
} | ||
|
||
public void eventInput() | ||
{ | ||
int countKeys[] = new int[1]; | ||
keysInput.forEach((key, value) -> { | ||
if (key == D && value) | ||
getPlayer().moveRight(); | ||
if (key == Q && value) | ||
getPlayer().moveLeft(); | ||
|
||
if (!value) | ||
countKeys[0]++; | ||
if (countKeys[0] == keysInput.size()) | ||
getPlayer().idle(); | ||
}); | ||
} | ||
|
||
|
||
public Map<KeyCode, Boolean> getKeysInput() { return keysInput; } | ||
public ArrayList<Entity> getEntities() { return entities; } | ||
public Player getPlayer() { return player; } | ||
} | ||
public ObservableList<Entity> getEntities() { return this.entities; } | ||
public TileMaps getTileMaps() { return this.tileMaps; } | ||
public Player getPlayer() { return this.player; } | ||
public Clock getGameClock() { return this.clock; } | ||
public int getTicks() { return this.ticks; } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
package fr.sae.terraria.modele; | ||
|
||
import fr.sae.terraria.modele.blocks.TallGrass; | ||
import fr.sae.terraria.modele.blocks.Tree; | ||
import fr.sae.terraria.modele.entities.Rabbit; | ||
import fr.sae.terraria.modele.entities.entity.Entity; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
import java.util.Random; | ||
|
||
import static fr.sae.terraria.modele.blocks.TallGrass.TALL_GRASS_SPAWN_RATE; | ||
import static fr.sae.terraria.modele.blocks.TallGrass.WHEN_SPAWN_A_TALL_GRASS; | ||
import static fr.sae.terraria.modele.blocks.Tree.TREE_SPAWN_RATE; | ||
import static fr.sae.terraria.modele.blocks.Tree.WHEN_SPAWN_A_TREE; | ||
import static fr.sae.terraria.modele.entities.Rabbit.RABBIT_SPAWN_RATE; | ||
import static fr.sae.terraria.modele.entities.Rabbit.WHEN_SPAWN_A_RABBIT; | ||
|
||
|
||
public class GenerateEntity | ||
{ | ||
private static final Random random = new Random(); | ||
|
||
|
||
/** | ||
* Génère une entité selon de quand il spawn et du pourcent de change qu'il spawn réellement. | ||
* | ||
* @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 | ||
*/ | ||
private static void generateAnEntity(Environment environment, Entity e, int whenSpawn, double spawnRate) | ||
{ | ||
List<Entity> entities = environment.getEntities(); | ||
TileMaps maps = 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++) | ||
// Est-ce que l'arbre doit spawn sur ce 'y' | ||
if (Math.random() < spawnRate) { | ||
List<Integer> locFloorsOnAxisX = findFloors(maps, y); | ||
// Si il y a du sol sur la ligne | ||
if (!locFloorsOnAxisX.isEmpty()) { | ||
int onWhichFloor = random.nextInt(locFloorsOnAxisX.size()); | ||
int targetFloor = locFloorsOnAxisX.get((onWhichFloor == 0) ? onWhichFloor : onWhichFloor - 1); | ||
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) { | ||
for (Entity entity : entities) | ||
if (entity instanceof Tree && xEntity == entity.getX() && yEntity == entity.getY()) | ||
// Un arbre est déjà present ? Il ne le génère pas et arrête complétement la fonction | ||
return; | ||
e.setX(xEntity); | ||
e.setY(yEntity); | ||
e.getGravity().setXInit(xEntity); | ||
e.getGravity().setYInit(yEntity); | ||
e.setRect(widthTile, heightTile); | ||
// Une fois une position trouvée, on l'ajoute en tant qu'entité pour qu'il puisse ensuite l'affiché | ||
entities.add(0, e); | ||
} | ||
// Une fois l'arbre généré, il arrête complétement toute la fonction | ||
return; | ||
} | ||
// Sinon on retourne vers la premiere boucle 'for' | ||
} | ||
} | ||
|
||
/** Range les positions du sol sur la ligne 'y' */ | ||
private static List<Integer> findFloors(TileMaps maps, int y) | ||
{ | ||
List<Integer> localisation = new ArrayList<>(); | ||
for (int x = 0; x < maps.getWidth(); x++) { | ||
int targetTile = maps.getTile(x, y); | ||
|
||
if (targetTile == TileMaps.FLOOR_TOP || targetTile == TileMaps.FLOOR_RIGHT || targetTile == TileMaps.FLOOR_LEFT) | ||
localisation.add(x); | ||
} | ||
|
||
return localisation; | ||
} | ||
|
||
/** À 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(), WHEN_SPAWN_A_TREE, 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(), WHEN_SPAWN_A_TALL_GRASS, TALL_GRASS_SPAWN_RATE); } | ||
/** À un certain moment, grace au tick, il va générer des lapins sur un sol */ | ||
public static void rabbit(Environment environment) { generateAnEntity(environment, new Rabbit(environment), WHEN_SPAWN_A_RABBIT, RABBIT_SPAWN_RATE); } | ||
} |
Oops, something went wrong.