---- Отредактировано для настройки адреса на пиксель ----
Элемент уничтожает двойную буферизацию, но есть также проблема с тем, как получить пиксели в BufferedImage
.
Если вы позвоните
WriteableRaster raster = bi.getRaster()
на BufferedImage
, он вернет WriteableRaster
.Оттуда вы можете использовать
int[] pixels = new int[WIDTH*HEIGHT];
// code to set array elements here
raster.setPixel(0, 0, pixels);
Обратите внимание, что вы, вероятно, захотите оптимизировать код, чтобы фактически не создавать новый массив для каждого рендеринга.Кроме того, вы, вероятно, захотите оптимизировать код очистки массива, чтобы не использовать цикл for.
Arrays.fill(pixels, 0xFFFFFFFF);
, вероятно, превзошел бы ваш цикл, установив фон в белый цвет.
----Отредактировано после ответа ----
Ключ находится в вашей первоначальной настройке JFrame и в цикле рендеринга запуска.
Сначала вы должны указать SWING прекратить растеризацию в любое время;потому что вы будете говорить об этом, когда закончите рисовать буферизованное изображение, которое хотите полностью заменить.Сделайте это с помощью
setIgnoreRepaint(true);
в JFrame. Затем вы захотите создать буферную стратегию.По сути, он определяет, сколько буферов вы хотите использовать
createBufferStrategy(2);
Теперь, когда вы попытались создать стратегию буфера, вам нужно захватить объект BufferStrategy
, так как он понадобится вам позже для переключения буферов.
final BufferStrategy bufferStrategy = getBufferStrategy();
Внутри Thread
измените цикл run()
, чтобы он содержал:
...
move();
drawSqure(bi1);
Graphics g = bufferStrategy.getDrawGraphics();
g.drawImage(bi1, 0, 0, null);
g.dispose();
bufferStrategy.show();
...
Графика, извлеченная из bufferStrategy, будет внеэкранным объектом Graphics
при создании тройкибуферизация, это будет «следующий» внеэкранный Graphics
объект в циклическом порядке.
Изображение и контекст Graphics не связаны в сценарии сдерживания, и вы сказали Swing, чтосделать рисунок самостоятельно, поэтому вы должны нарисовать изображение вручную.Это не всегда плохо, так как вы можете указать переворачивание буфера, когда изображение полностью прорисовано (и не раньше).
Утилизация графического объекта - это просто хорошая идея, поскольку она помогает в сборке мусора.Отображение bufferStrategy
перевернет буферы.
Хотя где-то в вышеприведенном коде и может быть ошибка, это должно помочь вам на 90%.Удачи!
---- Оригинальный пост следует за ----
Может показаться глупым отсылать такой вопрос к учебнику по javase, но вы изучили * 1052?* и BufferCapatbilites
?
Основная проблема, с которой, я думаю, вы столкнулись, заключается в том, что вас одурачивает название Изображения.BufferedImage
не имеет ничего общего с двойной буферизацией, он имеет отношение к «буферизации данных (обычно с диска) в памяти».Таким образом, вам понадобятся два BufferedImages, если вы хотите иметь «изображение с двойной буферизацией»;так как неразумно изменять пиксели в отображаемом изображении (это может вызвать проблемы с перекрашиванием).
В коде рендеринга вы получаете графический объект.Если вы настроили двойную буферизацию в соответствии с приведенным выше руководством, это означает, что вы по умолчанию захватите объект вне экрана Graphics
, и весь рисунок будет находиться вне экрана.Затем вы рисуете свое изображение (конечно, правильное) на объекте вне экрана.Наконец, вы указываете стратегию для show()
буфера, и она заменит вам графический контекст.