2017-01-08 4 views
0

Cette question n'est pas "l'écran entier scintille" type de question.Objets spécifiques scintillant lorsque repeint

J'essaie de comprendre Java graphiques et fait un jeu simple, mais quand la scène est redessinée avec de nouveaux objets, des objets permet de rester scintille, ODLYpas tout l'écran.

Voici ma méthode 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(); 
} 

Que peut causer ce problème? Je ne pense pas que la quantité de bulles cause ce problème.

Si vous voulez vérifier, c'est le zip du projet file et c'est le .jar file

+0

Je ne vois rien de mal avec le code. Généralement, lorsque l'écran scintille dans une application awt/swing, c'est parce que quelqu'un a utilisé SwingUtilities.InvokeLater(), donc seulement une partie de la page est redessinée pendant cet événement de repaint, d'autres parties plus tard. Ensuite, la prochaine étape est de vérifier que la toile est à double tampon, après quoi je suis à court d'idées. –

Répondre

2

Votre mise à jour du modèle, ce qui est fait dans le fil des événements sur le mouvement de la souris, doit être synchronisé avec votre fil de rendu. Le scintillement se produit parce que votre modèle est parfois dans un état incohérent lorsque le rendu se produit.

Une façon de résoudre ce problème est de rendre dans le fil que vous mettez à jour votre modèle Vous pouvez exécuter votre rendu dans le fil de l'événement avec SwingUtilities:.

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

Si vous utilisez des composants sont rendus par AWT ou Swing vous devriez toujours faire votre rendu dans le fil de l'événement. Comme vous contrôlez vous-même l'ensemble du processus de rendu, vous avez la possibilité de le rendre dans un thread séparé, mais vous devrez synchroniser l'accès à votre modèle (c'est-à-dire écrire dans le modèle effectué par le thread d'événement synchronisé avec les lectures effectuées par le thread de rendu).

Par exemple:

Dans Shredder.scan() (appelé du thread d'événement)

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; 
      } 
     } 
    } 
} 

Et dans votre fil render:

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

En forme, il serait bon idée de mettre le code qui doit être synchronisé dans un seul endroit afin que le code d'appel ne doit pas être concerné par le maintien de la cohérence.

+1

Ceci est vrai pour les composants de peinture, mais ce n'est pas toujours une déclaration vraie lors de l'utilisation d'un BufferStrategy. – VGR

+0

@VGR: J'ai mis à jour la réponse pour clarifier cela. – teppic

+0

Eh bien, allez-vous regarder ça. Il a résolu le problème. – orkun