Этот ответ является очень очень упрощенным объяснением!Я рекомендую проверить этот журнал linux , который исследует что-то похожее.
Основная проблема, которая вызывает «мерцание», заключается в том, что розыгрыш выполняется «быстро».
Возьмите свой основной цикл:
for(;;) {
ball.move();
window.setContentPane(ball);
window.setContentPane(player);
player.move();
}
Этот цикл обновляет позиции шара, а затем "добавляет его на панель содержимого".Пока он рисуется, следующее изображение уже добавлено и нарисовано.Это вызывает мерцание (опять же, обратите внимание: это очень упрощено).
Самое простое решение, чтобы устранить «мерцание» - это позволить потоку спать после того, как он нарисован, и «ждать», пока ничья не станетготово.
boolean running = true;
int delay = 15; // adjust the delay
while(running) {
ball.move();
player.move();
window.setContentPane(ball);
window.setContentPane(player);
try {
Thread.sleep(delay);
} catch(InterruptedException e) {
// We were interrupted while waiting
// Something "woke us up". Stop the loop.
e.printStackTrace();
running = false;
}
}
Этот метод Thread.sleep позволяет текущему Thread"подождать" указанное время.
Задержка может быть скорректирована до чего-то более практичного.Вы можете, например, рассчитать, сколько кадров вы хотите и спать на эту сумму.
Другим способом было бы «время» обновления.Это можно сделать с помощью таймера.Так как это более или менее устарело, я реализую его с помощью ScheduledExecutorService
int delay = 15; // adjust the delay
ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool();
scheduledExecutorService.scheduleAtFixedRate(new Runnable() {
public void run() {
ball.move();
player.move();
}
}, delay, TimeUnit.MILLISECONDS)
Начиная с Java8, вы можете написать это, используя лямбду, например:
scheduledExecutorService.scheduleAtFixedRate(() -> {
ball.move();
player.move();
}, delay, TimeUnit.MILLISECONDS)
Чтобы остановить это,Теперь вы можете позвонить:
scheduledExecutorService.shutdown();
Однако: существуют более сложные решения.Одним из них, как вы уже отметили, является двойная буферизация .Но есть также несколько различных техник , которые компенсируют более сложные проблемы.Они используют то, что называется перелистыванием страниц.