Есть ли способ показать массив в виде изменяющейся сетки / гистограммы в JFrame в рамках симуляции Game of Life? - PullRequest
0 голосов
/ 06 февраля 2019

Я сейчас пытаюсь настроить Мини-версию Игры Жизни, но я изо всех сил пытаюсь визуализировать ее в кадре, используя массив для создания сетки.

Это мой первыйВремя использования интерфейсов, поэтому я решил протянуть сетку и массив через измененную гистограмму.Тем не менее, я продолжаю получать сообщение об ошибке с JComponent, когда я пытаюсь поместить график / сетку в фрейм с вызываемым методом paintComponent.Я не создавал Graphic g ранее, хотя я импортировал JFrame, JComponent и Graphic в основное тело.

Основное тело

 JFrame frame = new JFrame();
 frame.setSize(400,200);
 frame.setTitle("Mini Game of Life");
 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 for (int t = 0; t < 30; t++)
 {
      grid = LifeSweeper(grid, x, y);   //Line 104
      grid = next;  
      // Line below main Error
      JComponent component = paintComponent(Graphics g; x; y; int grid[][]);
      frame.add(component);

      frame.setVisible(true);
 }

Метод paintComponent

public void paintComponent(Graphics g, int x, int y, int grid[][])
{
  for (int i = 0; i < x; i++) 
    {
        for (int j = 0; j < y; j++) 
        {

            if (grid[i][j] == 1) 
            {
                g.fillRect(x, y, 10, 10);
            }
        }
    }  
}

План состоял в том, чтобы игра в жизни запускалась в цикле for, который обновлял бы графику фрейма, при этом grid - текущая версия игрового массива, x и y - размер сетки, а следующий - возвращаемый массив из метода LifeSweeper.,Затем paintComponent сгенерирует графику и поместит ее в рамку, обновляя в цикле for.Тем не менее, JComponent продолжает возвращать ошибку, заявляя, что строка не является оператором и как есть пропущенные точки с запятой.Я полагаю, что есть более простой способ обойти это, но я не могу найти его в javadoc или других страницах.

РЕДАКТИРОВАТЬ: Я попытался запустить программу, как есть, вот текущая ошибка / исключениесообщение:

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: -1
at lifegame.LifeGame.LifeSweeper(LifeGame.java:129)
at lifegame.LifeGame.main(LifeGame.java:104)

РЕДАКТИРОВАТЬ 2: Метод LifeSweeper добавлен в соответствии с запросом.Заметки еще не были добавлены, но он запускает две серии вложенных циклов: первый проверяет и подсчитывает соседние ячейки, второй изменяет ячейки в соответствии с правилами жизни.

public static int[][] LifeSweeper(int[][] next, int a, int b)
{
    int cellFate[][] = new int[a][b];
    int cellsStatus[][] = new int [a][b];
    for (int x = 1; x < next.length-1; x++)
    {
        for (int y = 1; y < next[0].length-1; y++)
        {
            int cellCounter = 0;
            int cellStatus = 0;
            for (int i = -1; i <= 1; i++)   
            {
                for (int j = -1; j <= 1; i++)
                {
                    if (next[i][j] == 1) // Line 129
                    {
                        cellCounter++;
                    }
                    else if (next[0][0] == 1)
                    {
                        cellStatus = 1;
                    }
                }
            }
            cellFate[x][y] = cellCounter - 1;
            cellsStatus[x][y] = cellStatus;
        }
    }
    for (int x = 1; x < next.length-1; x++)
    {
      for (int y = 1; y < next[0].length-1; y++)
      {
          if (cellsStatus[x][y] == 0)
          {
              if (cellFate[x][y] == 0)
              {
                  next[x][y] = 0;
              }
              if (cellFate[x][y] == 3)
              {
                  next[x][y] = 1;
              }
          }
          if (cellsStatus[x][y] == 1)
          {
              if (cellFate[x][y] < 2)
              {
                  next[x][y] = 0;
              }
              if (cellFate[x][y] == 2 || cellFate[x][y] == 3)
              {
                  next[x][y] = 1;
              }
              if (cellFate[x][y] > 3)
              {
                  next[x][y] = 0;
              }
          }
      }
    } 
    return next;
}

1 Ответ

0 голосов
/ 07 февраля 2019

Исключением является сообщение "эй, вы пытались получить доступ к элементу за пределами вашего массива, который больше 0 и меньше размера вашего массива".Непосредственная проблема заключается здесь:

for (int i = -1; i <= 1; i++)   // i starts at -1 
        {
            for (int j = -1; j <= 1; i++) // jstarts at -1  Note that you are incrementing i, which is unrelated to the exception, but still probably not what you want.
            {
                if (next[i][j] == 1) // Line 129  - next[-1][-1] accessed, which is prior to the beginning of the array.  Exception thrown.

В игре жизни вам необходимо учитывать случаи, когда ячейки находятся на краю сетки.Перед строкой 129 убедитесь, что вы не пытаетесь указать точки за пределами сетки.

Еще одна точка в строке 129, вы упоминаете, что намереваетесь проверить соседей ячеек в этом месте, но из моего чтенияКажется, вы проверяете только соседей ячейки 0,0.Вы намеревались проверить x+i и y+j?Это позволит выполнить проверку окружения ячеек x и y.

paintComponent, но все в порядке, но в следующем фрагменте кода также есть несколько проблем, которые вы можете рассмотреть:

grid = LifeSweeper(grid, x, y); // LifeSweeper looks like a constructor for a class.  Being a function, you should call it lifeSweeper.  Before you posted line 129, I was very confused about why you were trying to construct a LifeSweeper named grid using itself.
grid = next;  //I remain confused about what next is in this context, as your grid already updated, presumably.
JComponent component = paintComponent(Graphics g; x; y; int grid[][]); //This won't compile, and even if it did, it looks like you're calling with a null g and an empty grid.  Probably not what you want.

Вы идете по правильному пути, но вы столкнулись с классическим крайним случаем, с которым столкнулись все, кто когда-либо делал симулятор Game of Life, в том числе и я, когда я учился кодировать.

Что касаетсяваш paintComponent, есть несколько проблем с написанным кодом, немаловажным из которых является то, что вам на самом деле не следует вызывать paintComponent напрямую;система управления окнами будет делать это всякий раз, когда это необходимо (о чем вы можете сигнализировать, вызывая такие методы, как revalidate() и repaint()).Я бы взглянул на Как работает paintComponent , который поможет вам выбрать правильный путь.

...