Partage
  • Partager sur Facebook
  • Partager sur Twitter

Gestion des collisions dans une animation...

...entre des instanciations de 2 types d'objets:

Sujet résolu
    3 novembre 2010 à 13:18:37

    Hello à tous!

    Désolé pour ce titre quelque peu imbuvable!

    Je suis en train de coder un petit jeu en javascript qui s'anime dans la balise canvas d'HTML5. Pour l'instant le truc est simple, des balles circulent de gauche à droite automatiquement et des carrés (appelés bloc) peuvent être glissés sur leur chemin pour le faire faire demi-tour

    J'ai donc une classe balle et une classe bloc.

    Mon système de collision, dans son état actuel, fait rebondir les balles lorsqu'elles touchent les côtés et si elles touchent UN bloc distinct.


    Voici mon soucis : (jetez un coup d'oeil au code en même temps, ce n'est pas simple d'expliquer clairement sans)

    Maintenant que je veux plusieurs blocs, j'ai créer la classe bloc, mais je ne vois plus comment vérifier les collisions.

    Pour animer en canvas, il faut une boucle de rafraichissement (jusque là, rien de suprenant ^^). Pour instancier mes balles, j'ai une boucle qui parcours un array qui les stock et les affichent. La vérification de collision se fait dans cette boucle pour que cela marche avec chacune des balles.
    Mais maintenant que j'instancie aussi les blocs, ça coince.
    Instanciés (de la manière que les balles, cad tableau avec boucle for) à côté de la boucle des balles, je ne peux vérifier la collision, puisqu'elle ne peut plus identifier distinctement les blocs.
    Instanciés dans la boucle des balles, bah ça bug, bien sûr

    Et la je rame depuis des heures pour trouver la solutions :colere2: !

    Je ne vais quand même pas créer distinctement chaque bloc ou balle pour vérifier toutes les possibilités de collision (genre balle 1 VS bloc1, balle 2 VS bloc 2 ...etc pendant des kilomètres de ligne de code...

    Donc question:
    Dois-je complètement revoir la structure du code pour ne plus me trouver face à cette impasse
    Dois-je passer par un tableau de collision qui lui stockerait chaque possibilité (je suppose que ça peut marcher, mais je ne vois clairement pas comment le mettre en place)
    La solution se trouve peut-être au niveau de croiser les boucles entre elles (que ce soit celles d'instanciation et de vérifications de collision)

    Petite, précision, je suis novice en la matière, donc j'ai bien entendu encore pas mal de zone de flou. Mais je peux passer des heures à rouiller un problème! kniark kniark!!

    Please help me!!!!

    Merci d'avance à ceux qui se pencheront sur le problème

    PS: petite précision, pour éviter des "tes variables ne correspondent pas!" hihi : j'ai laissé l'algorithme des collisions avec les variables du bloc lorsqu'il n'y en avait qu'un seul, d'où des "blocX" au lieu de "blocs[i].blocX".
    De même, la collision ne se fait pas exactement sur le carré dessiné, j'ai pas fini de régler les abscisses et ordonnées, je suis en train de coder la fonction "drag and drop"


    //----------------------- Initialisation canvas-----------------------------------//
    var ctx;
    var canvas;
    
    function init() {
    	canvas = document.getElementById("canvas_jeu");
     	ctx = canvas.getContext("2d");
     	return setInterval(draw, tempo);
    	}
    
    
    // --------------------------- VARIABLES -------------------------------------------//
    
    var taille_balle = 10; 
    var vitesse_balle = 2;
    var dirBalleX = 1;
    var dirBalleY = 1;
    var blocX;
    var blocY;
    var L_bloc = 30;
    var H_bloc = 30;
    var tempo = 10;
    var collide = false;
    
    
    
    // ------------------------------------- LES BALLES ---------------------------------------------------------// 
    
    // Class Ball
    function Ball(balleX, balleY, taille_balle, dirBalleX, vitesse_balle) {
    
    	this.balleX = balleX;
    	this.balleY = balleY;
    	this.taille_balle = taille_balle;
    	this.dirBalleX = dirBalleX;
    	this.vitesse_balle = vitesse_balle;
    	
    	
    	this.move = function() {
    
    		    // Collision canvas' border
    	        if( (this.balleX + this.dirBalleX * this.vitesse_balle) + this.taille_balle>300) this.dirBalleX = -1;
    	        else if ( (this.balleX + this.dirBalleX * this.vitesse_balle) - this.taille_balle <  0) this.dirBalleX = 1;
    		    // deplacement balle
    	        this.balleX += this.dirBalleX * this.vitesse_balle;
    		 	// drawing balls
    	    	cercle(this.balleX, this.balleY, this.taille_balle);
    	}
    	
    }//end class Ball
    
    //ball generation  
    // ici la fonction est appelé par un bouton html avec "onclick"
    function createBall() {
    	balls.push(new Ball(20, 20, taille_balle, dirBalleX, vitesse_balle));
    	balls.push(new Ball(20, 80, taille_balle, dirBalleX, vitesse_balle));
    	balls.push(new Ball(20, 140, taille_balle, dirBalleX, vitesse_balle));
    	balls.push(new Ball(20, 200, taille_balle, dirBalleX, vitesse_balle));
    }
    
    // Array for stocking balls
    var balls = new Array();
    
    
    // -------------------------------------- LES BLOCS ----------------------------------------------------------//
    
    //Class Bloc
    function Bloc (blocX, blocY, L_bloc, H_bloc) {
    
    	this.blocX = blocX;
    	this.blocY = blocY;
    	this.L_bloc = L_bloc;
    	this.H_bloc = H_bloc;
    	
    	this.drawBloc = function() {
    		rect(this.blocX, this.blocY, this.L_bloc, this.H_bloc);
    	}
    }
    
    
    /// ici la fonction est appelé par un bouton html avec "onclick"
    function createBloc() {
    	blocs.push(new Bloc(100, 20, 30, 30));
    }
    
    // Array for stocking blocs
    var blocs = new Array();
    
    
    // ------------------------------------- L'ANIMATION ---------------------------------------------------------//
    
    function draw(){
          
            // On efface la zone
            ctx.clearRect(0, 0, 3000, 3000);
     
     		// BLOC GESTION
            for (var j = 0; j < blocs.length; j++) {	 
            	blocs[j].drawBloc();
             }//end for blocs
                  
                  
            // BALL GESTION
            for(var i = 0; i < balls.length; i++) {
              	
              	balls[i].move();
            
            	collide = false;
    			
    			// bloc collisions
    				// left side 
    		        	if( (balls[i].balleX + balls[i].dirBalleX * balls[i].vitesse_balle) + balls[i].taille_balle > blocX 
    		        	&&  (balls[i].balleX + balls[i].dirBalleX * balls[i].vitesse_balle) + balls[i].taille_balle < (blocX + L_bloc)
    		        	&&   blocY < (balls[i].balleY + balls[i].taille_balle)  
    		        	&&  (blocY + H_bloc) > (balls[i].balleY - balls[i].taille_balle)) {
    		        			balls[i].dirBalleX = -1;
    		        			collide = true;
    		        	}
    	        	
    	        	// right side 
    		        	if( (balls[i].balleX + balls[i].dirBalleX * balls[i].vitesse_balle) - balls[i].taille_balle < (blocX + L_bloc) 
    			        &&  (balls[i].balleX + balls[i].dirBalleX * balls[i].vitesse_balle) + balls[i].taille_balle > (blocX + L_bloc)
    			        &&   blocY < (balls[i].balleY + balls[i].taille_balle)  
    			        &&  (blocY + H_bloc) > (balls[i].balleY - balls[i].taille_balle)) {
    			        		balls[i].dirBalleX = 1;
    			        		collide = true;
    			        }
           		
           		
            }// end for balls
            
                   
    }//fin draw
    
    //---------------------------- LANCEMENT ----------------------------//
    
    init();
    
    
       
       
    // -------------------- FORME -----------------------------//
            
             function ligne (ax, ay, bx, by){
            	ctx.beginPath();
    		 	ctx.moveTo(ax,ay);
    		 	ctx.lineTo(bx,by);
    		  	ctx.stroke();
              	} 
             function cercle (x, y, r){
                ctx.beginPath();
                ctx.arc(x, y, r, 0, (Math.PI/180)*360, true);
                ctx.fill();
             	}
    		function rect(x,y,w,h) {
     			ctx.beginPath();
     			ctx.rect(x,y,w,h);
     			ctx.closePath();
     			ctx.fill();
    			}
    
    • Partager sur Facebook
    • Partager sur Twitter
      3 novembre 2010 à 14:23:51

      Il faut que dans la boucle de BALL GESTION, tu parcours à chaque itération le tableau des blocs, et tu vérifies la collision ou non de la balle avec chaque bloc.

      Ca serait pas mal de créer une petite fonction qui se charge de ça.


      // BALL GESTION
      for(var i = 0; i < balls.length; i++) {
        balls[i].move();
        collide = checkCollisionWithAllBlocks(balls[i]);
      }
      
      
      /* Avec une fonction de ce genre : */
      
      function checkCollisionWithAllBlocks(ball) {
        for (var i = 0; i < blocs.length; i++) {
          var bloc = blocs[i],
          blocX = bloc.blocX,
          blocY = bloc.blocY,
          H_bloc = bloc.H_bloc,
          L_bloc = bloc.L_bloc;
          // bloc collisions
          // left side 
          if( (ball.balleX + ball.dirBalleX * ball.vitesse_balle) + ball.taille_balle > blocX 
          &&  (ball.balleX + ball.dirBalleX * ball.vitesse_balle) + ball.taille_balle < (blocX + L_bloc)
          &&   blocY < (ball.balleY + ball.taille_balle)  
          &&  (blocY + H_bloc) > (ball.balleY - ball.taille_balle)) {
            ball.dirBalleX = -1;
            return true;
          }
        
          // right side 
          if( (ball.balleX + ball.dirBalleX * ball.vitesse_balle) - ball.taille_balle < (blocX + L_bloc) 
          &&  (ball.balleX + ball.dirBalleX * ball.vitesse_balle) + ball.taille_balle > (blocX + L_bloc)
          &&   blocY < (ball.balleY + ball.taille_balle)  
          &&  (blocY + H_bloc) > (ball.balleY - ball.taille_balle)) {
            ball.dirBalleX = 1;
            return true;
          }
        }
        return false;
      }
      


      Un truc comme ça par exemple.


      Bien entendu, tu peux checker la collision juste entre une balle et une bloc. Ca change juste la position de la boucle for().

      De même, tu peux faire la vérification dans la boucle des blocs, en parcourant le tableau des balles...

      Tu me suis ?
      • Partager sur Facebook
      • Partager sur Twitter
        3 novembre 2010 à 14:38:52

        Héhé c'était exactement ça!

        j'ai trouvé entre temps (trop acharné, j'ai continué à fouiller). Je ne l'ai pas codé de la manière, mais c'est le même truc, creer la fonction ailleurs, et rapeller chaque bloc pour le test par une variable intérmédiaire

        Je sais pas si tu connais http://balldroppings.com/js/ , j'ia trouvé grâce à ça.

        Je suis pas encore à l'aise avec les tableaux, en fait, ni avec tou ça d'ailleurs! mais c'est tellement "trippant

        Par contre à quoi servent tes "return" ? (pareil, je n'en comprends pas les subtilités)

        En tout cas merci et bon code!
        • Partager sur Facebook
        • Partager sur Twitter
          3 novembre 2010 à 14:50:56

          Les return ne servent à rien ici... puisque la variable collide de ton premier code ne servait à rien non plus :D

          Je les ai juste mis pour qu'elle obtienne la même valeur... au cas où tu décides de lui donner une utilité :D
          • Partager sur Facebook
          • Partager sur Twitter
            3 novembre 2010 à 14:56:36

            Ha ok! merci :)

            En fait, si, mes returns servent pour mettre un bruitage lors de la collision, mais j'ai simplifier le post pour être plus clair
            • Partager sur Facebook
            • Partager sur Twitter

            Gestion des collisions dans une animation...

            × 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