Problème de collision entre une balle et un rectangle, des solutions ?

General

loic

3 weeks ago

Hey !

Je suis débutant en programmation mais relativement assez acharné pour être arrivé jusqu'ici sans aide, malgré ça c'est le moment d'en demander alors je fait appel à un connaisseur en la matière ;)

Voila l'histoire, après le pong je m'essaye à un casse brique, et je m'en sort plutôt bien... enfin jusqu'à maintenant.

Le reste de mon code source est dans un autre fichier (que je peut montrer si il y a des intéressés) mais plus bas j'ai copié mon code source concernant l'affichage des briques et des collisions à celles-ci.

Donc le problème ici c'est que ma balle tape les briques et les fait disparaitre cependant elle tape aux centres des briques et non aux bords (sans parler des angles qui sont carrément snober par ma très chère balle).

J'ai bien essayer de rajouter la taille de la balle aux positions des briques (dans la fonction de collision) mais alors un coté touche et son opposé est traversé (donc c'est pas mieux ^^).

Pour l'instant j'émet plusieurs hypothèses (sans grand succès), peut être un problème de vitesse de la balle (pourtant de 1 ici), les fonctions collideRectRect mal placées ou un paramètre qui manque ???

Je sèche carrément ^o^ 

Merci d'avance pour les âmes charitables de passage par là !


//info : ballSize = 3, et ma fonction "void brick" est réutilisée au début de ma fonction "void setup"
//info : il y a 10 briques réparties sur 3 lignes => 4 puis 2 puis 4
///////////////////////////////////////////////
//////////////affichage briques et collision//////////////////////////

  //variable brique
  const int brickX = 20;
  const int brickY = 20;
  const int brickW = 10;
  const int brickH = 4;

 ///////variable marge de séparation//////
//ligne de brique (séparation entre les briques)
  const int sepaY2 = 6;
  const int sepaY3 = 12;

  //variables etat des briques
  int brick1 = 1;
  int brick2 = 1;
  int brick3 = 1;
  int brick4 = 1;
  int brick5 = 1;
  int brick6 = 1;
  int brick7 = 1;
  int brick8 = 1;
  int brick9 = 1;
  int brick10 = 1;

void brick ()
{
  ////////////////////////////////////////////////////////////////////////////
  /////////////ligne 1////////////////////////////////////////////////////////
  while (brick1) 
  {
    gb.display.setColor(ORANGE);
    gb.display.fillRect (brickX,brickY,brickW,brickH);
    
    if (gb.collideRectRect(ballX,ballY,ballSize,ballSize,brickX,brickY,brickW,brickH)) {
      brick1 = 0;
      ballSpeedY = -ballSpeedY;
    }
    break;
  }
  while (brick2) 
  {
    gb.display.setColor(ORANGE);
    gb.display.fillRect (brickX + brickW + 1,brickY,brickW,brickH);

    if (gb.collideRectRect(ballX,ballY,ballSize,ballSize,brickX + brickW + 1,brickY,brickW,brickH)) {
      brick2 = 0;
      ballSpeedY = -ballSpeedY;
    }
    break;
  }
  while (brick3) 
  {
    gb.display.setColor(ORANGE);
    gb.display.fillRect (brickX + (brickW*2) + 2,brickY,brickW,brickH);

    if (gb.collideRectRect(ballX,ballY,ballSize,ballSize,brickX + (brickW*2) + 2,brickY,brickW,brickH)) {
      brick3 = 0;
      ballSpeedY = -ballSpeedY;
    }
    break;
  }
  while (brick4) 
  {
    gb.display.setColor(ORANGE);
    gb.display.fillRect (brickX + (brickW*3) + 3,brickY,brickW,brickH);

    if (gb.collideRectRect(ballX,ballY,ballSize,ballSize,brickX + (brickW*3) + 3,brickY,brickW,brickH)) {
      brick4 = 0;
      ballSpeedY = -ballSpeedY;
    }
    break;
  }
  ////////////////////////////////////////////////////////////////////////////////////
  ///////////////ligne 2/////////////////////////////////////////////////////////////
  while (brick5) 
  {
    gb.display.setColor(ORANGE);
    gb.display.fillRect (brickX + brickW + 1,brickY + sepaY2,brickW,brickH);

    if (gb.collideRectRect(ballX,ballY,ballSize,ballSize,brickX + brickW + 1,brickY + sepaY2,brickW,brickH)) {
      brick5 = 0;
      ballSpeedY = -ballSpeedY;
    }
    break;
  }
  while (brick6) 
  {
    gb.display.setColor(ORANGE);
    gb.display.fillRect (brickX + (brickW*2) + 2,brickY + sepaY2,brickW,brickH);

    if (gb.collideRectRect(ballX,ballY,ballSize,ballSize,brickX + (brickW*2) + 2,brickY + sepaY2,brickW,brickH)) {
      brick6 = 0;
      ballSpeedY = -ballSpeedY;
    }
    break;
  }
  ////////////////////////////////////////////////////////////////////////////
  /////////////ligne 3////////////////////////////////////////////////////////
  while (brick7) 
  {
    gb.display.setColor(ORANGE);
    gb.display.fillRect (brickX,brickY + sepaY3,brickW,brickH);

    if (gb.collideRectRect(ballX,ballY,ballSize,ballSize,brickX,brickY + sepaY3,brickW,brickH)) {
      brick7 = 0;
      ballSpeedY = -ballSpeedY;
    }
    break;
  }
  while (brick8) 
  {
    gb.display.setColor(ORANGE);
    gb.display.fillRect (brickX + brickW + 1,brickY + sepaY3,brickW,brickH);

    if (gb.collideRectRect(ballX,ballY,ballSize,ballSize,brickX + brickW + 1,brickY + sepaY3,brickW,brickH)) {
      ballSpeedY = -ballSpeedY;
      brick8 = 0;
    }
    break;
  }
  while (brick9) 
  {
    gb.display.setColor(ORANGE);
    gb.display.fillRect (brickX + (brickW*2) + 2,brickY + sepaY3,brickW,brickH);

    if (gb.collideRectRect(ballX,ballY,ballSize,ballSize,brickX + (brickW*2) + 2,brickY + sepaY3,brickW,brickH)) {
      brick9 = 0;
      ballSpeedY = -ballSpeedY;
    }
    break;
  }
  while (brick10) 
  {
    gb.display.setColor(ORANGE);
    gb.display.fillRect (brickX + (brickW*3) + 3,brickY + sepaY3,brickW,brickH);

    if (gb.collideRectRect(ballX,ballY,ballSize,ballSize,brickX + (brickW*3) + 3,brickY + sepaY3,brickW,brickH)) {
      brick10 = 0;
      ballSpeedY = -ballSpeedY;
    }
    break;
  }
}

