Skip to content
This repository has been archived by the owner on Nov 21, 2023. It is now read-only.

Commit

Permalink
Merge pull request #8 from NaulaN/develop
Browse files Browse the repository at this point in the history
Sprint n°2
  • Loading branch information
naulan-chrzaszcz authored May 29, 2022
2 parents b1a782e + 596cedf commit c5383c4
Show file tree
Hide file tree
Showing 72 changed files with 1,909 additions and 361 deletions.
Binary file added Cahier_d'initialisation.pdf
Binary file not shown.
18 changes: 10 additions & 8 deletions src/main/java/fr/sae/terraria/Terraria.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,27 +8,29 @@

import java.io.File;
import java.io.IOException;

import java.net.URL;


public class Terraria extends Application
{
// TODO: effet de profondeur dans la terre
private String titleWindow = "Terraria-Like";
private int widthWindow = 1280;
private int heightWindow = 720;
// Constants
public static final String srcPath = "src/main/resources/fr/sae/terraria/";
public static final double TARGET_FPS = .017;
public static final int DISPLAY_RENDERING_WIDTH = 465;
public static final int DISPLAY_RENDERING_HEIGHT = 256;

private final String titleWindow = "Terraria-Like";
private final int widthWindow = 1280;
private final int heightWindow = 720;


public static void main(String[] args) { launch(); }

public void start(Stage stage) throws IOException
{
/* TODO: Commencer par le menu */

URL pathFxml = Terraria.class.getResource("vue/game.fxml");
if (pathFxml == null)
pathFxml = new File("src/main/resources/fr/sae/terraria/vue/game.fxml").toURI().toURL();
pathFxml = new File(srcPath + "vue/game.fxml").toURI().toURL();

FXMLLoader fxmlLoader = new FXMLLoader(pathFxml);
Controller ctrl = new Controller(stage);
Expand Down
274 changes: 151 additions & 123 deletions src/main/java/fr/sae/terraria/controller/Controller.java

Large diffs are not rendered by default.

37 changes: 37 additions & 0 deletions src/main/java/fr/sae/terraria/modele/Clock.java
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(); }
}
148 changes: 106 additions & 42 deletions src/main/java/fr/sae/terraria/modele/Environment.java
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; }
}
93 changes: 93 additions & 0 deletions src/main/java/fr/sae/terraria/modele/GenerateEntity.java
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); }
}
Loading

0 comments on commit c5383c4

Please sign in to comment.