Partage
  • Partager sur Facebook
  • Partager sur Twitter

Déplacement "fluide"

    20 décembre 2009 à 1:27:18

    Bonsoir,

    J'ai un soucis que je n'arrive pas à résoudre.
    Je souhaiterais faire se déplacer un objet en fonction de points entrés dans un tableau. Les attributs x et y de l'objet prennent bien toutes les valeurs intermédiaires entre les deux points; mais l'objet en lui même apparait d'abord à son point de départ, et une fois la boucle finit se "téléporte" au point d'arrivé.
    Je n'arrive donc pas à avoir une animation "fluide" du déplacement (On devrait voir l'objet se déplacer pixel par pixel)

    Mon code actuel ressemble à ceci:
    double x1, x2, y1, y2;
    //(x1, y1) est le point de départ, (x2, y2) l'arrivé
    x1=rp.x; y1=rp.y;
    //rp est mon objet à déplacer
    x2=arTrajetFinal[1][0]; y2=arTrajetFinal[1][1];
    			    	
    //coefficients à appliquer pour avoir un déplacement 
    //suivant la droite passant par (x1, y1) et (x2, y2)		    	
    double sumX=0, sumY=0, coefX=calcCoefX(x1, x2), coefY=calcCoefY(y1, y2);
    boolean stop = false;
    			    	
    while(!stop) {
    	try {
    		Thread.sleep(5);
    	}
    	catch (InterruptedException e) {
    		e.printStackTrace();
    	}
    
    	sumX += coefX;
    	sumY += coefY;
    						
    	//System.out.println(rp.x + " // "+ rp.y);
    						
    	if(rp.x < arTrajetFinal[k][0]) {
    		if(sumX>=1) {
    			rp.x +=(int)sumX;
    			sumX -= (int)sumX;
    		}
    	} else if(rp.x > arTrajetFinal[k][0]) {
    		if(sumX>=1) {
    			rp.x -= (int)sumX;
    			sumX -= (int)sumX;
    		}
    	}
    						
    	if(rp.y < arTrajetFinal[k][1]) {
    		if(sumY>=1) {
    			rp.y ++;
    			sumY -= (int)sumY;
    		}
    	} else if(rp.y > arTrajetFinal[k][1]) {
    		if(sumY>=1) {
    			rp.y -= (int)sumY;
    			sumY -= (int)sumY;
    		}
    	}
    						
    	if(rp.x==arTrajetFinal[k][0] && rp.y==arTrajetFinal[k][1]) {
    		System.out.println("sortie");
    		stop = true;
    	}
    }
    


    Je ne comprends vraiment pas pourquoi l'objet se "téléporte" uniquement lorsque l'on sort de notre boucle while, mais c'est vraiment problématique.

    Si quelqu'un pouvait m'aider à comprendre pourquoi ca fait ca, et comment faire pour qu'il en soit autrement?
    D'avance merci
    • Partager sur Facebook
    • Partager sur Twitter
      20 décembre 2009 à 10:57:14

      Il faudrait que tu indiques au système d'affichage que ton objet s'est déplacé et qu'il doit donc se mettre à jour.
      Il faudrait plus d'infos sur la manière dont tu affiches tes éléments pour pouvoir t'aider.
      • Partager sur Facebook
      • Partager sur Twitter
        20 décembre 2009 à 23:04:09

        Donc pour tout ce qui est affichage, j'ai :

        class main
        Rectangle r1 = new Rectangle(100, 120, 0, 0);
        
        public void paint(Graphics g) {
            Graphics2D g2 = (Graphics2D)g;
        		
            drawChar(g2, r1, 12, Color.blue);
        }
        public void drawChar(Graphics2D g, Rectangle r, int size, Color colour) {
            g.setColor(Color.white);
            g.fillOval(r.x, r.y, size+2, size+2);
            g.setColor(colour);
            g.fillOval(r.x+1, r.y+1, size, size);
        }
        
        public void run() {
            while (true) {
                repaint();
                try{  Thread.sleep(5); } catch (InterruptedException e) { e.printStackTrace(); }
            }
        }
        


        Donc, je créé un rectangle de taille 0*0 et je me sert de ses attributs x et y pour dessiner un cercle prenant ces attributs. Et une boucle infini qui est censée redessiner toutes les 5 ms notre rond.
        • Partager sur Facebook
        • Partager sur Twitter
          21 décembre 2009 à 12:46:32

          En fait si j'ai bien compris tu ne mets pas à jour ton affichage dans ton code.
          Tout les déplacements que tu fais dans la boucle while se font petit à petit mais ne sont afficher que pour le résultat final, ce qui donne l'impression que ton rond se téléporte. :magicien:
          Rectangle r1 = new Rectangle(100, 120, 0, 0);
          
          public void paint(Graphics g) {
              Graphics2D g2 = (Graphics2D)g;
          		
              drawChar(g2, r1, 12, Color.blue);
          }
          public void drawChar(Graphics2D g, Rectangle r, int size, Color colour) {
              g.setColor(Color.white);
              g.fillOval(balle_X,balle_Y, size+2, size+2);// ici tu donnes les coordonnées de la balle que tu veux dessiner
              g.setColor(colour);
              g.fillOval(r.x+1, r.y+1, size, size);
          }
          /* Méthode qui reçois une position en pixel x, y */
          public void positionnerBalle(int x, int y) {
          	balle_X = x;
          	balle_Y = y;
          	repaint();
          }
          


          Maintenant que on a quelque chose qui reçoit les positions en pixel(balle_X,balle_Y: oublie pas de les déclarer dans ta classe) on peut les mettre à jours
          lors de chaque boucle.
          Il faut donc appeler la fonction positionnerBalle(x,y); dans ta boucle while il faudra crée une instance de l'objet dans lequel ta mis ton panneau

          double x1, x2, y1, y2;
          //(x1, y1) est le point de départ, (x2, y2) l'arrivé
          x1=rp.x; y1=rp.y;
          //rp est mon objet à déplacer
          x2=arTrajetFinal[1][0]; y2=arTrajetFinal[1][1];
          			    	
          //coefficients à appliquer pour avoir un déplacement 
          //suivant la droite passant par (x1, y1) et (x2, y2)		    	
          double sumX=0, sumY=0, coefX=calcCoefX(x1, x2), coefY=calcCoefY(y1, y2);
          boolean stop = false;
          			    	
          while(!stop) {
          	try {
          		Thread.sleep(5);
          	}
          	catch (InterruptedException e) {
          		e.printStackTrace();
          	}
          
          	sumX += coefX;
          	sumY += coefY;
          						
          	//System.out.println(rp.x + " // "+ rp.y);
          						
          	if(rp.x < arTrajetFinal[k][0]) {
          		if(sumX>=1) {
          			rp.x +=(int)sumX;
          			sumX -= (int)sumX;
          		}
          	} else if(rp.x > arTrajetFinal[k][0]) {
          		if(sumX>=1) {
          			rp.x -= (int)sumX;
          			sumX -= (int)sumX;
          		}
          	}
          						
          	if(rp.y < arTrajetFinal[k][1]) {
          		if(sumY>=1) {
          			rp.y ++;
          			sumY -= (int)sumY;
          		}
          	} else if(rp.y > arTrajetFinal[k][1]) {
          		if(sumY>=1) {
          			rp.y -= (int)sumY;
          			sumY -= (int)sumY;
          		}
          	}
          						
          	if(rp.x==arTrajetFinal[k][0] && rp.y==arTrajetFinal[k][1]) {
          		System.out.println("sortie");
          		stop = true;
          	}
                  /* ici t'appelles la méthode positionnerBalle du main ou je ne sait pas ou tu l'as mise   
                     et tu lui envois les positions en x et en y de ce que tu veux faire bouger la j'ai mis x et y par défaut */
                  main.positionnerBalle(x,y);
          
          }
          

          Bon j'ai pas pris la peine de comprendre ce que fait ton algorithme pas voulu me casser la tête
          :lol: mais ça devrais être suffisant pour que tu puisses un peu avancer :D


          • Partager sur Facebook
          • Partager sur Twitter
            21 décembre 2009 à 13:02:37

            Tout d'abord, merci de ton aide ^^

            J'ai adapté ton code pour qu'il corresponde à mes besoins (puisque là j'ai pris l'exemple avec une seule balle, mais en tout il y en aura 10)

            class main :
            public void posBalle(Rectangle r, int x, int y) {
                r.x = x;
                r.y = y;
                repaint();
            }
            


            Par contre, dans ma classe player, je n'arrive pas à apeller ma fonction se trouvant dans le main.
            class player:
            main.posBalle(rp, rp.x, rp.y);
            


            j'ai une erreur d'eclipse :
            "Cannot make a static reference to the non-static method posBall(Rectangle, int, int) from the type main"

            Tu as dis : "il faudra crée une instance de l'objet dans lequel ta mis ton panneau". Je n'ai pas trop compris cette phrase. Pourrais-tu me l'expliquer? Je pense que mon erreur viens de là.

            EDIT :

            Ok je viens de comprendre, il faudrait faire un truc comme ca
            main myMain = new main();
            


            et ensuite appeler ma méthode ainsi
            myMain.posBalle(rp, rp.x, rp.y);
            


            Mais peut on faire une occcurrence de la classe main? Ca fous pas un peu le bordel?
            (J'ai essayé de faire comme je viens de le dire, mais plus rien ne se passe :/ même plus la "téléportation")

            • Partager sur Facebook
            • Partager sur Twitter
              21 décembre 2009 à 13:21:59

              C'est parce que en java quand tu utilises une fonction d'une autre classe tu dois d'abord instancier la classe
              exemple : j'ai la fonction positionnerballe(); dans une classe Affichage et bien je dois d'abord l'appeler si je veux l'utiliser dans la classe Déplacement
              Déplacement deplace = new Déplacement();
              /* Et alors quand on l'appel on fait */
              deplace.positionnerballe(x,y);
              

              Mais pour toi ton erreur je crois que c'est parceque la classe main est static et que tu l'appelles dans une fonction dynamique, c'est pas propre du tout de coder dans la classe main. Il faudrait que tu réorganises un peu ton programme o_O pour le rendre un peu plus Orienter Objet.
              En générale quand on code en JAVA on a tout ce qui est affichage dans une classe que l'on nome fenetre.
              Je te conseil fortement de lire ceci :) ça devrait t'aider
              http://www.siteduzero.com/tutoriel-3-1 [...] n-simple.html XD j'avais oublier le lien
              • Partager sur Facebook
              • Partager sur Twitter
                21 décembre 2009 à 13:29:30

                En effet, je suis bien conscient que mon code est affreux :D J'ai pas trop l'habitude de coder sous Java mais ici j'avais pas le choix

                je vais potasser un peu ton lien pour réorganiser mon bordel, mais le probleme est toujours là :/
                • Partager sur Facebook
                • Partager sur Twitter

                Déplacement "fluide"

                × 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