package fr.raversoft.yllisanSkies.engine;
import fr.raversoft.yllisanSkies.tests.Jeu;
import fr.raversoft.yllisanSkies.MainGame;
import java.io.IOException;
import org.newdawn.slick.*;
import org.newdawn.slick.geom.Rectangle;
/**
*
* @author JALOUZET Jérémie
*/
public class Camera {
private MainGame mainGame = null;
/**
* Ecran du jeu
*/
private Screen ecran = null;
/**
* Map actuelle
*/
private Map map = null;
// Personnage
/**
* Largeur du personnage
*/
public final static int PERSONNAGE_LARGEUR = 48;
/**
* Hauteur du personnage
*/
public final static int PERSONNAGE_HAUTEUR = 64;
/**
* Déplacement (en nombre de pixels) du personnage à chaque pas
*/
public int deplacement_pixels = 4;
/**
* Etape de mouvement
*/
SpriteSheet sprite = null;
private int etape_mouvement = 0;
private int nombre_etapes = 8;
private int pas = 1;
private int nombre_pas = 2;
/**
* Ecart dans le premier pixel de l'image du personnage et le premier pixel
* du personnage
*/
private int perso_ecartHorizontal = PERSONNAGE_HAUTEUR / 8;
private int perso_ecranX = 0;
private int perso_ecranY = 0;
private int perso_mapX = 0;
private int perso_mapY = 0;
private Rectangle perso_contour = null;
private boolean perso_enMouvement = false;
private Direction perso_direction = null;
// Animations du personnage
/**
* Temps d'une frame
*/
private int animation_tempsFrame = 120;
private Animation animation_actuelle = null;
private Animation animation_marche_gauche = new Animation(false);
private Animation animation_marche_droite = new Animation(false);
private Animation animation_marche_haut = new Animation(false);
private Animation animation_marche_bas = new Animation(false);
public Camera(MainGame mainGame, Screen ecran, Map map, int x, int y, Direction direction) throws SlickException, IOException {
this.mainGame = mainGame;
this.ecran = ecran;
this.map = map;
this.perso_mapX = x;
this.perso_mapY = y;
this.perso_direction = direction;
initialisation();
}
private void initialisation() throws SlickException, IOException {
perso_contour = new Rectangle(0, 0, Jeu.CASE, Jeu.CASE);
initAnimations();
updateEcranX();
updateEcranY();
}
public void gestionClavier(GameContainer container) throws SlickException {
if (container.getInput().isKeyDown(Commands.left())) {
deplacement(Direction.Gauche);
} else if (container.getInput().isKeyDown(Commands.right())) {
deplacement(Direction.Droite);
} else if (container.getInput().isKeyDown(Commands.up())) {
deplacement(Direction.Haut);
} else if (container.getInput().isKeyDown(Commands.down())) {
deplacement(Direction.Bas);
} else {
setImmobile();
}
}
public int getMilieuX() {
return ecran.getMilieuLargeur() - Jeu.CASE;
}
public int getMilieuY() {
return ecran.getMilieuHauteur() - (Jeu.CASE / 2);
}
public Rectangle getPersoContour() {
return perso_contour;
}
public void changeAnimation() {
switch (perso_direction) {
case Gauche:
animation_actuelle = animation_marche_gauche;
break;
case Droite:
animation_actuelle = animation_marche_droite;
break;
case Haut:
animation_actuelle = animation_marche_haut;
break;
case Bas:
animation_actuelle = animation_marche_bas;
break;
}
}
private void loadAnimations(Animation animation, SpriteSheet sprite, int i) {
animation.addFrame(sprite.getSprite(0, i), animation_tempsFrame);
animation.addFrame(sprite.getSprite(1, i), animation_tempsFrame);
animation.addFrame(sprite.getSprite(2, i), animation_tempsFrame);
animation.addFrame(sprite.getSprite(1, i), animation_tempsFrame);
}
private void initAnimations() throws SlickException, IOException {
sprite = new SpriteSheet(Resources.getCharSet(mainGame.getParty().getPersonnageLeader().getImage()), PERSONNAGE_LARGEUR, PERSONNAGE_HAUTEUR);
changeAnimation();
loadAnimations(animation_marche_haut, sprite, 0);
loadAnimations(animation_marche_droite, sprite, 1);
loadAnimations(animation_marche_bas, sprite, 2);
loadAnimations(animation_marche_gauche, sprite, 3);
}
public Direction getDirection() {
return perso_direction;
}
public boolean estEnMouvement() {
return perso_enMouvement;
}
public void setEnMouvement(boolean b) {
perso_enMouvement = b;
if (!b) {
etape_mouvement = 0;
}
}
public boolean entreEnCollision() throws SlickException {
for (int i = 0; i < map.getNombreBlocs(); i++) {
Bloc bloc = map.getBloc(i);
if (perso_contour.intersects(bloc.getForme())) {
return true;
}
}
return false;
}
public void deplacement(Direction direction) throws SlickException {
etape_mouvement++;
this.perso_direction = direction;
changeAnimation();
switch (direction) {
case Gauche:
addEcranX(-deplacement_pixels);
map.updateBlocs();
if ((ecran.estModeFantome() || !entreEnCollision()) && (getPersoMapX() >= 0)) {
setEnMouvement(true);
} else {
setEnMouvement(false);
setImmobile();
addEcranX(deplacement_pixels);
}
break;
case Droite:
addEcranX(deplacement_pixels);
map.updateBlocs();
if ((ecran.estModeFantome() || !entreEnCollision()) && (getPersoMapX() <= (map.getLargeur() - Jeu.CASE))) {
setEnMouvement(true);
} else {
setEnMouvement(false);
setImmobile();
addEcranX(-deplacement_pixels);
}
break;
case Haut:
addEcranY(-deplacement_pixels);
map.updateBlocs();
if ((ecran.estModeFantome() || !entreEnCollision()) && (getPersoMapY() >= 0)) {
setEnMouvement(true);
} else {
setEnMouvement(false);
setImmobile();
addEcranY(deplacement_pixels);
}
break;
case Bas:
addEcranY(deplacement_pixels);
map.updateBlocs();
if ((ecran.estModeFantome() || !entreEnCollision()) && (getPersoMapY() <= (map.getHauteur() - Jeu.CASE))) {
setEnMouvement(true);
} else {
setEnMouvement(false);
setImmobile();
addEcranY(-deplacement_pixels);
}
break;
}
if (etape_mouvement >= nombre_etapes) {
setEnMouvement(false);
pas++;
if (pas >= nombre_pas) {
pas = 0;
}
}
}
public Animation getAnimationActuelle() {
return animation_actuelle;
}
public void setImmobile() {
if (pas == 1) {
animation_actuelle.setCurrentFrame(3);
} else {
animation_actuelle.setCurrentFrame(1);
}
}
private void updatePolygoneX() {
perso_contour.setX(perso_ecranX + perso_ecartHorizontal);
}
private void updatePolygoneY() {
perso_contour.setY(perso_ecranY + Jeu.CASE);
}
public int getPersoEcranX() {
return perso_ecranX;
}
public int getPersoEcranY() {
return perso_ecranY;
}
public int getPersoMapX() {
return perso_mapX;
}
public int getPersoMapY() {
return perso_mapY;
}
private void updateEcranX() {
int diff = perso_mapX - getMilieuX();
if (diff > ((map.getLargeur() - ecran.getLargeur()))) {
map.x = -map.getLargeur() + ecran.getLargeur();
perso_ecranX = ecran.getLargeur() - (map.getLargeur() - diff - getMilieuX() + perso_ecartHorizontal);
} else if (diff >= 0) {
map.x = -diff;
perso_ecranX = getMilieuX() - perso_ecartHorizontal;
} else if (diff < 0) {
map.x = 0;
perso_ecranX = perso_mapX - perso_ecartHorizontal;
}
updatePolygoneX();
}
private void updateEcranY() {
int diff = perso_mapY - getMilieuY();
if (diff > (map.getHauteur() - ecran.getHauteur())) {
map.y = -map.getHauteur() + ecran.getHauteur();
perso_ecranY = ecran.getHauteur() - (map.getHauteur() - diff - getMilieuY() + Jeu.CASE);
} else if (diff >= 0) {
map.y = -diff;
perso_ecranY = getMilieuY() - Jeu.CASE;
} else if (diff < 0) {
map.y = 0;
perso_ecranY = perso_mapY - Jeu.CASE;
}
updatePolygoneY();
}
public void addEcranX(int i) {
perso_mapX += i;
updateEcranX();
}
public void addEcranY(int i) {
perso_mapY += i;
updateEcranY();
}
public void setEcranX(int i) {
perso_ecranX = i;
updatePolygoneX();
}
public void setEcranY(int i) {
perso_ecranY = i;
updatePolygoneY();
}
public void affiche(Graphics g) {
map.afficheCouche(Map.COUCHE_BASSE);
map.afficheCouche(Map.COUCHE_INTERMEDIAIRE);
affichePersonnage(g);
map.afficheCouche(Map.COUCHE_HAUTE);
map.updateBlocs();
}
private void affichePersonnage(Graphics g) {
g.drawAnimation(getAnimationActuelle(), getPersoEcranX(), getPersoEcranY());
getAnimationActuelle().setAutoUpdate(estEnMouvement());
}
}