Partage
  • Partager sur Facebook
  • Partager sur Twitter

Cercle en Java

Sujet résolu
    24 septembre 2011 à 14:53:58

    Bonjour, voila j'ai un petit soucis avec mon code java, je dois créer des cercles et les faire bouger (position,taille,et vitesse varié), sa c'est bon mais parfois :
    - ils laissent des traces sur l'écran
    - les cercles sont coupés parfois (tout dépend de la vitesse mais ça arrive quand même)
    - les cercles clignotent

    j'aimerais bien résoudre ces 3 problèmes voici mon code :
    package BalleRebondisante;
    
    
    import java.awt.Dimension;
    import java.awt.Graphics;
    
    import javax.swing.JPanel;
    
    public class Balle extends Thread{
    	
    	int lower = 5;
    	int higher = 30;
    	int lower2 = 0;
    	int higher2 = 250;
    	int lower3 = 1;
    	int higher3 = 5;
    
    
    	private JPanel panneau;
    	private int x =(int)(Math.random() * (higher2-lower2)) + lower2;
    	private int y = (int)(Math.random() * (higher2-lower2)) + lower2;
    	private int dx  =(int)(Math.random() * (higher3-lower3)) + lower3;
    	private int dy  =(int)(Math.random() * (higher3-lower3)) + lower3;
    
    	private  final int taille =(int)(Math.random() * (higher-lower)) + lower;
    
    	public Balle(JPanel panneau, ThreadGroup groupe, String nom){
    		super(groupe,nom);
    		this.panneau=panneau;
    
    	}
    
    	public void dessine() {
    		Graphics surface = panneau.getGraphics(); // récupère les ressources graphiques
    		surface.fillOval(x, y, taille, taille); // pour permettre le tracé des dessins
    		surface.dispose();  // libère les ressources graphiques pour d'autres applications
    	}
    
    	public void déplace() {
    		Graphics surface = panneau.getGraphics();
    		surface.setXORMode(panneau.getBackground());
    		surface.fillOval(x, y, taille, taille);   // efface l'ancien tracé grâce
    		x += dx; y += dy;                         // à la fonction XOR
    		Dimension dim = panneau.getSize(); // dimension du panneau
    		if (x<1) {
    			x=1; dx = -dx; 
    		}
    		if (x+taille >= dim.width ) {
    			x = dim.width - taille; dx = -dx; 
    		}
    		if (y<1) { 
    			y=1; dy = -dy; }
    
    		if (y+taille >= dim.height ) {
    			y = dim.height - taille; dy = -dy; 
    		}
    		surface.fillOval(x, y, taille, taille); // trace le nouvel emplacement de la balle
    		surface.dispose();
    	}
    	public void run() {
    		try {
    			dessine();
    			while (!interrupted()) {
    				déplace(); sleep(20);
    			}
    		}
    		catch (InterruptedException e) {}
    		Graphics surface = panneau.getGraphics();
    		surface.setXORMode(panneau.getBackground());
    		surface.fillOval(x, y, taille, taille);
    		
    	}
    
    
    }
    

    package BalleRebondisante;
    
    
    
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    
    
    
    public class Ecran extends JFrame{
    	
    	private static final int DEFAULT_HEIGHT_FENETRE = 500;
    	private static final int DEFAULT_WIDTH_FENETRE = 650;
    	private static final int DELAY_REFRESH = 25;
    	private static final int NB_BALLES = 150;
    	protected static final int TY_BORD = 5;
    	
    	static JPanel panneau = new JPanel();
    	JPanel contentPane;
    	static ThreadGroup groupe = new ThreadGroup("balle");
    	
    	public Ecran() {
    	super("Balles rebondissantes");
    	this.setSize(DEFAULT_WIDTH_FENETRE,DEFAULT_HEIGHT_FENETRE);
    	setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    	
    	 
    	
    	 contentPane = (JPanel) this.getContentPane();
    	 contentPane.add(panneau);
    	 this.setVisible(true);
    	}
    	
    	
    	
    	
    	 public static void main(String[] args) {
    	new Ecran();
    	for(int i =0;i<NB_BALLES;i++){
    		Balle balle = new Balle(panneau, groupe, "balle");
    		
    		balle.start();
    		try {
    			Thread.sleep(500);
    		} catch (InterruptedException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    		
    	}
    	 }
    	
    }
    
    • Partager sur Facebook
    • Partager sur Twitter
      24 septembre 2011 à 19:00:16

      j'ai compris comment fonctionne le double buffer mais le soucis c'est qu'il faut faire un extends de Frame et j'ai déjà un extends de Thread donc je peux faire un implements de Runnable à la place mais après tout plante ><
      • Partager sur Facebook
      • Partager sur Twitter
        24 septembre 2011 à 20:56:53

        Salut,

        Enfaite, je pense que c'est ta structure est fausse.
        Il n'y a pas de rapport entre une balle et un thread.
        Quant tu fait ClassA extend ClassB. c'est qui ClassA est une classB amélioré. Ici on peut pas dire qu'un balle est un thread amélioré.

        C'est plus ta frame qui doit implémenté l'interface Runnable. Le thread se chargera de donner l'ordre d'avancer la balle puis de la dessiner.
        • Partager sur Facebook
        • Partager sur Twitter
          25 septembre 2011 à 11:36:49

          merci pour tes indication , après avoir bataillé avec le code pendant plusieurs heures^^ j'ai réussi à changer le Thread, mais maintenant le soucis est au niveau du double buffer , quand je fait un image = createImage(x,y) il me la met a null :s
          alors que dans l'exemple de java cela marche bien x)


          j'ai besoin d'aide pour crée un double buffer, j'ai beau tester plein de chose rien ne marche (j'arrive même a dessiner des tubes ><)

          voici le code : c'est dans la méthode dessine


          package BalleSdz;
          
          import java.awt.Dimension;
          import java.awt.Frame;
          import java.awt.Graphics;
          import java.awt.Image;
          import javax.swing.JPanel;
          
          public class Balle extends Frame{
          
          	int lower = 5;
          	int higher = 30;
          	int lower2 = 0;
          	int higher2 = 250;
          	int lower3 = 1;
          	int higher3 = 5;
          
          	private JPanel panneau;
          	private int x =(int)(Math.random() * (higher2-lower2)) + lower2;
          	private int y = (int)(Math.random() * (higher2-lower2)) + lower2;
          	private int dx  =(int)(Math.random() * (higher3-lower3)) + lower3;
          	private int dy  =(int)(Math.random() * (higher3-lower3)) + lower3;
          
          	private Graphics buffer;
          	private Image image;
          
          	private  final int taille =(int)(Math.random() * (higher-lower)) + lower;
          
          	public Balle(JPanel panneau){
          		super();
          		this.panneau=panneau;
          
          	}
          
          	public void dessine() {
          
          		if(buffer==null){
          			image = createImage(panneau.getWidth(),panneau.getHeight());
          			buffer = image.getGraphics();	// problème ici null pointer !!!!!!!!
          		}
          
          		Graphics surface = panneau.getGraphics(); // récupère les ressources graphiques
          		buffer.fillOval(x, y, taille, taille); // pour permettre le tracé des dessins
          		surface.drawImage(image, 0	,0, this);
          		surface.dispose();  // libère les ressources graphiques pour d'autres applications
          	}
          
          	public void reDessine(){
          
          		Graphics surface = panneau.getGraphics();
          		surface.setXORMode(panneau.getBackground());
          		surface.fillOval(x, y, taille, taille);
          	}
          
          	public void déplace() {
          		Graphics surface = panneau.getGraphics();
          		surface.setXORMode(panneau.getBackground());
          		surface.fillOval(x, y, taille, taille);   // efface l'ancien tracé grâce
          		x += dx; y += dy;                         // à la fonction XOR
          		Dimension dim = panneau.getSize(); // dimension du panneau
          		if (x<1) {
          			x=1; dx = -dx; 
          		}
          		if (x+taille >= dim.width ) {
          			x = dim.width - taille; dx = -dx; 
          		}
          		if (y<1) { 
          			y=1; dy = -dy; }
          
          		if (y+taille >= dim.height ) {
          			y = dim.height - taille; dy = -dy; 
          		}
          		surface.fillOval(x, y, taille, taille); // trace le nouvel emplacement de la balle
          		surface.dispose();
          	}
          
          	public static void main(String[] args) {
          		new Ecran();
          	}
          }
          


          je met l'autre classe au cas où

          package BalleSdz;
          
          
          
          import java.awt.Graphics;
          import java.awt.Image;
          
          import javax.swing.JFrame;
          import javax.swing.JPanel;
          
          
          
          public class Ecran extends JFrame implements Runnable{
          	
          	private static final int DEFAULT_HEIGHT_FENETRE = 500;
          	private static final int DEFAULT_WIDTH_FENETRE = 650;
          	private static final int DELAY_REFRESH = 25;
          	private static final int NB_BALLES = 150;
          	protected static final int TY_BORD = 5;
          
          	
          	static JPanel panneau = new JPanel();
          	JPanel contentPane;
          	static ThreadGroup groupe = new ThreadGroup("balle");
          	
          	public Ecran() {
          		
          	super("Balles rebondissantes");
          	this.setSize(DEFAULT_WIDTH_FENETRE,DEFAULT_HEIGHT_FENETRE);
          	setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
          	 contentPane = (JPanel) this.getContentPane();
          	 contentPane.add(panneau);
          	 this.setVisible(true);
          	 for(int i=0;i<NB_BALLES;i++){
          		 try {
          			 new Thread(this).start();
          				Thread.sleep(500);
          			} catch (InterruptedException a) {
          				// TODO Auto-generated catch block
          				a.printStackTrace();
          			}
          	 }
          	}
          	
          	@Override
          	public void run() {
          		
          		Balle balle = new Balle(panneau);
          		try {
          				balle.dessine();
          			while (true) {
          				balle.déplace(); 
          				Thread.sleep(20);
          			}
          		}
          		catch (InterruptedException e) {}
          			balle.reDessine();
          	}
          	
          }
          
          • Partager sur Facebook
          • Partager sur Twitter
            26 septembre 2011 à 22:41:10

            Up =) besoin d'aide pour le double buffer svp j'ai beau tester plein de truc rien ne marche correctement :s
            • Partager sur Facebook
            • Partager sur Twitter
              26 septembre 2011 à 22:52:50

              La méthode createImage(), c'est toi qui l'a écrite ? Je ne la vois pas dans ton code.
              • Partager sur Facebook
              • Partager sur Twitter
                26 septembre 2011 à 22:57:07

                c'est une méthode hérité de frame sauf que si je fait image= createImage(400,400); j’obtiens un null pointer quand je fait un getGraphics dessus , pourtant dans l'exemple de java pour eu ça marche mais pas dans mon code :s
                http://java.developpez.com/faq/gui/?pa [...] ublebuffering
                • Partager sur Facebook
                • Partager sur Twitter
                  26 septembre 2011 à 23:11:31

                  Ce que j'ai du mal à comprendre c'est pourquoi tu as un NullPointer alors que ton image est censée être instanciée...
                  • Partager sur Facebook
                  • Partager sur Twitter
                    26 septembre 2011 à 23:17:49

                    c'est peu être par ce que ce n'est pas dans une méthode paint(Graphics g) mais ça m'étonne ^^


                    Image utilisateur
                    • Partager sur Facebook
                    • Partager sur Twitter
                      26 septembre 2011 à 23:25:50

                      D'après la javadoc createImage() renvoie null si le composant n'est pas affichable (displayable).

                      Le problème c'est que ta Frame (Balle) il faut lui dire qu'elle est dans ton Ecran. Il faut ajouter le composant... enfin je pense que c'est dans cette voie la qu'il faut chercher

                      Edit

                      En mettant un setVisible(true); dans le constructeur de Balle ca semble améliorer les choses. Il n'y a plus de NullPointer et ca affiche les balles. Par contre l'affichage est pas super mais ca c'est un autre problème ^^

                      Je pense que comme tu n'avais pas mis le setVisible il ne considérait pas ta Frame comme displayable, par conséquent le createImage() te renvoyais null et tu avais une belle NullPointerException :)
                      • Partager sur Facebook
                      • Partager sur Twitter
                        26 septembre 2011 à 23:40:41

                        sauf que j'ai une frame qui clignote du coup , par contre j'ai remarquer que si je renomme ma méthode dessine en paint(Graphics g) et que je fait repaint() au lieu de balle.dessine() je n'est plus de null pointer mais toujours un soucis d'affichage, il faudrait aussi modifier la méthode déplace()

                        ps:supprime la méthode reDessine() il ne va jamais dedans^^'

                        je remet les codes ils fonctionnent mais toujours un soucis de double buffer (il reste surement juste un petit truc à modifier :s )

                        package BalleRebondisante;
                        import java.awt.Color;
                        import java.awt.Dimension;
                        import java.awt.Frame;
                        import java.awt.Graphics;
                        import java.awt.Image;
                        import javax.swing.JPanel;
                        
                        public class Balle extends Frame{
                        
                        	int lower = 5;
                        	int higher = 30;
                        	int lower2 = 0;
                        	int higher2 = 250;
                        	int lower3 = 1;
                        	int higher3 = 5;
                        
                        	private JPanel panneau;
                        	private int x =(int)(Math.random() * (higher2-lower2)) + lower2;
                        	private int y = (int)(Math.random() * (higher2-lower2)) + lower2;
                        	private int dx  =(int)(Math.random() * (higher3-lower3)) + lower3;
                        	private int dy  =(int)(Math.random() * (higher3-lower3)) + lower3;
                        
                        	private Graphics buffer;
                        	private Image image;
                        
                        	private  final int taille =(int)(Math.random() * (higher-lower)) + lower;
                        
                        	public Balle(JPanel panneau){
                        		super();
                        		this.panneau=panneau;
                        	}
                        
                        	public void paint(Graphics g) {
                        
                        		if(buffer==null){
                        			image = createImage(500,650);
                        			buffer = image.getGraphics();	// problème ici null pointer !!!!!!!!
                        		}
                        
                        		buffer.setColor( Color.white );
                        		buffer.fillRect( 0, 0, 500, 650 );
                        		buffer.setColor( Color.black );
                        		buffer.fillOval(x, y, taille, taille); // pour permettre le tracé des dessins
                        		g.drawImage(image, 0	,0, this);
                        		// libère les ressources graphiques pour d'autres applications
                        	}
                        	
                        	public void déplace(Graphics g) {
                        	
                        		Graphics surface = panneau.getGraphics();
                        		surface.setXORMode(panneau.getBackground());
                        		surface.fillOval(x, y, taille, taille);   // efface l'ancien tracé grâce
                        		x += dx; y += dy;                         // à la fonction XOR
                        		Dimension dim = panneau.getSize(); // dimension du panneau
                        		if (x<1) {
                        			x=1; dx = -dx; 
                        		}
                        		if (x+taille >= dim.width ) {
                        			x = dim.width - taille; dx = -dx; 
                        		}
                        		if (y<1) { 
                        			y=1; dy = -dy; }
                        
                        		if (y+taille >= dim.height ) {
                        			y = dim.height - taille; dy = -dy; 
                        		}
                        		surface.fillOval(x, y, taille, taille); // trace le nouvel emplacement de la balle
                        		surface.dispose();
                        	}
                        
                        	public static void main(String[] args) {
                        		new Ecran();
                        	}
                        }
                        


                        package BalleRebondisante;
                        
                        import javax.swing.JFrame;
                        import javax.swing.JPanel;
                        
                        public class Ecran extends JFrame implements Runnable{
                        
                        	private static final int DEFAULT_HEIGHT_FENETRE = 500;
                        	private static final int DEFAULT_WIDTH_FENETRE = 650;
                        	private static final int DELAY_REFRESH = 25;
                        	private static final int NB_BALLES = 5;
                        	protected static final int TY_BORD = 5;
                        
                        	static JPanel panneau = new JPanel();
                        	JPanel contentPane;
                        	static ThreadGroup groupe = new ThreadGroup("balle");
                        
                        	public Ecran() {
                        
                        		super("Balles rebondissantes");
                        		this.setSize(DEFAULT_WIDTH_FENETRE,DEFAULT_HEIGHT_FENETRE);
                        		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                        		contentPane = (JPanel) this.getContentPane();
                        		contentPane.add(panneau);
                        		this.setVisible(true);
                        		for(int i=0;i<NB_BALLES;i++){
                        			try {
                        				new Thread(this).start();
                        				Thread.sleep(500);
                        			} catch (InterruptedException a) {
                        				// TODO Auto-generated catch block
                        				a.printStackTrace();
                        			}
                        		}
                        	}
                        
                        	@Override
                        	public void run() {
                        
                        		Balle balle = new Balle(panneau);
                        		try {
                        			repaint();
                        			while (true) {
                        				balle.déplace(panneau.getGraphics()); 
                        				Thread.sleep(20);
                        			}
                        		}
                        		catch (InterruptedException e) {}
                        
                        	}
                        }
                        
                        • Partager sur Facebook
                        • Partager sur Twitter
                          27 septembre 2011 à 20:19:28

                          J'ai fait un petit truc vite fait, Pour que tu est la forme du programme.

                          Il te reste a mettre en place le double buffer.
                          A change le type de variable des balle de int a double pour un meilleur rendu.




                          package BalleRebondisante;
                          
                          import javax.swing.JFrame;
                          import javax.swing.JPanel;
                          
                          public class Ecran extends JFrame implements Runnable{
                          
                          	private static final int DEFAULT_HEIGHT_FENETRE = 500;
                          	private static final int DEFAULT_WIDTH_FENETRE = 650;
                          	private static final int DELAY_REFRESH = 25;
                          	private static final int NB_BALLES = 5;
                          	protected static final int TY_BORD = 5;
                          
                          	
                          	private Thread thread ;
                                  private Balle[] balles ;
                          	public Ecran() {
                          
                          		super("Balles rebondissantes");
                          		this.setSize(DEFAULT_WIDTH_FENETRE,DEFAULT_HEIGHT_FENETRE);
                          		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                          		
                          		balles = new Balle[NB_BALLES];
                          		for(int i=0;i<NB_BALLES;i++){
                                              balles[i] = new Balle();
                                              this.add(balles[i]);
                                              
                          		}
                                          thread = new Thread(this);
                                          
                                          this.setVisible(true);
                                          thread.start();
                          	}
                          
                          	@Override
                          	public void run() {
                          		try {	
                          			while (true) {
                                                          for( int i = 0 ; i < NB_BALLES ; i++)
                                                              balles[i].déplace(this.getSize()); 
                                                          
                          				Thread.sleep(DELAY_REFRESH);
                          			}
                          		}
                          		catch (InterruptedException e) {
                                              System.err.println(e.getMessage());
                                          }
                          
                          	}
                                  
                                  
                                  
                                  public static void main(String[] args) {
                          		new Ecran();
                          	}
                          }
                          



                          package BalleRebondisante;
                          import java.awt.Color;
                          import java.awt.Dimension;
                          import java.awt.Frame;
                          import java.awt.Graphics;
                          import java.awt.Image;
                          import javax.swing.JComponent;
                          import javax.swing.JPanel;
                          
                          public class Balle extends JComponent{
                          
                          	int lower = 5;
                          	int higher = 30;
                          	int lower2 = 0;
                          	int higher2 = 250;
                          	int lower3 = 1;
                          	int higher3 = 4;
                          
                          	
                          	private int x =(int)(Math.random() * (higher2-lower2)) + lower2;
                          	private int y = (int)(Math.random() * (higher2-lower2)) + lower2;
                          	private int dx  =(int)(Math.random() * (higher3-lower3)) + lower3;
                          	private int dy  =(int)(Math.random() * (higher3-lower3)) + lower3;
                          
                          	
                          
                          	private  final int taille =(int)(Math.random() * (higher-lower)) + lower;
                          
                          	public Balle(){
                          		super();
                          		this.setLocation(x, y);
                                          this.setSize(taille , taille);
                                          this.setPreferredSize(getSize());
                          	}
                          
                          	public void paint(Graphics g) {
                                          
                          		g.setColor( Color.black );
                          		g.fillOval(0, 0, taille, taille); // pour permettre le tracé des dessins
                          	}
                          	
                          	public void déplace(Dimension dim) {
                          	
                          
                          		x += dx; 
                                          y += dy;                         
                          		
                          		if (x<1) {
                          			x=1; 
                                                  dx = -dx; 
                          		}
                          		if (x+taille >= dim.width ) {
                          			x = dim.width - taille; 
                                                  dx = -dx; 
                          		}
                          		if (y<1) { 
                          			y=1; dy = -dy; }
                          
                          		if (y+taille >= dim.height ) {
                          			y = dim.height - taille; 
                                                  dy = -dy; 
                          		}
                          		setLocation(x, y);
                                          revalidate();
                          	}
                          
                          	
                          }
                          


                          Enfin, voila si sa peut d'aider, j'avait du temps a perde :p
                          • Partager sur Facebook
                          • Partager sur Twitter
                            27 septembre 2011 à 20:36:02

                            Merci pour ton code , apparemment pas besoin de double buffer ^^' il y a juste la 1ère balle qui bug, visiblement cela fonctionne mieux avec une liste merci =) j'ai juste a corrigé le soucis des balles qui rebondissent trop tard mais ca devrais aller^^

                            ps: j'ai enlever revalidate() je ne sais pas a quoi il sert mais en tout cas sans lui la première balle ne bug plus ;)

                            merci encore :)
                            • Partager sur Facebook
                            • Partager sur Twitter

                            Cercle en Java

                            × 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