Ich arbeite gerade an einem 2d Platformer mit Monogame. Ich kann ein Sprite zeichnen, ich kann einen Charakter und ein Level zeichnen, ich kann den Charakter bewegen und springen, aber wenn ich hüpfe, "schwebt" mein Charakter über dem Level Block, anstatt darauf zu landen. Die linken und rechten Kollisionen funktionieren gut, der Charakter wird angehalten, wenn er gestoppt werden sollte, aber wenn er springt, landet er nicht richtig. Ich habe folgenden Code:C# Monogame: "Floating" Sprite nach dem Sprung
Um zu überprüfen, ob der Spieler springen möchte, wird überprüft, ob der Pfeil nach oben gedrückt wird.
if(state.IsKeyDown(Keys.Up) && hasJumped == false)
{
jumping = true;
}
Nach der Prüfung für das keypress getan wird, gibt es eine Überprüfung, ob die jumping
Variable wahr ist
if (jumping == true)
{
jump();
} else if (falling == true && topOfBlock == false)
{
fall();
}
else
{
hasJumped = false;
verticalMovement = 14;
}
Grundsätzlich jumping
prüft, ob Sie springen wollen, falling
prüft, ob der Charakter fällt topOfBlock
prüft, ob sich das Zeichen oben auf einem Block befindet, hasJumped
prüft, ob gerade ein Sprung ausgeführt wird (also kein Doppelsprung möglich ist) und verticalMovement
ist die Anzahl der Pixel, um die der Charakter pro Tick springt/fällt.
Die jump()
und fall()
Methode wie folgt aussehen:
private void jump()
{
if (verticalMovement >= 0)
{
position.Y -= verticalMovement;
verticalMovement--;
} else
{
jumping = false;
hasJumped = true;
falling = true;
}
}
public void fall()
{
position.Y += verticalMovement;
verticalMovement++;
}
Der Code für sich selbst spricht, denke ich. Wenn sich das Zeichen nicht mehr nach oben bewegt, wird falling
auf true
gesetzt, wodurch die Methode fall()
ausgelöst wird, solange sich das Zeichen nicht auf einem Block befindet.
Schließlich wird das Kollisionsrechteck des Charakters auf die neue Position des Charakters aktualisiert.
colRect = new Rectangle((int)position.X, (int)position.Y, 64, 48);
Wo position.X
position.Y
und der X-Charakter sind und Y-Position und 64
48
und die Breite des Sprites und Höhe.
Um zu überprüfen, ob die Kollision Rechteck mit dem Kollisions Rechteck eines Blocks schneidet ich den folgenden Code
private void checkCollision()
{
bool topCol = false;
for (int x = 0; x < blockTileArray.GetLength(0); x++)
{
for (int y = 0; y < blockTileArray.GetLength(1); y++)
{
if (blockTileArray[x, y] != null)
{
if (hero.colRect.Intersects(blockTileArray[x, y].topWall))
{
topCol = true;
}
}
}
}
if(topCol == true)
{
hero.topOfBlock = true;
} else
{
hero.topOfBlock = false;
}
}
topCol
ist ein Bool, die mit der Oberseite des Blocks eine Kollision gibt es oder nicht überprüft, ob. Die Schleifen prüfen für jeden Block im Array, ob das Zeichen sich mit topWall
überschneidet oder nicht. Wenn ja, setzt es topCol
auf wahr. Nach der Schleife prüft es, ob topCol
wahr ist oder nicht. Wenn es so ist, heißt es hero.topOfBlock
bis true
, was bedeutet, dass der Charakter nicht fallen sollte. Wenn es false
ist, setzt es hero.topOfBlock
zu false
, die die fall()
Methode in der Klasse Hero auslösen würde, solange jumping
falsch ist.
schließlich das topWall
Kollisions Rechteck erzeugt wird, wie folgt:
topWall = new Rectangle((int)position.X, (int)position.Y - size, size, 1);
position.X
und position.Y
sind die X- und Y-Positionen, size
ist die Breite und Höhe des Blocks (beide sind 30, wie es ein Quadrat) , die 1 soll es nur 1 Pixel hoch machen.
Nun wie gesagt, das Problem ist, dass der Charakter nach dem Springen schwebt. Die Start-Y-Position ist 402 Pixel (wobei der erste Block topWall.Y
420 ist, was bedeutet, dass das Zeichen oben auf dem Block steht, wenn das Spiel geladen wird), nach dem Springen sollte es zurück zu 402 gehen. Jedoch; nach einmaligem Sprung geht es zu 374, dann 373, dann 387, 386, ..., 374, 373, zurück zu 387 und so weiter. Ich habe keine Ahnung, was das Problem verursacht. Ich habe mehrere Dinge ausprobiert, zum Beispiel mit den Kollisionsrechtecken des Blocks und des Charakters zu basteln, aber nichts scheint zu funktionieren. Wenn ich die - size
von (int)position.Y - size
in topWall = new Rectangle()
(die ich dachte, wäre das Problem) entfernen, fällt das Zeichen durch den Block, so dass es auch nicht beheben.
Nur ein bisschen klarer zu machen, was ich meine, hier sind zwei Bilder:
Sie haben 'position.Y - = verticalMovement;' zum Springen? Sollte es beim Springen nicht hinzugefügt und beim Fallen subtrahiert werden? Mit welchem Wert wird Ihre 'verticalMovement' initialisiert? – AsheraH
Nein, je höher der Y-Wert, desto niedriger wird das Sprite platziert. Wenn Sie also springen wollen, müssen Sie den Y-Wert verringern, also das '- =' anstelle von '+ ='. – lolwut147258369
@AsheraH Die Position 0,0 befindet sich in den meisten Fällen oben links in der Programmierung, sowohl für XNA als auch für Winforms, HTML ect. – Steven