gyromite_ya/src/modele/calculs/Jeu.java

297 lines
9.4 KiB
Java

/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package modele.calculs;
import modele.calculs.Controle4Directions;
import modele.calculs.Direction;
import modele.calculs.Gravite;
import modele.calculs.IO.LecteurFichier;
import modele.calculs.Ordonnanceur;
import modele.donnees.*;
import modele.donnees.Colonne;
import modele.donnees.Menu;
import java.awt.*;
import java.util.ArrayList;
import java.util.HashMap;
/** Actuellement, cette classe gère les postions
* (ajouter conditions de victoire, chargement du plateau, etc.)
*/
public class Jeu {
public static final int SIZE_X = 20;
public static final int SIZE_Y = 10;
// compteur de déplacements horizontal et vertical (1 max par défaut, à chaque pas de temps)
private HashMap<ElementPhysique, Integer> cmptDeplH = new HashMap<ElementPhysique, Integer>();
private HashMap<ElementPhysique, Integer> cmptDeplV = new HashMap<ElementPhysique, Integer>();
private Heros hector;
private HashMap<ElementDynamique, Point> map = new HashMap<ElementDynamique, Point>(); // permet de récupérer la position d'une entité à partir de sa référence
private HashMap<ObjetGyromide, Point> mapInit = new HashMap<ObjetGyromide, Point>(); // N'est utilisé qu'a l'initialisation. Permet d'initialiser la grille
private ObjetGyromide[][][] grilleEntites = new ObjetGyromide[SIZE_X][SIZE_Y][2]; // permet de récupérer une entité à partir de ses coordonnées
private Ordonnanceur ordonnanceur = new Ordonnanceur(this);
// Etat du jeu courant. 0 = ecran titre, 2 = Menu choix, 4 = Plateau Jeu (les valeurs entre sont les valeurs de transitions)
private int state = 0;
public synchronized int getState() {
int retour = state;
if (state % 2 == 1) state ++;
return retour;
}
public Jeu() {
startTitleScreen();
}
public void resetCmptDepl() {
cmptDeplH.clear();
cmptDeplV.clear();
}
public void start(long _pause) {
ordonnanceur.start(_pause);
}
public ObjetGyromide[][][] getGrille() {
return grilleEntites;
}
public Heros getHector() {
return hector;
}
// PARTIE INITIALISATIONS
private void initialisationDesEntites() {
this.state = 3;
LecteurFichier.loadMap("Map/test.gyro", this);
System.out.println("Map loaded");
}
public void startTitleScreen() {
this.state = 0;
MenuInput.getInstance().addEntiteDynamique(new Menu(this));
ordonnanceur.add(MenuInput.getInstance());
}
// PARTIE MANIPULATIONS ENTITE
public void addEntite(ObjetGyromide e, int x, int y) {
if(e instanceof ElementFond)
grilleEntites[x][y][1] = e;
else if (e instanceof ElementPhysique)
grilleEntites[x][y][0] = e;
if(e instanceof ElementDynamique)
map.put((ElementDynamique) e, new Point(x, y));
mapInit.put(e, new Point(x, y));
if(e instanceof Heros && hector == null) hector = (Heros) e;
}
/** Permet par exemple a une entité de percevoir sont environnement proche et de définir sa stratégie de déplacement
*
*/
public ElementPhysique regarderDansLaDirection(Entite e, Direction d) {
Point positionEntite = map.get(e);
return objetALaPosition(calculerPointCible(positionEntite, d));
}
public ElementFond regarderDerriereSoit(Entite e) {
Point positionEntite = map.get(e);
return fondALaPosition(positionEntite);
}
public ElementPhysique regarderDevantSoit(ElementFond e) {
Point positionEntite = map.get(e);
return objetALaPosition(positionEntite);
}
/** Si le déplacement de l'entité est autorisé (pas de mur ou autre entité), il est réalisé
* Sinon, rien n'est fait.
*/
public boolean deplacerEntite(ElementDynamique e, Direction d) {
boolean retour = false;
Point pCourant = map.get(e);
Point pCible = pCourant;
if(d != null) {
pCible = calculerPointCible(pCourant, d);
}
if (e instanceof Colonne) { // Si c'est un colonne
if(deplacerColonne((Colonne) e, pCourant, d))
retour = true;
} else if (contenuDansGrille(pCible) && e instanceof Entite) { // a adapter (collisions murs, etc.)
Entite ent = (Entite) e;
if(objetALaPosition(pCible) == null) {
// compter le déplacement : 1 deplacement horizontal et vertical max par pas de temps par entité
switch (d) {
case bas:
case haut:
if (cmptDeplV.get(ent) == null) {
cmptDeplV.put(ent, 1);
retour = true;
}
break;
case gauche:
case droite:
if (cmptDeplH.get(ent) == null) {
cmptDeplH.put(ent, 1);
retour = true;
}
break;
}
if (retour) {
deplacerEntite(pCourant, pCible, ent);
}
} else if((d == Direction.haut || d == Direction.bas) && objetALaPosition(pCible) instanceof Decor) {
killPlayer(ent);
}
} else if (e instanceof modele.donnees.Items) {
retour = true;
retirerItem(pCourant, (modele.donnees.Items) e);
}
return retour;
}
private void killPlayer(Entite e) {
System.out.println("Techniquement le joueur est mort");
}
private boolean deplacerColonne(Colonne c, Point pCible, Direction d) {
ArrayList<ElementDynamique> aDeplacer = new ArrayList<ElementDynamique>();
boolean deplctPossible = true;
for(int i = 0; i < 2; i++) {
pCible = calculerPointCible(pCible, d);
ElementPhysique ep = objetALaPosition(pCible);
if (ep instanceof Decor) {
deplctPossible = false;
break;
} else if (ep instanceof ElementDynamique && ep.peutEtreEcrase())
aDeplacer.add((ElementDynamique) ep);
else if (ep instanceof Colonne) {
break;
}
}
if(deplctPossible) {
for (ElementDynamique eD : aDeplacer) {
for(int i = 0; i < 2; i++) {
eD.avancerDirectionChoisie(d);
cmptDeplV.put((ElementPhysique) eD, null);
}
}
deplacerEntite(map.get(c), pCible, (Entite) c);
}
return deplctPossible;
}
private Point calculerPointCible(Point pCourant, Direction d) {
Point pCible = null;
switch(d) {
case haut: pCible = new Point(pCourant.x, pCourant.y - 1); break;
case bas : pCible = new Point(pCourant.x, pCourant.y + 1); break;
case gauche : pCible = new Point(pCourant.x - 1, pCourant.y); break;
case droite : pCible = new Point(pCourant.x + 1, pCourant.y); break;
}
return pCible;
}
private void deplacerEntite(Point pCourant, Point pCible, Entite e) {
grilleEntites[pCourant.x][pCourant.y][0] = null;
grilleEntites[pCible.x][pCible.y][0] = e;
map.put(e, pCible);
}
private void retirerItem(Point pCourant, modele.donnees.Items elt) {
grilleEntites[pCourant.x][pCourant.y][1] = null;
map.put((ElementDynamique) elt, new Point(-1, -1));
}
/** Indique si p est contenu dans la grille
*/
private boolean contenuDansGrille(Point p) {
return p.x >= 0 && p.x < SIZE_X && p.y >= 0 && p.y < SIZE_Y;
}
private ElementPhysique objetALaPosition(Point p) {
ObjetGyromide retour = objetGyALaPosition(p, 0);
if(retour instanceof ElementPhysique)
return (ElementPhysique) retour;
else
return null;
}
private ElementFond fondALaPosition(Point p) {
ObjetGyromide retour = objetGyALaPosition(p, 1);
if(retour instanceof ElementFond)
return (ElementFond) retour;
else
return null;
}
private ObjetGyromide objetGyALaPosition(Point p, int prof) {
ObjetGyromide retour = null;
if (contenuDansGrille(p)) {
retour = grilleEntites[p.x][p.y][prof];
}
return retour;
}
public Direction getDirection(ElementDynamique sujet, ElementDynamique cible) {
Point orig = map.get(sujet);
Point dest = map.get(cible);
if(orig.getX() - dest.getX() > 0)
return Direction.gauche;
else
return Direction.droite;
}
public double getDistance(ElementDynamique sujet, ElementDynamique cible) {
Point orig = map.get(sujet);
Point dest = map.get(cible);
return orig.distance(dest);
}
public Ordonnanceur getOrdonnanceur() {
return ordonnanceur;
}
// PARTIE MANIPULATION MENU
public boolean updateMenu(Direction d) {
switch (getState()) {
case 0:
if (d == Direction.action)
initialisationDesEntites();
break;
}
return true;
}
}