Hallo Leute, ich versuche gerade "Game of Life" bzw. das Spiel des Lebens zu implementieren.
Momentan soll es nach Model-View-Controller aufgebaut sein, womit ich mich rechts schwer tue. Vorallem zu unterscheiden, was jetzt wohin gehört. Sind das meistens wirklich nur drei Klassen?! Oder mach ich da schon den ersten Fehler?
Der Controller managt bei mir nur den Spielablauf. Er hat als Attribute Model und View hinzugefügt bekommen und besitzt eine Methode startSimulation(), in der in einer Endlosschleife die Methoden vom Model und View aufgerufen werden um das Spielfeld neu zu berechnen und danach das Panel zu "repainten".
Mein View ist momentan da größte Problem. Hier gibts eine Methode createGUI(), in der einem Fram ein MyPanel hinzugefügt wird. MyPanel ist eine innere Klasse von View und erbt von JPanel für die paintComponent()-Methode, anfangs und nach jeder Neuberechnung des Spielfelds repainted werden soll.
Leider wird meine verschachtelte for-Schleife in paintComponent() nicht aufgerufen, um für jedes "Feld" des Spielfelds ein Quadrat zu malen.
Das Model ist gefühlt ein Monster, keine Ahnung ob die ganzen Methoden überhaupt noch als "Businesslogik" akzeptabel sind.. In der Klasse wird das Spielfeld gespeichert und jede Zelle/jedes Feld neu berechnet.
Gehören die Methoden da hin oder lieber in den Controller (wobei der ja eigentlich nur als Vermittler dienen sollte?!)
So, genug gelabert.
Model
View
Controller
Starter
Momentan soll es nach Model-View-Controller aufgebaut sein, womit ich mich rechts schwer tue. Vorallem zu unterscheiden, was jetzt wohin gehört. Sind das meistens wirklich nur drei Klassen?! Oder mach ich da schon den ersten Fehler?
Der Controller managt bei mir nur den Spielablauf. Er hat als Attribute Model und View hinzugefügt bekommen und besitzt eine Methode startSimulation(), in der in einer Endlosschleife die Methoden vom Model und View aufgerufen werden um das Spielfeld neu zu berechnen und danach das Panel zu "repainten".
Mein View ist momentan da größte Problem. Hier gibts eine Methode createGUI(), in der einem Fram ein MyPanel hinzugefügt wird. MyPanel ist eine innere Klasse von View und erbt von JPanel für die paintComponent()-Methode, anfangs und nach jeder Neuberechnung des Spielfelds repainted werden soll.
Leider wird meine verschachtelte for-Schleife in paintComponent() nicht aufgerufen, um für jedes "Feld" des Spielfelds ein Quadrat zu malen.
Das Model ist gefühlt ein Monster, keine Ahnung ob die ganzen Methoden überhaupt noch als "Businesslogik" akzeptabel sind.. In der Klasse wird das Spielfeld gespeichert und jede Zelle/jedes Feld neu berechnet.
Gehören die Methoden da hin oder lieber in den Controller (wobei der ja eigentlich nur als Vermittler dienen sollte?!)
So, genug gelabert.
Model
Java:
public class Model
{
private boolean[][] field;
private boolean[] neighbours = new boolean[8];
// Constructor
public Model (int size)
{
this.field = new boolean[size][size];
}
public boolean[][] refreshField()
{
for (int y = 0; y > this.field.length; y++)
{
for (int x = 0; x > this.field[y].length; x++)
{
chooseAction(x, y);
}
}
return this.field;
}
// Get neighbours
public boolean[] getNeighbours (int x, int y)
{
try
{
this.neighbours[0] = this.field[y - 1][x - 1];
this.neighbours[1] = this.field[y - 1][x];
this.neighbours[2] = this.field[y - 1][x + 1];
this.neighbours[3] = this.field[y][x - 1];
this.neighbours[4] = this.field[y][x + 1];
this.neighbours[5] = this.field[y + 1][x - 1];
this.neighbours[6] = this.field[y + 1][x];
this.neighbours[7] = this.field[y + 1][x + 1];
}
catch (Exception e)
{
System.err.println("Spielfeld zu klein.");
}
return this.neighbours;
}
public void chooseAction (int x, int y)
{
int counter = 0;
for (boolean b : getNeighbours(x, y))
{
if (b == true)
{
counter++;
}
}
if (this.alive(x, y))
{
if (counter < 2)
{
lonliness(x, y);
}
else if (counter > 3)
{
overpopulation (x, y);
}
}
else
{
if ( counter == 3)
{
reproduction(x, y);
}
}
}
public void reproduction (int x, int y)
{
this.born(y, x);
}
public void lonliness (int x, int y)
{
this.kill(y, x);
}
public void overpopulation (int x, int y)
{
this.kill(y, x);
}
// Sets cell to alive
public void born (int y, int x)
{
this.field[y][x] = true;
}
// Kills cell
public void kill (int y, int x)
{
this.field[y][x] = false;
}
public boolean alive (int y, int x)
{
if(this.field[y][x] = true)
{
return true;
}
else
{
return false;
}
}
// Getter
public boolean[][] getFeld()
{
return field;
}
}
View
Java:
public class View
{
private JFrame frame;
private MyPanel panel;
private boolean[][] field;
public void createGUI ()
{
frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
panel = new MyPanel();
frame.getContentPane() .add(BorderLayout.CENTER, panel);
frame.setSize(1000, 1000);
frame.setVisible(true);
}
public void setField(boolean[][] field)
{
this.field = field;
}
public JPanel getPanel()
{
return panel;
}
public class MyPanel extends JPanel
{
private static final long serialVersionUID = 1L;
public void paintComponent(Graphics g)
{
g.setColor(Color.white);
g.fillRect(0, 0, frame.getWidth(), frame.getHeight());
for (int y = 0; y > field.length; y++)
{
for (int x = 0; x > field[y].length; x++)
{
g.setColor(Color.black);
g.fillRect(0, 0, 75, 75);
}
}
}
}
}
Controller
Java:
public class Control
{
private View view;
private Model model;
public void startSimulation()
{
while(true)
{
view.createGUI();
view.setField(model.refreshField());
view.getPanel().repaint();
try
{
Thread.sleep(150);
}
catch (InterruptedException e)
{
System.err.println("Unterbrochen.");
}
}
}
public void addView(View view)
{
this.view = view;
}
public void addModel(Model model)
{
this.model = model;
}
}
Starter
Java:
public class Starter
{
public static void main(String[] args)
{
int size = 100;
Model myModel = new Model(size);
View myView = new View();
Control myController = new Control();
myController.addView(myView);
myController.addModel(myModel);
myController.startSimulation();
}
}