2017-05-31 1 views
2

J'utilise actuellement le moteur physique box2d dans java dans libgx, et je suis confronté à des problèmes de collision. Le problème est que le corps cesse de bouger et qu'un point de collision apparaît sur une surface plane. La façon dont je travaille est que je fais plusieurs corps, chacun représentant un bloc, et ces blocs sont côte à côte. Regardez le point de collision ici:Erreur de collision Box2D

enter image description here

le corps ne doit pas entrer en collision ici pour la coordonnée Y des corps est égal, et de leur côté est égal aussi bien.

float PPM = 100; 
float side = 45; 
    for (float i = start; i < end; i++) { 
     /** 
     * perlin noise for terrain 
     */ 
     def.type = BodyDef.BodyType.StaticBody; 
     float place = Maths.map(noise.noise(off, off), 0, 1, -10, 50); 
     if (place < 10) { 
      place = 0; 
     } else if (place < 20) { 
      place = side; 
     } else if (place < 30) { 
      place = side * 2; 
     } else if (place < 40) { 
      place = side * 3; 
     } else if (place <= 50) { 
      place = side * 4; 
     } 


     place += side/2; 

     float posx = (i * side); 
     float posy = place; 
     float size = side/2f; 
     def.position.set(posx/PPM, posy/PPM); 
     b = world.createBody(def); 
     shape.setAsBox(size/PPM, size/PPM); 
     fdef.shape = shape; 
     fdef.isSensor = false; 
     b.createFixture(fdef); 
     off += 0.01; 
     toSetLast = posx + side; 

     GrassBlock grass = new GrassBlock(b, new 
     Vector2(b.getPosition().x * PPM, b.getPosition().y * PPM)); 
     //dirt under grass 
     for (float j = (place/side) - 1; j >= -1; j--) { 
      posy = j * side; 

      def.position.set(posx/PPM, posy/PPM); 
      b = world.createBody(def); 
      shape.setAsBox(size/PPM, size/PPM); 
      fdef.isSensor = false; 
      fdef.shape = shape; 
      b.createFixture(fdef); 
      DirtBlock dirt = new DirtBlock(b, new 
      Vector2(b.getPosition().x * PPM, b.getPosition().y * PPM)); 
      addBlock(dirt.getLocation(), dirt); 
     } 
     addBlock(grass.getLocation(), grass); 

    } 

Répondre

2

Je crois que ce que vous rencontrez est un court connu venant de la bibliothèque Box2D.

Voir What could cause a sudden stop in Box2D? pour une autre description de ce problème. Voir Box2D C++ tutorials - Ghost vertices pour une explication de ce qui se passe et ce que vous pouvez faire pour atténuer le problème ...

Fondamentalement, utiliser une chaîne en forme pour la texture sol comme au lieu de polygones (ou sur les polygones) de sorte que votre Le bloc mobile se déplace réellement sur le dessus de la chaîne. Cela suppose que la version de l'implémentation de java box2d que vous utilisez possède la forme de chaîne qui fournit le support des "vertices fantômes".

Sous les détails du capot ...

Alors que les formes de la chaîne en perspective de l'utilisateur fournissent le lissage, sous le capot, il est des formes de pointe qui se servent à faire le lissage. Les formes de bord le font avec deux sommets spéciaux supplémentaires (en plus des deux attendus d'un bord). Lorsque la bibliothèque évalue un contact entre une forme de chaîne et un polygone (ou un cercle), elle le fait en identifiant le segment de la chaîne avec lequel le contact pourrait se produire. Il traduit ensuite ce segment de chaîne en un bord avec ses sommets supplémentaires définis sur les sommets adjacents de la chaîne. Et ensuite le contact est évalué entre ce bord traduit et le polygone (ou cercle). Cela se produit automatiquement avec les formes de chaîne et aucune option dans les formes de chaîne n'est utilisée pour obtenir ce comportement.

Un utilisateur peut obtenir les mêmes résultats qu'avec les formes de chaîne en assemblant des formes de bord pour tous les segments de la chaîne et en définissant tous les sommets supplémentaires des arêtes aux sommets logiquement adjacents. Cela utilise cependant beaucoup plus de mémoire que la forme de la chaîne et demande à l'utilisateur d'écrire plus de code à faire (au moins pour les chaînes ayant plus de deux sommets).

+0

Je vais essayer ce soir, et je reviendrai à vous. Bien, cela fonctionnerait-il encore si je gardais le corps de box2d en tant que polygone, mais ai fait ce polygone avec un chainhape? – Liwaa

+0

@Liwaa La forme de la chaîne est destinée aux formes arbitraires non solides. De plus, les formes de chaîne (et de bord) ne sont pas destinées à être utilisées pour des corps dynamiques. Si vous utilisiez C++ (au lieu de Java), vous pouvez essayer [ma fourche de Box2D] (https://github.com/louis-langholtz/Box2D) qui supporte les formes dynamiques de chaînes et de bords et les polygones qui glissent sur des polygones. Cependant, ma fourche n'est pas portée vers Java. Donc, cela ne vous sert à rien. Incidemment, j'ai [une description de ce problème de collage et comment je l'ai résolu dans ma fourche] (https://github.com/louis-langholtz/Box2D/blob/dev/Documentation/CollisionHandlng.md) si quelqu'un est intéressé . –

+0

@LousLangholtz il a réussi à travailler avec la forme de la chaîne parfaite, j'ai d'abord eu des problèmes avec la forme de la chaîne, puis ils ont réussi à travailler. Merci! – Liwaa

2

Bien que Louis Langholtz la réponse est déjà bonne, j'ai plus à ajouter.

sommets de la chaîne ou fantômes sont généralement des approches recommandées, mais: -

  • Il est difficile d'utiliser dans la pratique.
  • Il faut un codeur pour assembler manuellement ces bords/coins.
    (fastidieux dans un scénario)

Je recommande biseautage la boîte à la place: -

enter image description here

J'ai testé (jbox2d) - il peut réduire l'effet du Glitch de manière significative.
L'inconvénient de cette approche est qu'elle nécessite des sommets supplémentaires.
(par exemple 4 sommets -> 8 sommets)

Ainsi, il nécessite plus de puissance de calcul.

Par conséquent, dans les pratiques, je divise généralement tous les corps en 2 groupes: -

  • OK pour avoir Glitch (par exemple les débris) -> ne modifiez pas (pas cher)
  • ne peut pas avoir Glitch (par exemple, caractère) -> utilisation biseautage approche (plus cher)

Personnellement, je l'espère, il est un moyen facile d'utiliser la chaîne/fantôme comme Louis Langholtz recommande, cependant.

+0

Je comprends que je devrais rendre les bords incurvés du polygone? comment puis-je faire cela avec la forme de polygone? @javaLover – Liwaa

+0

@Liwaa Oui. Ce n'est pas particulièrement difficile. Vous aurez peut-être besoin de temps pour y réfléchir. Voici quelques trucs similaires qui peuvent vous donner quelques idées approximatives. https://www.youtube.com/watch?v=3qMNuoTHNHs et http://doc.cgal.org/latest/Straight_skeleton_2/index.html – javaLover

+0

Merci pour toute l'aide, j'apprécie :) – Liwaa