Проблема с мерцанием BufferedImage - PullRequest
0 голосов
/ 22 января 2011

Здравствуйте, я пишу небольшую игру, и она почти закончена, единственное, что не работает, это ImageBuffer. Каждые 10 миллисекунд я вызываю метод repaint (). Мой метод paint () выглядит следующим образом:

private Graphics2D g2D;

public void paint (Graphics g) {
    BufferedImage bimage = ((Graphics2D)g).getDeviceConfiguration().createCompatibleImage(700, 600, Transparency.OPAQUE);
    g2D = bimage.createGraphics();
    g2D.setFont(font);        
    for(Wall wall: walls){
        wall.paint(g2D);
    }
    g2D.setColor(Color.orange);
    paddle.paint(g2D);
    g2D.drawString(score + "", 150,50);
    g2D.drawString("record: "+topscore  , 350,50);
    g2D.setColor(Color.red);
    ball.paint(g2D);
    g.drawImage(bimage,0,0,this);
}

Но это не устраняет мерцание. Я думаю, что экран как-то очищается до того, как изображение с буферизацией начинает рисоваться. Может ли кто-нибудь помочь мне с решением этой проблемы? спасибо!

Ответы [ 3 ]

2 голосов
/ 23 января 2011

Вам необходимо переопределить update:

public void update() {
    paint();
}

Реализация по умолчанию update заполняет весь регион цветом фона перед вызовом paint, и именно это вызывает мерцание.

1 голос
/ 23 января 2011

Я не могу точно сказать, что вы делаете по опубликованному коду, но я предполагаю, что вы пытаетесь нарисовать фоновое изображение с движущимися изображениями сверху. Если так, то ваш подход неверен.

Вы не хотите воссоздавать фоновое изображение каждый раз, когда вызывается рисование. Вместо этого буферизованное изображение должно быть создано один раз вне метода paintComponent (). Затем, когда вы перерисовываете компонент, вы сначала просто рисуете изображение (как фон). Затем вы рисуете весло и шарик поверх фона.

Также другой подход состоит в том, чтобы просто использовать JLabels для представления вашего весла и мяча. Затем, чтобы переместить компонент, вы просто меняете его местоположение. Затем необходимо перекрасить только старое / новое расположение компонента вместо всего фона, что также более эффективно.

1 голос
/ 22 января 2011

Вы должны расширить JComponent вместо Canvas, в зависимости от того, используете ли вы Swing, а не AWT. Это дает вам легкий и легкий компонент, и вам не нужно реализовывать поддержку двойной буферизации. Затем в вашем переопределенном paintComponent(..) нарисуйте ваше изображение с предоставленным графическим объектом.

Что касается исходного кода, то создание нового совместимого изображения каждый раз при рисовании выглядит ужасно (это очень дорогая операция, использующая большие байтовые буферы - вы будете получать частые GC-паузы). Если вы действительно хотите использовать двойную буферизацию в AWT (которая дает мерцание при изменении размера, но в апплете все должно быть в порядке), вам следует изучить BufferStrategy .

Редактировать: изменил компонент на JComponent, упс:)

...