Partage
  • Partager sur Facebook
  • Partager sur Twitter

JLayeredPane et JPanel

Sujet résolu
    20 octobre 2010 à 18:05:12

    Bonjour,

    Je suis en train de programmer un "jeu de football". En gros, des joueurs se déplacent sur un terrain de manière plus ou moins aléatoire.
    Le problème que j'ai est qu'à chaque fois qu'un joueur change de position, l'ensemble du terrain et des joueurs est redessiné, ce qui entraine un scintillement désagréable à la vue (en plus de n'être pas optimisé).
    Pour remédier à ça, j'ai voulu utiliser un JLayeredPane qui contient 2 JPanel, un pour le terrain et un pour les joueurs (pour commencer).
    Néanmoins, impossible de réussir à afficher le terrain en dessous des joueurs.

    Voilà mon code :

    Image imgStade, imgJoueurs;
            JLayeredPane jlpEnsemble;
            JPanel jpStade, jpJoueurs;
    
            jpStade = new JPanel();
            jpStade.setBounds(0, 0, 800, 400);
            jpJoueurs = new JPanel();
            jpJoueurs.setBounds(0, 0, 800, 400);
            jlpEnsemble = new JLayeredPane();
            jlpEnsemble.setPreferredSize(new Dimension(800, 400));        
            jlpEnsemble.add(jpJoueurs, new Integer(1));
            jlpEnsemble.add(jpStade, new Integer(2));
            this.getContentPane().add(jlpEnsemble);
            pack();
            this.setVisible(true);
    
            Dimension dim = jpStade.getSize();
            imgStade = jpStade.createImage(dim.width, dim.height);
            Graphics g = imgStade.getGraphics();
            g.setColor(Color.green);
            g.fillRect(0, 0, dim.width, dim.height); // Dessin du stade
            Dimension dim2 = jpJoueurs.getSize();
            imgJoueurs = jpJoueurs.createImage(dim2.width, dim2.height); // Image qui servira à dessiner les joueurs par la suite
    


    Auriez vous une idée de l'origine du problème ?

    Merci d'avance
    • Partager sur Facebook
    • Partager sur Twitter
      23 octobre 2010 à 16:40:07

      Un JPanel est opaque par défaut, donc si tu veux pouvoir voir derrière lui, i faut appeler dessus la méthode setOpaque(false);. Un simple jpJoueurs.setOpaque(false); devrait donc marcher.
      Par contre, quelques remarques supplémentaires :
      - N'utilise pas new Integer(int), mais plutôt Integer.valueOf(int), Java garde en mémoire les Integer pas trop élevés, ça t'évite de créer des objets pour rien.
      - Il y a d'autres manière d'éviter ce scintillement. Le plus simple est d'utiliser le constructeur JPanel(boolean isDoubleBuffered). Si ce booléen vaut true, alors Java dessinera d'abord tout le composant en mémoire, sans l'afficher, puis échangera le dessin en mémoire et celui affiché à l'écran une fois terminé, ce qui rendra ce scintillement imperceptible.
      - De plus, si ton dessin prends du temps, évites de redessiner tout le terrain quand un joueur se déplace peut-être. Si ta caméra ne bouge pas, tu dois juste redessiner la région qui contient le joueur. Dans ce cas, au lieu d'appeler la méthode repaint() sur ton composant, utilises repaint(long tm, int x, int y, int width, int height);. Laisses tm à 0, les autres paramètres définissent la région à repeindre.
      - Enfin, ça me parait assez étrange qu'un scintillement soit visible si tu n'as qu'un terrain et des joueurs à dessiner. Vérifie que tu n'effectues pas de traitement dans tes méthodes paintComponent (ou paint), si tu effectues des calculs dedans, tu as probablement une erreur de conception quelque part. Tes méthodes de dessin ne doivent contenir que du dessin, pas de calcul (par exemple, n'effectue surtout pas les déplacements de tes joueurs dans cette méthode).
      • Partager sur Facebook
      • Partager sur Twitter
        26 octobre 2010 à 20:04:33

        Bonsoir,
        Tout d'abord merci de tes conseils.
        Les scintillements viennent du fait que chaque joueur est un thread, et que à chaque mise à jour des coordonnées (toutes les 50ms) tout le terrain est redessiné.
        Je vais tenter de mettre en œuvre tes conseils.
        • Partager sur Facebook
        • Partager sur Twitter
          26 octobre 2010 à 20:40:08

          Salut,

          Chaque joueur est un Thread c'est bien, ça veut dire que tu as maximum 22 threads qui tournent en même temps (ce n'est as beaucoup).

          Normalement ce que tu doit redessiner à chaque fois c'est uniquement les joueurs, pour le terrain tu ne le dessine qu'une seule fois.

          Pour verifier si c'est le nombre de joueur qui pose problème, fait des essais avec 2, 4, 6 joueurs, et tu auras ta réponse.
          • Partager sur Facebook
          • Partager sur Twitter
          J'ai tous les badges d'OpenClassrooms.
            27 octobre 2010 à 13:11:02

            Mon problème venait d'une mauvaise utilisation du graphisme en Java.
            Merci à tous pour vos conseils.
            • Partager sur Facebook
            • Partager sur Twitter

            JLayeredPane et JPanel

            × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
            × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
            • Editeur
            • Markdown