каждый.
Следующее поколение в моем приложении Game of Life (ссылка - пример приложения) рассчитывается правильно. Игра работает, как и ожидалось, но вы должны нажимать «Далее» каждый раз, когда вы хотите новое поколение. У меня проблема с реализацией кнопки «Пуск» для зацикливания поколений. (См. Ссылку для определения различий между «next» и «start».)
Очевидно, мне нужен какой-то цикл внутри класса ActionListener. Я попытался вызвать nextGen () внутри actionListener рекурсивно, в то время как частное логическое значение true. Программа вылетает. Я также попытался установить какое-то ожидание, но это не имеет значения.
Это действительно делает 10 итераций, если я помещаю 10 строк nextGen (); внутри слушателя, так что я думаю, мне нужно подождать здесь. (Проблема с памятью.)
Надеюсь, вы поможете мне в этом. :)
Следующее поколение рассчитывается таким образом.
Класс ActionListener:
public class GameOfLifeListener implements ActionListener
{
// IMPORTANT: GameOfLifeGrid contains the GameOfLife collection!
private GameOfLifeGrid gameOfLife;
public GameOfLifeListener ( GameOfLifeGrid g )
{
this.gameOfLife = g;
}
@Override
public void actionPerformed (ActionEvent e)
{
// Get actionCommand
String ac = e.getActionCommand();
if ( ac.equals("next") )
{
// Method calculates next generation
nextGen();
}
if ( ac.equals("start") )
{
// ADDED CODE: See class GameOfLifeGrid in bottom.
gameOfLife.start();
}
}
private void nextGen ( )
{
// Get Next generation
gameOfLife.getCollection().nextGen();
// Repaint
gameOfLife.repaint();
}
}
actionListener запускает nextGen () для объекта GameOfLife при нажатии кнопки «Далее». Принцип работы метода nextGen () не важен, но здесь он вместе с некоторыми частями класса GameOfLife
public class GameOfLife extends CellCollection
{
// Temporary array for new generation . We must add next generations alive cells HERE.
// Else the calculations of the current generation will fail.
private Cell[][] nextGen = null;
public void nextGen ( )
{
// Create the new Array holding next generation
prepareNextCollection();
// Iterate the whole grid
for ( int row = 0; row < super.rows; row++ )
{
for ( int col = 0; col < super.cols; col++ )
{
ruleOne(row, col);
}
}
// Set the new collection to superClass.
// Super class holds the collection that will be drawn
super.setCollection(nextGen);
}
private void ruleOne ( int row, int col )
{
// Calculations not important. It works like expected.
}
private void prepareNextCollection ( )
{
this.nextGen = new Cell[rows][cols];
}
Это отдельные части класса GameOfLifeGrid. Рисует сетку и живые клетки (Cell array).
public class GameOfLifeGrid extends Grid
{
private GameOfLife collection = null;
// ADDED MEMBERS: Timer, int
private Timer timer;
private int updateEachMilliSec = 100; // Used in program. Not in this code
@Override
public void paintComponent ( Graphics g )
{
super.paintComponent(g);
drawCells(g);
}
private void drawCells ( Graphics g )
{
for ( int row = 0; row < rows; row++ )
{
for ( int col = 0; col < cols; col++ )
{
if ( ! collection.isEmptyPos(row, col) )
{
g.fillRect(super.calcX(col), super.calcY(row), cellSize, cellSize);
}
}
}
}
// ADDED METHOD!
public void start()
{
// Create a timer object. The timer will send events each 100 ms.
// The events will be caught by the ActionListener returned from
// nextGenlistener(). VOILA!
timer = new Timer(100, nextGenlistener());
// Start sending events to be caught!
timer.start();
}
// ADDED METHOD! The ActionListener who will catch the events sent by timer.
private ActionListener nextGenlistener ()
{
return new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
// Get next generation
collection.nextGen();
// Repaint
repaint();
}
};
}