Я написал программу, основанную на некоторых примерах, для имитации игры жизни Конвей. Каждая ячейка в игре либо живая, либо мертвая, и они хранятся в массиве целых чисел int[][]
, этот массив всегда не менее 1000 * 1000, а это значит, что есть миллионы ячеек.Java-paintComponent самый эффективный способ рисования миллионов квадратов из массива
Итерации через массив, чтобы найти применение всех различных правил, являются точными и не особенно интенсивны в ЦП. Тем не менее, метод, используемый для рисования этих прямоугольников на JFrame, может привести к 90% использования процессора на моем Xeon E3 1246 V3 (I7 4770). При размерах массива 2000^2 это может привести к жесткой блокировке Windows 10 полностью.
@Override
protected void paintComponent(Graphics g) {
liveCells = 0;
super.paintComponent(g);
Color gColor = g.getColor();
if(!backgroundWork || isPaused) {
for (int row = 0; row < grid.length; row++) {
for (int column = 0; column < grid[row].length; column++) {
//Checking if the cell is alive.
if (grid[row][column] == 1) {
liveCells++;
g.setColor(Color.red);
g.fillRect(column * UIScale, row * UIScale, UIScale, UIScale);
}
}
}
}
g.setColor(gColor);
if (isPaused) {
g.drawString("The game is paused", 0, 30);
g.drawString("Generation: " + generationCounter, 0, 10);
g.drawString("Living cells: " + liveCells, 150, 10);
} else { //If the game is running
g.drawString("Generation: " + generationCounter++, 0, 10);
g.drawString("Living cells: " + liveCells, 100, 10);
}
g.setColor(gColor);
try {
/* Sleep for some microseconds. */
TimeUnit.MICROSECONDS.sleep(sleepTimer);
} catch (InterruptedException ex) {
System.err.println("An InterruptedException was caught: " + ex.getMessage());
}
}
я вижу совершенно ясно, что рисунок клеток является проблемой, с тем чтобы позволить программе работать быстрее, я уже добавил способ изменить переменную backgroundWork, которая отключает обновляет сетку прямоугольники. Включение или выключение этого параметра приводит к различиям до 80% при загрузке процессора диспетчера задач.
С помощью текущего метода рисования сетки я не вижу способа сделать это намного быстрее, поскольку все ячейки независимы друг от друга, и обычно их не будет больше 3, в любом случае, так что нет причин для реализации способа рисования нескольких одновременно.
Может кто-нибудь предложить способ ускорить текущий процесс или другой способ рисования квадратов. Спасибо за любую помощь.
Рассматривали ли вы непосредственно листать биты в Растр BufferedImage, в этом от от EDT, а затем рисовать изображение в вашем методе paintComponent? –
Итак, что-то похожее на это http://stackoverflow.com/questions/14416107/int-array-to-bufferedimage –
Мне нужно было бы адаптировать его для размещения ячеек разных размеров. В настоящее время g.fillRectangle рисует квадрат со сторонами UIScale. В зависимости от того, что для него установлено, может быть представлено от 1 до 1 между значениями в массиве и пикселями на экране или 4 * 4 пикселя для одного элемента массива. –