2017-01-08 8 views
0

Этот вопрос не "весь экран мерцает" тип вопроса.Специфические объекты мерцают при перекраске

Я пытаюсь понять Java графику и сделал простую игру, но когда сцена перерисовывается с новыми объектами, некоторые объекты постоянно мерцает, odlyне весь экран.

Вот мой render() метод:

private BufferedImage image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB); 

private void render() { 
     BufferStrategy bs = this.getBufferStrategy(); 
     if(bs == null){ 
      createBufferStrategy(6); 
      return; 
     } 
     Graphics g = bs.getDrawGraphics(); 
     Graphics2D g2d = (Graphics2D)g; 
     //fill screen with black background 
     g.drawImage(image, 0, 0, getWidth(), getHeight(), null); 
     //draw cool stuff 
     try { 
      for (int i = 0; i < Element.elements.size(); i++) { 
       Element.elements.get(i).render(g2d); 
      } 
     } catch (Exception e) { 
      System.err.println("No such element to render"); 
     } 
     //dispose graphics 
     g.dispose(); 
     g2d.dispose(); 
     bs.show(); 
} 

Что может возможно вызвать эту проблему? Я не думаю, что количество пузырей вызывает эту проблему.

Если вы хотите, чтобы проверить, что это проект почтовый file и это .jar file

+0

Я не вижу ничего плохого в коде. Обычно, когда экран мерцает в приложении awt/swing, это связано с тем, что кто-то использовал SwingUtilities.InvokeLater(), поэтому только часть страницы перерисовывается во время этого события перерисовки, а другие части позже. Затем следующий шаг - проверить, что холст дважды буферизирован, после этого у меня нет идей. –

ответ

2

Ваше обновление модели, которая делается в потоке событий на ходу мыши, необходимо синхронизировать с вашим потоком рендеринга. Мерцание происходит из-за того, что ваша модель иногда находится в противоречивом состоянии при рендеринге.

Один из способов исправить это сделать в потоке, который вы обновляете вашу модель Вы можете запустить рендеринг в потоке событий с SwingUtilities:.

try { 
    SwingUtilities.invokeAndWait(new Runnable() { 
     @Override 
     public void run() { 
      render(); 
     } 
    }); 
} catch (InvocationTargetException | InterruptedException e) { 
    running = false; 
    System.err.println("Render interrupted"); 
} 

Если вы используете компоненты, отображаются AWT или Swing, вы должны всегда сделать рендеринг в потоке событий.

Поскольку вы сами контролируете весь процесс рендеринга, у вас есть возможность рендеринга в отдельном потоке, но вам придется синхронизировать доступ к вашей модели (то есть, запись в модель, выполняемую потоком событий, должна быть синхронизированный с чтениями, выполняемыми потоком рендеринга).

Например:

В Shredder.scan() (вызывается из потока событий)

public static void scan() { 
    synchronized (Element.elements) { 
     for (Element element : Element.elements) { 
      if (element.containsMouse()) { 
       if (element.getSize() < 24) { 
        Element.elements.remove(element); 
       } else { 
        element.cloneItself(); 
        Element.elements.remove(element); 
       } 
       skip = true; 
       break; 
      } 
     } 
    } 
} 

И в вашей визуализации теме:

synchronized (Element.elements) { 
    for (int i = 0; i < Element.elements.size(); i++) { 
     Element.elements.get(i).render(g2d); 
    } 
} 

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

+1

Это верно для компонентов рисования, но не всегда является истинным утверждением при использовании BufferStrategy. – VGR

+0

@ VGR: Я уточнил ответ, чтобы прояснить это. – teppic

+0

Хорошо, ты посмотришь на это. Он решил проблему. – orkun

 Смежные вопросы

  • Нет связанных вопросов^_^