Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

1

02.01.2015, 13:39

Hilfe für Jump n Run Spiel

Ich arbeite mich zu Zeit in die Spielprogrammierung ein und hänge gerade etwas an einer Sache fest.
Es soll letztendlich ein Jump n Run sein ähnlich wie Super Mario o.ä.
PlayerSprites, MapSprites sowie Background sind alle vorhanden und verhalten sich wie ich es wünsche.
Kollisionsabfrage zwischen Player und Map funktioniert, allerdings nicht ganz wie ich es gerne hätte.
Mein Problem liegt beim Springen bzw der Landung eines Sprungs. Es kommt immer wieder vor, dass der Player kurz vorm Boden stehen bleibt und dann quasi "schwebt".

Springen tue ich folgendermaßen:

if (!Jumped && KS.IsKeyDown(Keys.Up))
{
Jumped = true;
JumpHeight = JumpG;
}

if (Jumped && !Game1.Collision(new Vector2(PlayerPosition.X, PlayerPosition.Y - JumpHeight + Speed)))
{
PlayerPosition = new Vector2(PlayerPosition.X, PlayerPosition.Y - JumpHeight);
JumpHeight--;
}
else
Jumped = false;

(Habe gerade auch kleine Probleme die Formatierung für C#-Codes zu nutzen. Bekomme es nur vollkommen ohne Formatierung hin wenn ich das nutzen will. Daher der Code einfach so geschrieben)


Mir ist schon klar das es daran liegt, weil ich die JumpHeight dekrementiere und dadurch krumme Werte für die Y-Koordinate bekomme.
Allerdings fehlt mir der Ansatz wie ich das Problem umgehe. ?(

Rein theoretisch könnte ich den Player ja um Komplette Blöcke laufen lasse und das Problem so lösen, weil ich dann ja keine Zwischenschritte mehr habe. Finde ich aber nicht so ansehnlich.

Wie gesagt, ich arbeite mich gerade erst rein und stehe noch recht weit am Anfang.
Hoffe das es nicht ganz so sehr in den Augen bei euch weh tut wenn ihr das seht :P

LInsoDeTeh

Treue Seele

Beiträge: 372

Wohnort: Essen, Deutschland

Beruf: Team Lead Inhouse-Entwicklung

  • Private Nachricht senden

2

02.01.2015, 18:22

Ich glaube, dein Denkfehler liegt im zweiten if.
Du prüfst eine Kollision mit dem Boden über den Abstand "Y - Height + Speed", reduzierst innerhalb des Anweisungsblocks aber auf "Y - Height".
Die beiden Abstände müssen übereinstimmen, sonst bekommst du eben genau dieses Schweben.
Der zweite Fehler ist das Setzen deines Positionsvektors. Du veränderst mit JumpHeight nicht die Höhe des Spielers, sondern das Delta. Und da du das dann immer deinem Y der PlayerPosition zuordnest, bekommst du einen Mischmasch und keine absolute Position, da du keine Information mehr über den originalen Y-Wert behältst.

Probier das mal so:


int originalPlayerHeight = 0;

if (!Jumped && KS.IsKeyDown(Keys.Up))
{
Jumped = true;
JumpHeight = JumpG;
originalPlayerHeight = PlayerPosition.Y;
}

if (Jumped && !Game1.Collision(new Vector2(PlayerPosition.X, originalPlayerHeight + JumpHeight)))
{
PlayerPosition = new Vector2(PlayerPosition.X, originalPlayerHeight + JumpHeight);
JumpHeight--;
}
else
Jumped = false;

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »LInsoDeTeh« (02.01.2015, 18:29)


3

02.01.2015, 18:56

Also funktionieren tut es.
Ist jetzt nur suboptimal, da sich der Player nun vom Boden in die Luft "teleportiert".
Hinzu kommt, dass der Player nun richtig langsam vom Himmel Richtung Boden fällt, da ja nur noch Pixel für Pixel abgearbeitet wird.
Habe soweit verstanden was gemeint war, allerdings bringt mich das gerade noch nicht auf einen besseren Lösungsansatz.

Bin schon ewig lange im Netz am suchen, aber so recht werde ich nicht fündig. Bei den Tutorials handelt es sich meistens um Sprünge, die immer wieder darauf hinaus laufen, dass der Spieler an seiner Urspungshöhe landet. Also fehlt dabei die Berücksichtigung von Blöcken.

Weitere Vorschläge vllt?

LInsoDeTeh

Treue Seele

Beiträge: 372

Wohnort: Essen, Deutschland

Beruf: Team Lead Inhouse-Entwicklung

  • Private Nachricht senden

4

02.01.2015, 19:08

OK du könntest noch eine Variable einführen, die festlegt, ob der Spieler gerade nach oben fliegt (Start des Sprungs) oder nach unten (Ende des Sprungs) und dann JumpHeight entsprechend inkrementieren oder dekrementieren.

Schöner wäre eigtl. fast noch eine Funktion (z.B. -x^2+1, multipliziert mit deiner maximalen Sprunghöhe JumpG) zu verwenden, die die Sprunghöhe abhängig von der Zeit angibt und nicht mehr JumpHeight zu incrementieren/decrementieren, sondern eine JumpDuration (die dann in der oben gewählten Funktion von -1 bis 1 läuft. Damit könntest du später auch die Funktion austauschen und somit andere Sprungkurven hinbekommen.

Sowas in der Art (nicht getesteter Pseudocode):
Die Sprunggeschwindigkeit kannst du dann modifizieren, jenachdem, wie stark du jumpDuration inkrementierst (in meinem Beispiel + 0.1f)


int originalPlayerHeight = 0;

private float JumpHeightFunction(float jumpDuration) {
return -JumpG * (Math.Pow(jumpDuration, 2) + 1);
}

[...]

if (!Jumped && KS.IsKeyDown(Keys.Up))
{
Jumped = true;
jumpDuration = -1.0f;
originalPlayerHeight = PlayerPosition.Y;
}

float jumpHeight = JumpHeightFunction(jumpDuration);
if (Jumped && jumpDuration <= 1.0f && !Game1.Collision(new Vector2(PlayerPosition.X, originalPlayerHeight + jumpHeight)))
{
PlayerPosition = new Vector2(PlayerPosition.X, originalPlayerHeight + jumpHeight);
jumpDuration += 0.1f;
}
else
Jumped = false;

5

02.01.2015, 19:43

Orientiere dich doch einfach an der 'realen' Physik. Dein Spieler (sowie jedes andere Objekt auch) hat eine Position und Geschwindigkeit.
In jedem Frames wird die Geschwindigkeit zur Position und die globale Gravitation von der Geschwindigkeit (evtl vorher mit der Frametime multiplizieren, damit sich das ganze auch konstant bewegt). Wenn du den Spieler nun springen lassen willst, setzt du seine y-Geschwindigkeit auf einen bestimmten Wert. Den Rest macht die Gravitation. (Genauso machst du es auch, wenn du ihn seitwärts bewegen willst).
So hast du einen hübschen springenden Spieler ;)

6

03.01.2015, 14:00

Mir ist da über Nacht doch eine wesentlich einfachere Lösung in den Kopf geschossen.
Es Ist doch Sinnvoller die Kollisionen nicht während eines Sprungs abzufragen sondern permanent. Sobald dann ein Block von oben bzw unten kollidiert wird der Spieler einfach direkt auf bzw unter den Block gestellt.

So habe ich auf jeden Fall keine Probleme mehr und die Abständer der Blöcke sowie die Bewegungsgeschwindigkeit können variieren.

Danke trotzdem für eure Hilfe.

Werbeanzeige