Permalink
Browse files

Sérialisation des cartes

J'ai implémenté la lecture / l'écriture des cartes en binaire.
Pour la grande carte, ça prend quand même 4Mo...
Je t'envoie la carte par mail pour ne pas la mettre dans le git.
Pour faire marcher le main, met "carte.dat" à la racine du projet.
Sinon, tu peux aussi la regénérer en décommentant le début du code.
  • Loading branch information...
1 parent fa42421 commit ef08ee95268a684fb36e370abf18ddc35ed4d527 Cédric Connes committed Nov 24, 2011
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
@@ -1,23 +1,30 @@
import java.awt.Color;
import java.awt.Graphics;
-import java.awt.Image;
-import java.awt.Rectangle;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+
+public class Carte implements Serializable {
+ private static final long serialVersionUID = 42L;
-public class Carte {
private static final int COUCHES_INF = 2;
private static final int COUCHES_SUP = 2;
private final Case[][] cases;
private final int largeur;
private final int hauteur;
- private Ecran ecran = null;
-
+ private transient Ecran ecran = null;
+
public Carte(int largeur, int hauteur) {
this(largeur, hauteur, null);
}
- public Carte(int largeur, int hauteur, Image fond) {
+ public Carte(int largeur, int hauteur, Element fond) {
cases = new Case[largeur][hauteur];
this.largeur = largeur;
this.hauteur = hauteur;
@@ -27,11 +34,11 @@ public Carte(int largeur, int hauteur, Image fond) {
cases[i][j].setCouche(0, fond);
}
}
-
+
public void setEcran(Ecran ecran) {
this.ecran = ecran;
}
-
+
public Ecran getEcran() {
return ecran;
}
@@ -43,26 +50,70 @@ public boolean existe(int i, int j) {
public Case getCase(int i, int j) {
return cases[i][j];
}
-
+
public void rafraichir(int iMin, int jMin, int iMax, int jMax) {
ecran.rafraichirCarte(32 * iMin, 32 * jMin, 32 * iMax + 31, 32 * jMax + 31);
}
- public void dessiner(Graphics g, int xBase, int yBase, Rectangle zone) {
+ public void dessiner(Graphics g, int xBase, int yBase,
+ int xMin, int yMin, int largeur, int hauteur) {
// Calcul de la zone à dessiner
- int iMin = zone.x < 0 ? (zone.x - 31) / 32 : zone.x / 32;
- int iMax = ((zone.x + zone.width - 1) + 31) / 32;
+ int iMin = xMin < 0 ? (xMin - 31) / 32 : xMin / 32;
+ int iMax = ((xMin + largeur - 1) + 31) / 32;
- int jMin = zone.y < 0 ? (zone.y - 31) / 32 : zone.y / 32;
- int jMax = ((zone.y + zone.height - 1) + 31) / 32;
+ int jMin = yMin < 0 ? (yMin - 31) / 32 : yMin / 32;
+ int jMax = ((yMin + hauteur - 1) + 31) / 32;
// Affichage des cases
g.setColor(Color.BLACK);
for (int j = jMin; j <= jMax; j++)
for (int i = iMin; i <= iMax; i++)
- if (i < 0 || j < 0 || i >= largeur || j >= hauteur)
+ if (i < 0 || j < 0 || i >= this.largeur || j >= this.hauteur)
g.fillRect(32 * i - xBase, 32 * j - yBase, 32, 32);
else
cases[i][j].dessiner(g, 32 * i - xBase, 32 * j - yBase);
}
+
+ @Override
+ public String toString() {
+ return super.toString() + " : " + largeur + "x" + hauteur;
+ }
+
+ public static void ecrire(Carte carte, File fichier) {
+ try {
+ ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(fichier));
+ out.writeObject(carte);
+ out.close();
+ } catch (IOException e) {
+ System.err.println("Le fichier " + fichier + " ne peut pas être écrit :\n" + e);
+ }
+ }
+
+ public void ecrire(File fichier) {
+ ecrire(this, fichier);
+ }
+
+ public static Carte lire(File fichier) {
+ ObjectInputStream in;
+ try {
+ in = new ObjectInputStream(new FileInputStream(fichier));
+ } catch (IOException e) {
+ System.err.println("Le fichier " + fichier + "ne peut pas être lu.");
+ return null;
+ }
+
+ Object obj = null;
+ try {
+ obj = in.readObject();
+ } catch (IOException e) {
+ } catch (ClassNotFoundException e) {
+ }
+
+ if ((obj != null) && (obj instanceof Carte)) {
+ return (Carte) obj;
+ } else {
+ System.err.println("Le fichier " + fichier + " ne contient pas une carte valide.");
+ return null;
+ }
+ }
}
View
@@ -1,29 +1,32 @@
import java.awt.Graphics;
-import java.awt.Image;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.Serializable;
-
-
-public class Case {
+public class Case implements Serializable {
+ private static final long serialVersionUID = 42L;
+
private final Carte carte;
private final int i, j;
private final int couchesInf, nbCouches;
- private final Image couches[];
- private Personnage perso = null;
- private boolean libre = true;
+ private final Element couches[];
+ private boolean bloquee = false;
+ private transient Personnage perso = null;
+ private transient boolean libre = ! bloquee;
public Case(Carte carte, int i, int j, int couchesInf, int couchesSup) {
this.carte = carte;
this.i = i;
this.j = j;
this.couchesInf = couchesInf;
nbCouches = couchesInf + couchesSup;
- couches = new Image[nbCouches];
+ couches = new Element[nbCouches];
for (int k = 0; k < nbCouches; k++) couches[k] = null;
}
- public void setCouche(int couche, Image image) {
- couches[couche] = image;
+ public void setCouche(int couche, Element element) {
+ couches[couche] = element;
}
public Personnage getPerso() {
@@ -34,6 +37,14 @@ public void setPerso(Personnage perso) {
this.perso = perso;
}
+ public boolean estBloquee() {
+ return bloquee;
+ }
+
+ public void setBloquee(boolean bloquee) {
+ this.bloquee = bloquee;
+ }
+
public boolean estLibre() {
return libre;
}
@@ -45,7 +56,7 @@ public void setLibre(boolean libre) {
public void dessiner(Graphics g, int x, int y) {
// Dessin des couches inférieures
for (int couche = 0; couche < couchesInf; couche++)
- if (couches[couche] != null) g.drawImage(couches[couche], x, y, null);
+ if (couches[couche] != null) g.drawImage(couches[couche].getImage(), x, y, null);
// Dessin des personnages éventuels
Personnage perso;
@@ -58,6 +69,11 @@ public void dessiner(Graphics g, int x, int y) {
// Dessin des couches supérieures
for (int couche = couchesInf; couche < nbCouches; couche++)
- if (couches[couche] != null) g.drawImage(couches[couche], x, y, null);
+ if (couches[couche] != null) g.drawImage(couches[couche].getImage(), x, y, null);
+ }
+
+ private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
+ in.defaultReadObject();
+ libre = ! bloquee;
}
}
View
@@ -1,5 +1,4 @@
import java.awt.Graphics;
-import java.awt.Rectangle;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.image.BufferedImage;
@@ -12,6 +11,7 @@
private Carte carte;
private int xBase, yBase;
private BufferedImage image;
+ private Graphics g;
public Ecran(Joueur joueur) {
this.joueur = joueur;
@@ -37,10 +37,11 @@ synchronized private void redimensionner() {
yBase = joueur.getY() - hauteur / 2 + 24;
if (largeur > 0 && hauteur > 0) {
image = new BufferedImage(largeur, hauteur, BufferedImage.TYPE_INT_ARGB);
- carte.dessiner(image.getGraphics(), xBase, yBase,
- new Rectangle(xBase, yBase, largeur, hauteur));
+ g = image.createGraphics();
+ carte.dessiner(g, xBase, yBase, xBase, yBase, largeur, hauteur);
repaint();
} else {
+ g = null;
image = null;
}
}
@@ -60,8 +61,7 @@ synchronized public void rafraichirCarte(int xMin, int yMin, int xMax, int yMax)
final int hauteur = yMax - yMin;
if (largeur <= 0 || hauteur <= 0) return;
- carte.dessiner(image.getGraphics(), xBase, yBase,
- new Rectangle(xMin, yMin, largeur, hauteur));
+ carte.dessiner(g, xBase, yBase, xMin, yMin, largeur, hauteur);
repaint(xMin - xBase, yMin - yBase, largeur, hauteur);
}
@@ -74,8 +74,7 @@ protected void paintComponent(Graphics g) {
@Override
public void carteChangee(Carte carte) {
this.carte = carte;
- carte.dessiner(image.getGraphics(), xBase, yBase,
- new Rectangle(xBase, yBase, getWidth(), getHeight()));
+ carte.dessiner(g, xBase, yBase, xBase, yBase, getWidth(), getHeight());
repaint();
}
@@ -88,36 +87,27 @@ synchronized public void persoBouge(Direction dir) {
yBase = joueur.getY() - hauteur / 2 + 24;
if (image == null) return;
- final Graphics g = image.getGraphics();
switch (dir) {
case BAS:
g.copyArea(0, 8, largeur, hauteur - 8, 0, -8);
- carte.dessiner(g, xBase, yBase,
- new Rectangle(xBase, yBase + hauteur - 8, largeur, 8));
- carte.dessiner(g, xBase, yBase,
- new Rectangle(joueur.getX(), joueur.getY() - 8, 32, 56));
+ carte.dessiner(g, xBase, yBase, xBase, yBase + hauteur - 8, largeur, 8);
+ carte.dessiner(g, xBase, yBase, joueur.getX(), joueur.getY() - 8, 32, 56);
break;
case GAUCHE:
g.copyArea(0, 0, largeur - 8, hauteur, 8, 0);
- carte.dessiner(g, xBase, yBase,
- new Rectangle(xBase, yBase, 8, hauteur));
- carte.dessiner(g, xBase, yBase,
- new Rectangle(joueur.getX(), joueur.getY(), 40, 48));
+ carte.dessiner(g, xBase, yBase, xBase, yBase, 8, hauteur);
+ carte.dessiner(g, xBase, yBase, joueur.getX(), joueur.getY(), 40, 48);
break;
case DROITE:
g.copyArea(8, 0, largeur - 8, hauteur, -8, 0);
- carte.dessiner(g, xBase, yBase,
- new Rectangle(xBase + largeur - 8, yBase, 8, hauteur));
- carte.dessiner(g, xBase, yBase,
- new Rectangle(joueur.getX() - 8, joueur.getY(), 40, 48));
+ carte.dessiner(g, xBase, yBase, xBase + largeur - 8, yBase, 8, hauteur);
+ carte.dessiner(g, xBase, yBase, joueur.getX() - 8, joueur.getY(), 40, 48);
break;
case HAUT:
g.copyArea(0, 0, largeur, hauteur - 8, 0, 8);
- carte.dessiner(g, xBase, yBase,
- new Rectangle(xBase, yBase, largeur, 8));
- carte.dessiner(g, xBase, yBase,
- new Rectangle(joueur.getX(), joueur.getY(), 32, 56));
+ carte.dessiner(g, xBase, yBase, xBase, yBase, largeur, 8);
+ carte.dessiner(g, xBase, yBase, joueur.getX(), joueur.getY(), 32, 56);
break;
}
repaint();
View
@@ -0,0 +1,27 @@
+import java.awt.image.BufferedImage;
+import java.io.ObjectStreamException;
+import java.io.Serializable;
+
+
+public class Element implements Serializable {
+ private static final long serialVersionUID = 42L;
+
+ private final String nomTheme;
+ private final int i, j;
+ private final transient BufferedImage image;
+
+ public Element(String nomTheme, int i, int j, BufferedImage image) {
+ this.nomTheme = nomTheme;
+ this.i = i;
+ this.j = j;
+ this.image = image;
+ }
+
+ public BufferedImage getImage() {
+ return image;
+ }
+
+ private Object readResolve() throws ObjectStreamException {
+ return Ressources.getElement(nomTheme, i, j);
+ }
+}
View
@@ -1,3 +1,4 @@
+import java.io.File;
import java.io.IOException;
import javax.swing.JFrame;
@@ -6,32 +7,52 @@
@SuppressWarnings("serial")
public class Fenetre extends JFrame {
public Fenetre() throws IOException {
+ long debut = System.currentTimeMillis();
+ /*
Theme theme = Ressources.getTheme("tileset.png");
Carte carte = new Carte(20 * theme.getLargeur(), theme.getHauteur(),
- Ressources.getImage("tileset.png", 0, 0));
+ Ressources.getElement("theme3.png", 0, 0));
- for (int j = 0; j < 10/*theme.getHauteur()/**/; j++)
+ for (int j = 0; j < theme.getHauteur(); j++)
for (int k = 0; k < 20; k++)
for (int i = 0; i < theme.getLargeur(); i++)
- carte.getCase(i + k * theme.getLargeur(), j).setCouche(1, theme.getImage(i, j));
-
+ carte.getCase(i + k * theme.getLargeur(), j).setCouche(1, theme.getElement(i, j));
+
+ System.out.println("Début écriture (" + (System.currentTimeMillis() - debut) + ") : " + getMemoire());
+ carte.ecrire(new File("carte.dat"));
+ System.out.println("Fin écriture (" + (System.currentTimeMillis() - debut) + ") : " + getMemoire());
+ */
+ System.out.println("Début lecture (" + (System.currentTimeMillis() - debut) + ") : " + getMemoire());
+ Carte carte = Carte.lire(new File("carte.dat"));
+ System.out.println("Fin lecture (" + (System.currentTimeMillis() - debut) + ") : " + getMemoire());
+
Apparence apparence = Ressources.getApparence("charset.png");
- Joueur joueur = new Joueur(apparence, carte, 10, 17);
+ Joueur joueur = new Joueur(apparence, carte, 3, 3);
for (int i = 0; i < 10; i++) for (int j = 0; j < 10; j++)
new PNJ(Ressources.getApparence("charset2.png"), carte, 5 + i, 20 + j, 100, 1000);
-
+
Ecran ecran = new Ecran(joueur);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setContentPane(ecran);
setSize(400, 400);
-
+
+ System.out.println("Avant nettoyage : " + getMemoire());
Ressources.nettoyerThemes();
+ System.gc();
+ System.out.println("Après nettoyage : " + getMemoire());
setVisible(true);
}
+
+ public static String getMemoire() {
+ final Runtime r = Runtime.getRuntime();
+ final long total = r.totalMemory();
+ final long libre = r.freeMemory();
+ return ((total - libre) / 1024) + " ko / " + (total / 1024) + " ko";
+ }
public static void main(String[] args) throws IOException {
new Fenetre();
Oops, something went wrong.

0 comments on commit ef08ee9

Please sign in to comment.