Игра приложение жизни, с кликами мыши


У меня есть игра в жизнь программу, которая имеет grid[][] массив, который заполняется Cell объекты. Если есть ячейки в сетке квадрата, что сетка квадратная зеленая. Можно добавить ячейки вручную, нажав на квадраты и превратить их в зеленый цвет.

Когда Start Iterations кнопка нажата startIterations() способ начинается, что делает использование AnimationTimer. Все это выполняется в одном потоке, пока нет живых клеток влево или до 10 секунд.

Однако, я все еще влияют на этот процесс путем нажатия на свободных площадях и превращая их в зеленый цвет. Также у меня есть Stop Iterations кнопка, вызывающая AnimationTimerstop() способ при надавливании; я могу получить доступ к этой кнопки в то время как моделирование проводится в он работает нормально. Как это возможно, если есть только один поток?

Даже если он работает нормально, у меня такое ощущение, что это неправильно, чтобы все было в одном потоке. Что является лучшим подходом? Поставить анимацию в отдельном второй поток?

enter image description here

Основной класс:

public class Main extends Application {
private static int gameWidth = 800;
private static int gameHeight = 600;

private static int gridSize = 20;
private static Cell[][] grid = new Cell[gridSize][gridSize];

private static Scene scene;
private static Displayer gameDisplayer;

static SimpleIntegerProperty simulationCount = new SimpleIntegerProperty(0);
static int aliveCellsCount = 0;

private static boolean iterationsStatus = false;
@Override
public void start(Stage primaryStage) throws Exception {
    primaryStage.setTitle("Advanced Game of Life");

    createGrid();

    gameDisplayer = new Displayer(gameWidth, gameHeight, grid);

    scene = gameDisplayer.getGameScene();
    primaryStage.setScene(scene);
    primaryStage.show();

}

public static void main(String[] args) {
    launch(args);
}

startIterations() метод:

public static void startIterations() {
    System.out.println("Starting iterations");
    simulationCount.set(0);

    final long startNanoTime = System.nanoTime();

    new AnimationTimer() {
        private long lastUpdateTime = 0;

        public void handle(long currentNanoTime) {
            int currentTime = (int) Math.round((currentNanoTime - startNanoTime) / (double) 1000_000_000L);

            if (currentNanoTime - lastUpdateTime >= 100_000_000) {
                aliveCellsCount=updateGrid();

                simulationCount.set(simulationCount.get() + 1);
                lastUpdateTime = currentNanoTime;
            }

            if (aliveCellsCount == 0 || currentTime > 10 || !iterationsStatus) {
                stop();
                System.out.println("Stopped iterations");
            }
        }
    }.start();

    System.out.println("Finished iterations");
}

updateGrid() метод:

public static int updateGrid() {
        System.out.println("Updating grid");

        int livingCount;

        for (int i = 0; i < gridSize; i++) {
            for (int j = 0; j < gridSize; j++) {
                livingCount = 0;

                livingCount += checkGrid(i - 1, j);
                livingCount += checkGrid(i, j - 1);
                livingCount += checkGrid(i + 1, j);
                livingCount += checkGrid(i, j + 1);
                livingCount += checkGrid(i - 1, j - 1);
                livingCount += checkGrid(i + 1, j + 1);
                livingCount += checkGrid(i - 1, j + 1);
                livingCount += checkGrid(i + 1, j - 1);

                if (livingCount == 3) {
                    grid[i][j].setNextStatus(true);
                } else if (livingCount == 2 && grid[i][j].getStatus()) {
                    grid[i][j].setNextStatus(true);
                } else {
                    grid[i][j].setNextStatus(false);
                }

                System.out.print("livingCount for (" + i + ", " + j + "): " + livingCount);
                System.out.println(" => " + grid[i][j].getNextStatus());
            }
        }

        int resultLivingCount = 0;

        for (int i = 0; i < gridSize; i++) {
            for (int j = 0; j < gridSize; j++) {
                grid[i][j].setStatus(grid[i][j].getNextStatus());

                resultLivingCount += grid[i][j].getStatus() ? 1 : 0;
                // System.out.println("grid[" + i + "]["+j + "] is " + grid[i][j].getStatus());
            }
        }

        return resultLivingCount;
    }

handle() способ внутрь Displayer класс, который обрабатывает кнопки нажимает:

public void handle(ActionEvent event)  {
        if (event.getSource()==createCellButton)  {
           Main.createCell();
        }
        else if (event.getSource() == deleteCellsButton) {
            Main.deleteCells();
            cellsCountLabel.setText("Cells Count: " + (cellId + 1));
            System.out.println("Cells deleted");
        }
        else if (event.getSource()==randomGridButton)  {
            System.out.println("Calling random grid");

            Main.generateRandomGrid();
        }
        else if (event.getSource() == updateGridButton)  {
            Main.updateGrid();
        }
        else if (event.getSource() == startIterationsButton)  {
            Main.setIterationsStatus(true);
            Main.startIterations();
        }
        else if(event.getSource()==stopIterationsButton)  {
            Main.setIterationsStatus(false);
        }
        else  {
            System.out.println("Unknown button");
        }
    }


Комментарии