Charakter, der aufgrund der Schwerkraft vom Boden abprallt

7

Durch die Implementierung der Schwerkraft im Spiel springt der Charakter leicht auf und ab, wenn er auf dem Boden aufschlägt. Beim Debuggen springt der Charakter im Wesentlichen auf und vom Boden. Ich bin mir nicht ganz sicher, wie ich das Problem ausbügeln soll. Jede Hilfe hier wäre sehr dankbar.

Der konstante Wert

private float gravity = 0.09f;

Hinzufügen zur Geschwindigkeit, wenn sich der Charakter auf dem Boden befindet

if (!isOnGround)
 velocity.Y += gravity;

Hinzufügen der Gesamtgeschwindigkeit der Zeichen zur Gesamtposition.

position += velocity * (float)gameTime.ElapsedGameTime.TotalSeconds;

Teil der Kollisionsmethode, die bestimmt, ob sich der Charakter am Boden befindet oder nicht.

for (int y = topTile; y <= bottomTile; ++y)
            {
                for (int x = leftTile; x <= rightTile; ++x)
                {
                    // If this tile is collidable,
                    TileCollision collision = Level.GetCollision(x, y, tileMap);
                    if (collision != TileCollision.Passable)
                    {
                        // Determine collision depth (with direction) and magnitude.
                        Rectangle tileBounds = Level.GetBounds(x, y);
                        Vector2 depth = RectangleExtensions.GetIntersectionDepth(bounds, tileBounds);
                        float elapsed = (float)gameTime.ElapsedGameTime.TotalSeconds;

                        if (depth != Vector2.Zero)
                        {
                            float absDepthX = Math.Abs(depth.X);
                            float absDepthY = Math.Abs(depth.Y);

                            // Resolve the collision along the shallow axis.
                            if (absDepthY <= absDepthX || collision == TileCollision.Platform)
                            {
                                // If we crossed the top of a tile, we are on the ground.
                                if (previousBottom <= tileBounds.Top)
                                    isOnGround = true;
dbomb101
quelle
1
Warum nicht eine vorhandene Physik-Engine verwenden? Farseer braucht ungefähr einen Tag, um sich damit vertraut zu machen, und kann fast alles tun, was Sie überhaupt brauchen.
ClassicThunder

Antworten:

12

Ich fürchte, ich verstehe Ihren Kollisionscode noch nicht vollständig: Wenn irgendwo ein Fehler von einem Pixel auftritt, ist er schwer zu erkennen. Ihr Physikcode benötigt jedoch bereits einige Korrekturen:

  • Geschwindigkeitsaktualisierungen sollten vom Zeitschritt abhängen, auch wenn die Schwerkraft konstant ist
  • Die vertikale Geschwindigkeit sollte am Boden auf Null gesetzt werden
  • Das Hinzufügen der „Gesamtgeschwindigkeit“ ist falsch. Dies ist die Durchschnittsgeschwindigkeit für die Dauer des letzten Frames, die hinzugefügt werden muss. Dieser Artikel sollte erklären, warum .

Führt zu folgendem Code:

Vector2 oldvelocity = velocity;

if (!isOnGround)
    // This will require tweaking the gravity value
    velocity.Y += gravity * (float)gameTime.ElapsedGameTime.TotalSeconds;
else
    velocity.Y = 0.0;

position += 0.5 * (oldvelocity + velocity)
                * (float)gameTime.ElapsedGameTime.TotalSeconds;
Sam Hocevar
quelle
+1 Für die Verwendung der Verlet-Integration gegenüber der Euler-Integration. Ich habe das immer übersehen oder vergessen.
David Gouveia