|
|
|
|
El món i els éssers
del món |
|
|
|
|
|
El MonVisible
que has creat a la pràctica
2 no és res més que un dispositiu per veure les
coses que passen. Però a on passen de veritat les coses és
a la memòria de la màquina, en algun tros de la memòria
que, tot definint classes adequades, has de determinar. |
|
|
|
|
|
Hi haurà, doncs, una classe
Mon, que ha de contenir: |
|
|
|
|
|
- la quadrícula on viuran (o moriran) els éssers,
- les lleis de la vida, és a dir, les regles que
fan que uns éssers visquin i d'altres morin, i
- la manera com l'estat del món ha de pintar-se
al MonVisible.
|
|
|
|
|
|
Per representar els éssers
caldrà definir-los com a objectes de la classe Esser,
la qual ha de contenir, com a mínim, |
|
|
|
|
|
- l'estat de viu o mort de l'ésser que representa,
i
- la manera com aquest Esser
ha de pintar-se al MonVisible
|
|
|
|
|
|
Els éssers del món: |
|
|
|
|
|
 |
Comencem pels éssers.
Al projecte JocDeLaVida hi crees la nova classe
Esser: |
|
|
|
|
 |
/**
* La classe Esser representa un ésser dels que poblen
el món
* del "Joc de la Vida".
*
* @author (el vostre nom)
* @version (un número de versió o la data)
*/
public class Esser {
/**
* L'estat de viu o mort d'aquest Esser.
*/
private boolean esViu=false;
/**
* Mètode constructor per a objectes
de la classe Esser.
* @param esViu l'estat de viu o mort d'aquest
Esser.
*/
public Esser(boolean esViu) { // constructor
this.esViu=esViu;
}
}
|
|
|
|
|
|
|
i, com que, sovint, haurem de
preguntar o variar l'estat de viu o mort d'aquest Esser,
calen un mètode getter i un altre mètode setter
per a la variable esViu: |
|
|
|
|
 |
/**
* La classe Esser representa un ésser dels que poblen
el món
* del "Joc de la Vida".
*
* @author (el vostre nom)
* @version (un número de versió o la data)
*/
public class Esser {
/**
* L'estat de viu o mort d'aquest Esser.
*/
private boolean esViu=false;
/**
* Mètode constructor per a objectes
de la classe Esser.
* @param esViu l'estat de viu o mort d'aquest
Esser.
*/
public Esser(boolean esViu) { // constructor
this.esViu=esViu;
}
/**
* Obtenció de l'estat de viu o mort
d'aquest Esser.
*/
public boolean getEsViu () {
return esViu;
}
/**
* Determinació de l'estat de viu
o mort d'aquest Esser.
* @param esViu l'estat de viu o mort d'aquest
Esser que
* es vol determinar.
*/
public void setEsViu (boolean esViu) {
this.esViu=esViu;
}
}
|
|
|
|
|
|
|
Ara ja només falta decidir
com es pinta un ésser viu al MonVisible.
Per començar, un cercle vermell viu vorejat d'una circumferència
vermella, però més fosca ja farà un bon paper. Naturalment,
si l'ésser és mort, no es pinta: |
|
|
|
|
 |
