Bienvenue, Invité. Merci de vous connecter ou de vous inscrire.
Avez-vous perdu votre e-mail d'activation ?

Auteur Sujet: TileMap Collision (un bug étrange)  (Lu 2255 fois)

0 Membres et 1 Invité sur ce sujet

Animenz

  • Newbie
  • *
  • Messages: 2
    • Voir le profil
TileMap Collision (un bug étrange)
« le: Juillet 09, 2017, 05:07:34 pm »
Bonjour/Bonsoir
Tout d’abord merci d'avance pour votre aide et attention :)

Je n'ai pas trouvé la réponse à mes questions sur internet ou sur ce forum donc je viens poser la question ici.

J'ai conçus une fonction pour tester les collisions entre une TileMap et un RectangleShape et celle-ci fonctionne parfaitement :) enfin presque..

J'ai pris pour parti de récupérer les 4 coins de mon rectangle et de les tester deux par deux pour savoir si il touche un plafond, un sol ou un mur afin de réagir correctement, voici le code :

void Collision::TileCollision(const sf::RectangleShape& rect,const std::vector<std::vector<int>>& v, sf::Vector2f& moveSprite, int numVide)
    {
        int j1 = rect.getPosition().x/32; //coordonné x de la tuile
        int i1 = rect.getPosition().y/32; //coordonné y de la tuile
        int j2 = (rect.getPosition().x + rect.getSize().x -1)/32;
        int i2 = (rect.getPosition().y + rect.getSize().y -1)/32;

        if((v[i1][j1] != numVide) && (v[i1][j2] != numVide))   //mur de gauche(left);
            moveSprite.y++;
        else if((v[i2][j1] != numVide) && (v[i2][j2] != numVide))    //mur de droite(right);
            moveSprite.y--;
        if((v[i1][j1] != numVide) && (v[i2][j1] != numVide))    //plafond(up);
            moveSprite.x++;
        else if((v[i1][j2] != numVide) && (v[i2][j2] != numVide))    //sol(down);
            moveSprite.x--;
    }
Pour l'explication :
rect : est mon rectangle
v : est mon tableau contenant ma map en int
moveSprite : est celui qui enregistre tous les mouvements de mon rect, que je multiplie par une vitesse lors de l'appel de draw()
numVide : est le chiffre qui représente le vide dans mon tableau


Maintenant que la mise en situation est faite, MON PROBLÈME :
Rarement(il me faut au moins une dizaine d'essai à chaque fois) et avec un angle précis, le personnage peut forcer le passage a travers un mur en passant par un coin.

Le fait est que, dans mon test de collision, je n'agis que si 2 coins sont dans un murs.
Malheureusement, Je ne peux pas agir avec un seul coin, car je ne sais pas où renvoyé le rectangle.

Ma question est donc : que dois-je faire d'après vous, pour éviter que le rectangle puisse forcer le passage ?

Merci encore pour votre aide et attention.

Bonne journée :)

Animenz

  • Newbie
  • *
  • Messages: 2
    • Voir le profil
Re: TileMap Collision (un bug étrange)
« Réponse #1 le: Juillet 10, 2017, 08:17:11 am »
re-Bonjour/Bonsoir

J'ai cogité de mon côté afin de trouver une solution et je me suis dis, avec plus de précision(donc plus de point) je devrais pouvoir limiter mon problème au maximum afin de rendre ce bug quasi-inexpoitable.

Et donc décidé de vérifier des points autour des côté de mon rectangle, plutôt que les coins entre eux.

Mon rectangle se déplaçant à une vitesse de 2.5f avec un tour de boucle toutes les 1/60 seconde et une tile de 32 pixel, je ne peux pas aller en dessous des 1/8 sinon, lorsque je rentrerais en contact avec un mur, les points que j'ai choisis autour de mon coin seront tous en contact et ça ne fonctionneras plus.

Malheureusement, ça ne fonctionne tout de même pas, mais je ne comprend pas pourquoi :/
Voici mon code :
        int ux,dx,x1,x2,uy,dy,y1,y2;
        //Coordonnées des quatre coins
        x1 = rect.getPosition().x/32;
        y1 = rect.getPosition().y/32;
        x2 = (rect.getPosition().x + rect.getSize().x -1)/32;
        y2 = (rect.getPosition().y + rect.getSize().y -1)/32;
       //Coordonnées des points choisis
        ux = (rect.getPosition().x + rect.getSize().x*1/8 -1)/32;
        dx = (rect.getPosition().x + rect.getSize().x*7/8 -1)/32;
        uy = (rect.getPosition().y + rect.getSize().y*1/8 -1)/32;
        dy = (rect.getPosition().y + rect.getSize().y*7/8 -1)/32;

        //Bas
        if(((v[y2][x1] != numVide) && (v[y2][ux] != numVide))  
           || ((v[y2][x2] != numVide) && (v[y2][dx] != numVide)))
            moveSprite.y--;
        //Haut
        else if(((v[y1][x1] != numVide) && (v[y1][ux] != numVide))
           || ((v[y1][x2] != numVide) && (v[y1][dx] != numVide)))
            moveSprite.y++;
        //Gauche
        if(((v[y1][x2] != numVide) && (v[uy][x2] != numVide))
           || ((v[y2][x2] != numVide) && (v[dy][x2] != numVide)))
            moveSprite.x++;
        //Droite
        else if(((v[y1][x1] != numVide) && (v[uy][x1] != numVide))
           || ((v[y2][x1] != numVide) && (v[dy][x1] != numVide)))
            moveSprite.x--;
 

Encore une fois, merci d'avance pour votre attention et aide :)

Bonne journée
« Modifié: Juillet 10, 2017, 08:19:52 am par Animenz »

Phanoo

  • Full Member
  • ***
  • Messages: 136
    • Voir le profil
Re: TileMap Collision (un bug étrange)
« Réponse #2 le: Septembre 18, 2017, 10:44:47 am »
Tu as déjà peut etre trouvé la solution vu que ça fait 2mois, mais renseigne toi sur les algos de collision 2D, pour faire un systeme fiable tu peux utiliser l'algo des "axes séparés":

- tu déplace ton perso en X
- tu check les collisions, si il y a collision tu replace le perso contre l'obstacle
- tu déplace ton perso en Y
- tu check les collisions, si il y a collision tu replace le perso contre l'obstacle


En faisant un axe puis l'autre, tu n'aura plus de problème, en plus ton perso pourra 'glisser' contre les murs si tu vas en diagonale, plutot que de se bloquer