geed

NEW 3 weeks ago

Regarde dans mon programme Oubliettes, j'ai été confronté à des soucis similaires.
Du coup :

  • j'ai assimilé ma balle à un carré
  • j'applique le déplacement avec la vitesse, puis, si et seulement si, il y a une collision "j'annule" le déplacement.
  • Je détecte la collision sur la ligne "au dessus" de la plateforme, et pas "sur" la plateforme

loic

NEW 3 weeks ago

Ok merci bien. Je vais voir si je peux trouver une solution dans ton programme alors ;)

loic

NEW 3 weeks ago

Pour les personnes faisant face au même problème, la solution était de changer la taille de la balle (3*3 à la base et maintenant devenu 4*4) je ne comprend pas très bien pourquoi mais cela doit avoir un rapport avec la taille des briques (ici 4 de hauteur). La taille d'un objet doit pouvoir etre un multiple de la taille de l'objet avec lequel elle rentre en collision. Cette hypothèse reste à vérifier mais ça a régler mon problème. Merci Geed je l'ai déduis avec ton programme ;)

clement

NEW 3 weeks ago

si je peux me permettre , tu peux remplacer tous tes while(brick)

  while (brick10) 
  {
    gb.display.setColor(ORANGE);
    gb.display.fillRect (brickX + (brickW*3) + 3,brickY + sepaY3,brickW,brickH);

    if (gb.collideRectRect(ballX,ballY,ballSize,ballSize,brickX + (brickW*3) + 3,brickY + sepaY3,brickW,brickH)) {
      brick10 = 0;
      ballSpeedY = -ballSpeedY;
    }
    break;
  }


par des if


  if (brick10 == true) 
  {
    gb.display.setColor(ORANGE);
    gb.display.fillRect (brickX + (brickW*3) + 3,brickY + sepaY3,brickW,brickH);

    if (gb.collideRectRect(ballX,ballY,ballSize,ballSize,brickX + (brickW*3) + 3,brickY + sepaY3,brickW,brickH)) {
      brick10 = false; //Note le boolean <--------------------------- a initialiser boolean brick10 = true;
      ballSpeedY = -ballSpeedY;
    }
  }


ca ne resoud en rien ton probleme de collision mais tu utilisera la bonne syntax au bon endroit


De plus tu devrais regarder du coter des tableau pour tes briques mais ca peu venir dans un deuxieme temps.


its just my two cent  ;) 


You must be logged in in order to post a message on the forum

Log in