import
java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.Color;
/**
* La classe Esser representa un ésser dels que poblen
el món
* del "Joc de la Vida".
*
* @author (el vostre nom)
* @version (un número de versió o la data)
*/
public class Esser {
/**
* L'estat de viu o mort d'aquest Esser.
*/
private boolean esViu=false;
/**
* Mètode constructor per a objectes
de la classe Esser.
* @param esViu l'estat de viu o mort d'aquest
Esser.
*/
public Esser(boolean esViu) { // constructor
this.esViu=esViu;
}
/**
* Obtenció de l'estat de viu o mort
d'aquest Esser.
*/
public boolean getEsViu () {
return esViu;
}
/**
* Determinació de l'estat de viu
o mort d'aquest Esser.
* @param esViu l'estat de viu o mort d'aquest
Esser que
* es vol determinar.
*/
public void setEsViu (boolean esViu) {
this.esViu=esViu;
}
/**
* Mètode paint per a aquest Esser.
* @param dimensions les dimensions en píxels
d'aquest Esser.
* @param posicio la posició en píxels
d'aquest Esser.
* @param un objecte Graphics2D.
*/
public void paint (Dimension dimensions,
Dimension posicio,
Graphics2D g) {
if (esViu) {
// Només pintar-lo si és viu
//
Color vermell viu
g.setColor(Color.RED.brighter());
//
Omplir un cercle una mica més petit
g.fillOval(posicio.width+1,posicio.height+1,
dimensions.width-2,dimensions.height-2);
//
Color vermell fosc
g.setColor(Color.RED.darker().darker().darker());
//
Envoltar-lo amb una circumferència
g.drawOval(posicio.width+1,posicio.height+1,
dimensions.width-2,dimensions.height-2);
}
}
}
|
|
|
|
|
|
|
No oblidéssis pas importar
les classes necessàries! |
|
|
|
|
|
El món: |
|
|
|
|
|
 |
Ja t'hem dit que, bàsicament,
ha de ser la quadrícula que conté els éssers. Així,
doncs, la nova classe Món (que has d'afegir
al projecte JocDeLaVida) ha de tenir com a variable
d'instància una matriu doble (files i columnes) d'objectes
Esser: |
|
|
|
|
 |
/**
* La classe Mon conté la matriu que determina la situació
dels
* éssers que poblen el mon del "Joc de la Vida"
i les rutines que
* governen el seu comportament.
*
* @author (el vostre nom)
* @version (un número de versió o la data)
*/
public class Mon {
/**
* La matriu d'Esser's que conformen
aquest Mon.
*/
private Esser[][] elMon;
}
|
|
|
|
|
|
|
Però, per construir efectivament
la quadrícula d'aquest Mon, la variable
elMon, has d'haver decidit abans quantes columnes
i quantes files ha de tenir i, ja pensant en el MonVisible,
quanta pantalla n'ocuparà la visualització: has d'haver decidit,
doncs, quines dimensions, en píxels, ha de tenir un ésser.
Resultarà força pràctic definir una nova classe, Constants,
que contingui aquests paràmetres com a variables static: |
|
|
|
|
 |
import java.awt.Dimension;
/**
* La classe Constants conté els paràmetres del
"Joc de la Vida".
*
* @author (el vostre nom)
* @version (un número de versió o la data)
*/
public final class Constants {
/**
* Les dimensions del mon, en nombre
d'éssers.
*/
public static Dimension dimensionsMon=new
Dimension(40,30);
/**
* Les dimensions d'un ésser.
*/
public static Dimension dimensionsEsser=new
Dimension(12,12);
}
|
|
|
|
|
|
|
(Hi podries posar, a més,
els colors de les coses si volguéssis) Observa que si reuneixes tots
els paràmetres de l'aplicació en una classe com aquesta (que
es declara final perquè no serà
instanciada i només conté elements static)
simplement canviant-ne els valors de les constants que s'hi defineixen,
canvies l'aspecte de tota l'aplicació! |
|
|
|
|
|
Com a exemple d'això,
ara és el moment d'escriure el codi definitiu del mètode getDimensionsMonVisible()
de la classe Finestra: recorda que, a la pràctica
2, hi havies escrit un codi provisional que ara canviaràs: |
|
|
|
|
|
/**
* Mètode que fixa les dimensions
del MonVisible.
* ATENCIÓ:
CONTINGUT PROVISIONAL!
* @return les dimensions del
MonVisible
*/
public Dimension getDimensionsMonVisible
() {
return
new Dimension(400,300);
}
|
|
|
|
|
|
|
L'amplada del MonVisible
(en píxels) ha de ser igual a l'amplada (en éssers) del Mon,
multiplicada per l'amplada d'un ésser i, igualment, l'altura del
MonVisible (en píxels) ha de ser igual
a l'altura (en éssers) del Mon, multiplicada
per l'altura d'un ésser. Ja ho pots escriure: al mètode getDimensionsMonVisible()
de la classe Finestra escriu-hi: |
|
|
|
|
 |
