иллюстрирует несколько подходов к пиксельной анимации.
ТИРОВАТЬ ВТОРОЙ
Чтобы не допустить вкрадчивых комментариев и однострочных ответов, упускающих смысл:IFF это так же просто, как звонитьsetDoubleBuffered (правда), тогда как мне получить доступ к текущему автономному буферу, чтобы я мог начать возиться с базовым пиксельным буфером данных BufferedImage?
Я потратил время, чтобы написать работающий кусок кода (который тоже выглядит довольно забавно), поэтому я был бы очень признателен за ответы, которые на самом деле отвечают (какой шок;) на мой вопрос и объясняют, что / как это работает вместо однострочников и ворчливости Комментарии ;)
Вот рабочий фрагмент кода, который пересекает квадрат через JFrame. Я хотел бы знать о различных способах, которые можно использовать для преобразования этого фрагмента кода, чтобы он использовал двойную буферизацию.
Обратите внимание, что способ очистки экрана и перерисовки квадрата не самый эффективный, но на самом деле это не тот вопрос, о котором идет речь (в некотором смысле, лучше в этом примере он несколько медленный).
По сути, мне нужно постоянно изменять много пикселей в BufferedImage (чтобы иметь некоторую анимацию), и я не хочу видеть визуальные артефакты из-за одиночной буферизации на экране.
У меня есть JLabel, Icon которого является ImageIcon, оборачивающим BufferedImage. Я хочу изменить это BufferedImage.
Что нужно сделать, чтобы это стало двойной буферизацией?
Я понимаю что как-то"изображение 1" будет показано, пока я буду рисовать"изображение 2", Но потом, когда я закончил, опираясь на"изображение 2"как мне "быстро" заменить"изображение 1" от"изображение 2"?
Это то, что я должен делать вручную, например, заменяя ImageIcon JLabel самостоятельно?
Должен ли я всегда рисовать в одном и том же BufferedImage, а затем сделать быстрое «блицание» пикселей этого BufferedImage в BufferedImage JIabel's ImageIcon? (Наверное, нет, и я не вижу, как я мог бы «синхронизировать» это с «вертикальной пустой линией» монитора [или эквивалентом на плоском экране: я имею в виду, чтобы «синхронизировать», не вмешиваясь в момент обновления самого монитора). пикселей, чтобы предотвратить сдвиг]).
А как насчет "перекрасить" заказы? Я полагаю, чтобы вызвать их сам? Который / когда именно я должен позвонитьперекрасить () или что-то другое?
Наиболее важным требованием является то, что я должен изменять пиксели непосредственно в буфере данных пикселей изображения.
import javax.swing.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferInt;
public class DemosDoubleBuffering extends JFrame {
private static final int WIDTH = 600;
private static final int HEIGHT = 400;
int xs = 3;
int ys = xs;
int x = 0;
int y = 0;
final int r = 80;
final BufferedImage bi1;
public static void main( final String[] args ) {
final DemosDoubleBuffering frame = new DemosDoubleBuffering();
frame.addWindowListener(new WindowAdapter() {
public void windowClosing( WindowEvent e) {
System.exit(0);
}
});
frame.setSize( WIDTH, HEIGHT );
frame.pack();
frame.setVisible( true );
}
public DemosDoubleBuffering() {
super( "Trying to do double buffering" );
final JLabel jl = new JLabel();
bi1 = new BufferedImage( WIDTH, HEIGHT, BufferedImage.TYPE_INT_ARGB );
final Thread t = new Thread( new Runnable() {
public void run() {
while ( true ) {
move();
drawSquare( bi1 );
jl.repaint();
try {Thread.sleep(10);} catch (InterruptedException e) {}
}
}
});
t.start();
jl.setIcon( new ImageIcon( bi1 ) );
getContentPane().add( jl );
}
private void drawSquare( final BufferedImage bi ) {
final int[] buf = ((DataBufferInt) bi.getRaster().getDataBuffer()).getData();
for (int i = 0; i < buf.length; i++) {
buf[i] = 0xFFFFFFFF; // clearing all white
}
for (int xx = 0; xx < r; xx++) {
for (int yy = 0; yy < r; yy++) {
buf[WIDTH*(yy+y)+xx+x] = 0xFF000000;
}
}
}
private void move() {
if ( !(x + xs >= 0 && x + xs + r < bi1.getWidth()) ) {
xs = -xs;
}
if ( !(y + ys >= 0 && y + ys + r < bi1.getHeight()) ) {
ys = -ys;
}
x += xs;
y += ys;
}
}
РЕДАКТИРОВАТЬ
Этоне для полноэкранного Java-приложения, но обычного Java-приложения, работающего в собственном (несколько маленьком) окне.