2016-04-13 6 views
3

Nur um diese Frage vorzufüh- ren, bitte beachten Sie, dass ich nicht nach "fix my code" frage, sondern welche Techniken ich anwenden würde, um dieses Problem zu beheben. Ich entschuldige mich auch, wenn meine Schreibweise nicht sehr gut ist.2D C++ Kollisionserkennung fast perfekt, aber nicht ganz?

Okay, also ich habe ein 2D-Platformer-Spiel, das die Position des Spielers mit allen Kacheln (in einer Schleife) vergleicht, löst die Kollision entsprechend auf. Das ist so ziemlich die Struktur des Hauptspiels Schleife:

  1. Überprüfen Sie alle Kollisionen (und Springen aktivieren, wenn eine Kollision Gebrüll der Spieler aufgetreten)
  2. Holen Eingang und Spieler Änderungsgeschwindigkeit entsprechend
  3. hinzufügen Schwerkraft die Y-Geschwindigkeit
  4. Nehmen Geschwindigkeit und Reibung auf die Position Spieler
  5. zeichnen Sie das Spiel
  6. wiederholen

Aber trotz dieser Systemarbeit gibt es zwei kleinere, aber auffällige Probleme mit dem Kollisionssystem (ich habe Bilder zur Verfügung gestellt, um es einfacher zu machen). Es gibt zwei Probleme, die erste ist nicht so schlimm, aber die zweite Renderer das Spiel fast unspielbar!

Problem 1. Wenn man sich im Spiel nur nach links und rechts über den Boden bewegt, verliert der Spieler gelegentlich die gesamte Geschwindigkeit, die er gewonnen hat, und muss diese Geschwindigkeit dann wieder akkumulieren. Ich denke, das ist, weil meine Kollisionserkennungsfunktion hin und wieder nicht korrekt zurückkehrt. Hier ist ein Bild:

The prblem that is occuring

Ich hoffe, das war klar, das Problem wird erst wirklich deutlich, wenn über viele flache Land zu bewegen.

Problem 2 (Das ist viel schlimmer) Das Problem ist, dass der Spieler im Wesentlichen Wände hochspringen kann, denn wenn Sie zum Beispiel den linken Pfeil halten und den Sprung halten, springt der Spieler die Mauer hoch. Ich gehe davon aus, dass dies der Fall ist, weil Meine Kollisionserkennungsfunktion wahr zurückgibt, wenn die Kollision von der Seite kommt (obwohl dies nicht der Fall ist). Hier ist ein weiteres Bild (der Text ist klein, sorry): Edge collision bug

So, hier ist meine Kollisionserkennungsfunktion, die in zwei ‚Objekten‘ kehrt dann die Richtung von dem ersten Objekt, an das nehmen soll die Kollision aufgetreten ist, ich denke, das Problem hervorruft, wenn es um die Bestimmung der Richtung, wie dies kommt Probleme verursacht, wie oben gezeigt:

//Find the collision vectors 
     float vectorX = (a.Position.x + (a.Scale.x/2)) - (b.Position.x + (b.Scale.x/2)); 
     float vectorY = (a.Position.y + (a.Scale.y/2)) - (b.Position.y + (b.Scale.y/2)); 

     //Find the distance between the two objects 
     float deltaWidth = (a.Scale.x/2) + (b.Scale.x/2); 
     float deltaHeight = (a.Scale.y/2) + (b.Scale.y/2); 

     //Stores the direction of collision 
     Direction collisionDir = Direction::None; 

     //Check if the two objects are intersecting on the x and y axis 
     if (fabs(vectorX) < deltaWidth && fabs(vectorY) < deltaHeight) 
     { 
      //The direction of collision 
      float directionX = deltaWidth - fabs(vectorX); 
      float directionY = deltaHeight - fabs(vectorY); 

      //Check for vertical collision 
      if (directionX >= directionY) 
      { 
       //Check for collisions from the top 
       if (vectorY > 0) 
       { 
        a.Velocity.y = 0; 
        a.Position.y += directionY; 
        collisionDir = Direction::Up; 
       } 

       //Collisions form the botttom 
       else 
       { 
        a.Velocity.y = 0; 
        a.Position.y -= directionY; 
        collisionDir = Direction::Down; 
       } 
      } 

      else if (directionX < directionY/2) 
      { 
       //Check for collisions from the left 
       if (vectorX > 0) 
       { 
        a.Velocity.x = 0; 
        a.Position.x += directionX; 
        collisionDir = Direction::Left; 
       } 

       //Collisions form the right side 
       else 
       { 
        a.Velocity.x = 0; 
        a.Position.x -= directionX; 
        collisionDir = Direction::Right; 
       } 
      } 
     } 

     //Return the direction. 
     return collisionDir; 

diese eine Richtung zurück, überprüft Mein anderer Code auch wenn die Richtung == Bottom, dann wird es ermöglichen, Springen.

Vielen Dank für jede Hilfe. Ich übe für Ludum Dare, weil ich plane (wahrscheinlich) einen Jump'n'Run zu machen. Wenn ich keine Kollisionserkennung finde, weiß ich nicht, wie gut mein Spiel sein wird.

Wie dem auch sei Dank - Coder Cameron

+1

Fügen Sie Ihrem Spiel Protokollierung hinzu, die alle Daten zur Kollisionserkennung schreibt. Auf diese Weise werden Sie in der Lage sein, die Bedingungen zu finden, wo es sich falsch verhält. –

Antwort

3

Das erste, was ich empfehlen würde, ist selbst eine Vector2D Klasse zu machen, die einige Betreiber Ihre x- und y-Koordinaten und ein paar Überlast gilt für die Addition und Subtraktion von zwei Vector2Ds und Multiplikation und Division zu ermöglichen durch Ints, Floats und Doubles.Vertrauen Sie mir, es wird Ihr Leben viel einfacher machen, da Sie alle Ihre Kräfte und Kollisionspunkte halten können.

Weiter, wenn ich den Stil der Kollision verwendet haben Sie derzeit verwenden Ich habe immer gefunden, dass es:

A) Schwerer zu debuggen.

B) Schwieriger für andere Leute, Ihrem Code zu folgen.

Also würde ich empfehlen, eine Rectangle2D-Klasse zu erstellen, die Kollisionen mit anderen Rechtecken und anderen erforderlichen Funktionen behandelt.

Als eine Empfehlung haben Sie die obere linke Ecke und die untere rechte Ecke als Vektor von der Mitte des Rechtecks, was Skalierung und Kollisionserkennung viel einfacher macht. Dies bedeutet auch, dass Sie die anderen Ecken ableiten können, ohne sie direkt speichern zu müssen.

Hier ist ein Codebeispiel, das wahrscheinlich helfen, was ich versuche zu erklären:

bool Intersects(Rectangle2D other) 
{ 
    //Checks the right, left, bottom then top of the rectangle 
    //against the other. 
    if(other.topLeftCorner.x >= bottomRightCorner.x  //Checks the right 
     || other.bottomRightCorner.x <= topLeftCorner.x //Checks the left 
     || other.topLeftCorner.y >= bottomRightCorner.y //Checks the bottom 
     || other.bottomRightCorner.y <= topLeftCorner.y) //Checks the top 
     return false; 
    else 
     return true; 
} 

Sie können diesen Code manipulieren Sie die Richtung der Kollision zu geben. Hoffe das hilft.

Verwandte Themen