/**
* Mètode que fixa les dimensions
del MonVisible.
* @return les dimensions del MonVisible
*/
public Dimension getDimensionsMonVisible
() {
int ampleMonVisible=Constants.dimensionsMon.width*
Constants.dimensionsEsser.width;
int alturaMonVisible=Constants.dimensionsMon.height*
Constants.dimensionsEsser.height;
return new Dimension(ampleMonVisible,alturaMonVisible);
}
|
|
|
|
|
|
|
Compila i crea un objecte Finestra
i veuràs com n'han canviat les dimensions... |
|
|
|
|
|
Ara ja podem construir el Mon: |
|
|
|
|
 |
/**
* La classe Mon conté la matriu que determina la situació
dels
* éssers que poblen el mon del "Joc de la Vida"
i les rutines que
* governen el seu comportament.
*
* @author (el vostre nom)
* @version (un número de versió o la data)
*/
public class Mon {
/**
* La matriu d'Esser's que conformen
aquest Mon.
*/
private Esser[][] elMon;
/**
* Mètode constructor per a
objectes de la classe Mon
*/
public Mon() {
//constructor
int amplada=Constants.dimensionsMon.width;
int altura=Constants.dimensionsMon.height;
elMon=new Esser[amplada][altura];
}
}
|
|
|
|
|
|
|
Ara cal omplir d'essers la matriu
elMon: |
|
|
|
|
 |
/**
* La classe Mon conté la matriu que determina la situació
dels
* éssers que poblen el mon del "Joc de la Vida"
i les rutines que
* governen el seu comportament.
*
* @author (el vostre nom)
* @version (un número de versió o la data)
*/
public class Mon {
/**
* La matriu d'Esser's que conformen
aquest Mon.
*/
private Esser[][] elMon;
/**
* Mètode constructor per a
objectes de la classe Mon
*/
public Mon() { //constructor
int amplada=Constants.dimensionsMon.width;
int altura=Constants.dimensionsMon.height;
elMon=new Esser[amplada][altura];
ompleMon();
}
/**
* Inicialització d'aquest Mon.
La matriu elMon s'omple
* d'Esser's morts.
*/
public void ompleMon () {
for
(int i=0;i<elMon.length;i++) {
for
(int j=0;j<elMon[0].length;j++) {
elMon[i][j]=new
Esser(false);
}
}
}
}
|
|
|
|
|
|
|
Finalment (per ara!) cal pintar
el Mon en el MonVisible.
Es tracta de pintar els Essers a la seva posició: |
|
|
|
|
 |
import java.awt.Graphics2D;
import java.awt.Dimension;
/**
* La classe Mon conté la matriu que determina la situació
dels
* éssers que poblen el mon del "Joc de la Vida"
i les rutines que
* governen el seu comportament.
*
* @author (el vostre nom)
* @version (un número de versió o la data)
*/
public class Mon {
/**
* La matriu d'Esser's que conformen
aquest Mon.
*/
private Esser[][] elMon;
/**
* Mètode constructor per a
objectes de la classe Mon
*/
public Mon() { //constructor
int amplada=Constants.dimensionsMon.width;
int altura=Constants.dimensionsMon.height;
elMon=new Esser[amplada][altura];
ompleMon();
}
/**
* Inicialització d'aquest Mon.
La matriu elMon s'omple
* d'Esser's morts.
*/
public void ompleMon () {
for
(int i=0;i<elMon.length;i++) {
for
(int j=0;j<elMon[0].length;j++) {
elMon[i][j]=new
Esser(false);
}
}
}
/**
* Mètode paint per a aquest
Mon.
* @param un objecte Graphics2D.
*/
public void paint (Graphics2D g) {
for
(int i=0;i<elMon.length;i++) {
int
x=i*Constants.dimensionsEsser.width;
for
(int j=0;j<elMon[0].length;j++) {
int
y=j*Constants.dimensionsEsser.height;
Esser
esser=elMon[i][j];
esser.paint(Constants.dimensionsEsser,
new
Dimension(x,y),
g);
}
}
}
}
|
|
|
|
|
|
|
El Mon, el MonVisible i la
Finestra... |
|
|
|
|
|
|
Ja fa massa estona
que escrius codi, compiles... però que no veus en funcionament res
d'allò que has escrit! Passa que aquest Mon
(inacabat!) no està relacionat amb la Finestra,
no és una peça del muntatge posada al seu lloc. Ara toca posar-la:
ves a la classe Finestra i crea la variable d'instància
public Mon mon : |
|
|
|
|
 |
