2017-05-31 3 views
2

Ich benutze zur Zeit box2d Physik-Engine in Java in libgx, und ich habe Probleme mit Kollisionen. Das Problem ist, dass der Körper sich nicht mehr bewegt und ein Kollisionspunkt auf einem flachen Bereich erscheint. Die Art, wie ich arbeite, ist, dass ich mehrere Körper mache, die jeweils einen Block darstellen, und diese Blöcke sind nebeneinander. Blick auf dem Kollisionspunkt hier:Box2D Kollisionsfehler

enter image description here

der Körper soll nicht hier kollidieren für die Y des Körpers Koordinate gleich, und ihre Seite ist auch gleich.

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); 

    } 

Antwort

2

Ich glaube, was Sie erleben eine bekannte Kurz kommt der Box2D Bibliothek ist.

Weitere Informationen zu diesem Problem finden Sie unter What could cause a sudden stop in Box2D?. Siehe Box2D C++ tutorials - Ghost vertices für eine Erklärung, was los ist und was Sie tun, das Problem zu mildern ...

Grundsätzlich verwenden, um eine Kettenform für den Boden wie Textur anstelle von Polygonen (oder über die Polygone), damit Ihr Der bewegliche Block bewegt sich tatsächlich über der Kette. Das setzt voraus, dass die Version der java box2d-Implementierung, die Sie verwenden, über die Kettenform verfügt, die "Ghost Vertices" unterstützt.

unter der Haube Details ...

Während aus der Sicht Kette Formen des Benutzers Glättung sorgen, unter der Haube, es Kantenformen sind, dass die Glättung gewöhnen zu tun. Kantenformen tun dies mit zwei speziellen zusätzlichen Ecken (zusätzlich zu den erwarteten zwei Kanten). Wenn die Bibliothek einen Kontakt zwischen einer Kettenform und einem Polygon (oder einem Kreis) auswertet, identifiziert sie das Segment der Kette, mit dem der Kontakt auftreten könnte. Es übersetzt dann dieses Kettensegment in eine Kante mit seinen zusätzlichen Scheitelpunkten, die auf die benachbarten Scheitelpunkte in der Kette gesetzt sind. Und dann wird der Kontakt zwischen dieser übersetzten Kante und dem Polygon (oder Kreis) ausgewertet. Dies tritt automatisch bei Kettenformen auf und es gibt keine Option in Kettenformen, die verwendet wird, um dieses Verhalten zu erhalten.

Ein Benutzer könnte die gleichen Ergebnisse erzielen wie mit Kettenformen, indem Kantenformen für alle Segmente der Kette zusammengeführt und alle zusätzlichen Ecken der Kanten auf die logisch benachbarten Ecken gesetzt werden. Das verwendet jedoch wesentlich mehr Speicher als die Kettenform und erfordert, dass der Benutzer mehr Code schreiben muss (zumindest für Ketten mit mehr als zwei Eckpunkten).

+0

Ich werde das heute Abend versuchen und zu dir zurückkommen. Obwohl, würde das immer noch funktionieren, wenn ich den box2d Körper als ein Polygon behalten würde, aber dieses Polygon mit einer Kettenform machte? – Liwaa

+0

@Liwaa Kettenform ist für beliebige nicht feste Formen gedacht. Auch die Ketten- (und Kanten-) Formen sollen nicht für dynamische Körper verwendet werden. Wenn Sie C++ (statt Java) verwenden, können Sie [my fork von Box2D] (https://github.com/louis-langholtz/Box2D) ausprobieren, das dynamische Ketten- und Kantenformen und Polygone unterstützt, die über Polygone gleiten. Mein Fork wird jedoch nicht nach Java portiert. Es nützt dir also nichts. Übrigens habe ich [eine Beschreibung dieses Problems und wie ich es in meiner Gabel gelöst habe] (https://github.com/louis-langholtz/Box2D/blob/dev/Documentation/CollisionHandlng.md), wenn jemand interessiert ist . –

+0

@LousLangholtz es geschafft, mit der Kettenform perfekt zu arbeiten, hatte ich zuerst Probleme mit der Kettenform, dann haben sie es geschafft zu arbeiten. Vielen Dank! – Liwaa

2

Obwohl Louis Langholtz ist die Antwort schon gut, ich habe mehr hinzuzufügen.

Kette oder Geist Eckpunkte werden in der Regel Ansätze empfohlen, aber: -

  • Es ist schwierig, in der Praxis zu verwenden.
  • Es erfordert Coder, diese Kanten/Ecken manuell zu verbinden.
    (langweilig in einigen Szenario)

Ich empfehle Anfasen die Box stattdessen: -

enter image description here

ich getestet habe (jbox2d) - es deutlich den Effekt aus der Glitch reduzieren.
Der Nachteil dieses Ansatzes ist, dass er zusätzliche Eckpunkte benötigt.
(z.B. 4 Scheitelpunkte -> 8 Scheitelpunkte)

Daher erfordert es mehr Rechenleistung.

daher in Praktiken, teile ich generell alle Körper in 2 Gruppen: -

  • OK Glitch (zB Schmutz) -> nicht ändern (billig)
  • Kann nicht Glitch haben (zB character) - obwohl> Verwendung Anfasen Ansatz (teurer)

ich persönlich hoffe, es ist eine einfache Möglichkeit, Kette/Geist als Louis Langholtz empfehlen, zu verwenden.

+0

ich verstehe, dass ich die kanten des polygons gekrümmt machen sollte? Wie kann ich das mit Polygonform machen? @javaLover – Liwaa

+0

@Liwaa Ja. Es ist nicht besonders schwer. Vielleicht brauchen Sie etwas Zeit, um darüber nachzudenken. Hier sind einige ähnliche Dinge, die dir vielleicht ein paar grobe Ideen geben können. https://www.youtube.com/watch?v=3qMNuoTHNHs und http://doc.cgal.org/latest/Straight_skeleton_2/index.html – javaLover

+0

Danke für die Hilfe, ich schätze es :) – Liwaa