<codi anterior>
public class Finestra extends JFrame {
/**
* L'objecte Mon en el qual viuen i
moren els éssers.
*/
protected Mon mon;
/**
* L'objecte MonVisible que fa visibles
els éssers
* del món.
*/
protected MonVisible monVisible;
/**
* Mètode getter per a la variable
mon
* @return el Mon d'aquesta finestra
*/
public Mon getMon () {
return mon;
}
/**
* Mètode getter per a la variable
monVisible
* @return el MonVisible d'aquesta
finestra
*/
public MonVisible getMonVisible () {
return monVisible;
}
<segueix>
|
|
|
|
|
|
|
i, al mètode constructor
de la classe Finestra, construeix efectivament
el mon: |
|
|
|
|
 |
<codi
anterior>
/**
* Mètode constructor per a
objectes de la classe Finestra.
*/
public Finestra () { // constructor
setConfiguracio();
setControls();
mon=new Mon();
inicia();
}
<segueix>
|
|
|
|
|
|
|
Finalment, al mètode paint()
de la classe MonVisible falta afegir-hi la instrucció
de pintar-hi el contingut de l'objecte mon, és
a dir, la de pintar els éssers que conté: |
|
|
|
|
 |
<codi
anterior>
/**
* Mètode paint per a aquest
MonVisible.
* @param un objecte java.awt.Graphics
*/
public void paint (Graphics g) {
Graphics2D g2d=(Graphics2D)g;
// La classe Graphics2D di-
//
buixa molt millor que la
//
classe Graphics
// Els RenderingHint(s)
per millorar els gràfics
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setColor(Color.BLUE);
// Pinta blau...
int ample=getSize().width;
// Les dimensions del MonVisible
int alt=getSize().height;
g2d.fill3DRect(0,0,ample,alt,false);
// Pinta un rectangle
//
esfonsat de color
//
blau, que ocupa
//
tot el MonVisible
finestra.getMon().paint(g2d);
}
<segueix>
|
|
|
|
|
|
|
Arriba el moment de veure la
feina feta! Per poder veure els éssers, fes que, provisionalment,
el mètode ompleMon() de la classe Mon
ompli la matriu elMon d'éssers vius:
|
|
|
|
|
|
/**
* Inicialització d'aquest Mon.
La matriu elMon s'omple
* d'Esser's morts.
*/
public void ompleMon () {
for
(int i=0;i<elMon.length;i++) {
for
(int j=0;j<elMon[0].length;j++) {
//
elMon[i][j]=new Esser(false);
//
PROVISIONAL! Només per a veurel's
elMon[i][j]=new
Esser(true);
}
}
}
<segueix>
|
|
|
|
|
|
|
Compila i crea un objecte Finestra: |
|
|
|
|
|
|
|
|
|
|
|
Bé! bé! no? |
|
|
|
|
|
Ara pots provar de canviar els
valors de les constants en el fitxer Constants.java i veure com es comporta
la finestra... |
|
|
|
|
|
Canviar l'estat d'un ésser: |
|
|
|
|
|
|
Només queda, per ara,
un mètode a afegir a la classe Mon: un
mètode que serveixi per canviar l'estat viu/mort de l'Esser
que és a la cel·la de coordenades i,j:
|
|
|
|
|
|
/**
* Canvia l'estat de l'Esser situat
a una certa posició
* d'aquest Mon.
* @param i la posició "x"
de l'Esser.
* @param j la posició "y"
de l'Esser.
*/
public void canviaEstatViuOMort (int i,int
j) {
Esser esser=elMon[i][j];
// Quin Esser hi ha en aquesta
//
posició?
boolean estat=esser.getEsViu();
// En quin estat està ara?
esser.setEsViu(!estat);
// Canvi a l'estat contrari
}
|
|
  |