Die Logik dahinter ergibt ja auch überhaupt gar keinen Sinn.
Wenn du nach vorne läufst, addierst du 'direction', der kann aber je nach Blickwinkel auch gerne mal schräg nach oben zeigen. Du kannst also offensichtlich schon rumfliegen, wieso solltest du dann noch springen wollen?
Und dann die Abfrage 'if(!position.y > 0.1f)' Du kannst nur springen, wenn du unterhalb von 0.1 bist? Was du damit eigentlich ausdrücken willst, ist wohl, dass du nur springen kannst, wenn du auf dem Boden stehst, der sich vermutlich bei y=0 befindet. Ich könnte mir vorstellen, dass wenn du ein bisschen nach oben guckst, du dich auch nach oben bewegst, und dann oberhalb des Bodens bist.
Dann rufst du aber die Jump-Funktion auf, die nicht erkennt, dass du Springen willst, sondern nur, dass du schon in der Luft schwebst, und dann denkt, sie müsste dich Fallen lassen, wodurch sie dich wieder nach unten beschleunigt, was daraufhin nach der Jump-Funktion direkt wieder abgefangen wird.
Zusammengefasst hast du also nicht nur eine kaputte Jump-Funktion, du hast auch noch eine Flug-Funktion eingebaut, die von der Jump-Funktion kaputt gemacht wird. Einzelne Ideen deiner Implementierung sind ja gut und richtig, aber du hast das eigentliche Problem falsch abstrahiert, wodurch ziemlich alberne Sachen passieren. Und dann versuchst du mit noch mehr Logik, die Symptome zu verhindern, anstatt die Ursache zu beheben.
Also, wie reparieren wir das ganze? Nun, tatsächlich ist es erstaunlich einfach, die Gesetze der Physik zu benutzen: Ein Sprung bedeutet nicht, dass du dich ein Weilchen nach oben bewegst, und dann plötzlich umkehrst und die nach unten bewegst. In der echten Welt gibt es Schwerkraft, und die beschleunigt dich nach unten, solltest du nicht durch den Boden aufgehalten werden. Durch einen Sprung wird dein Körper einfach nur nach oben Beschleunigt, natürlich kann dieser aber nur ausgeführt werden, wenn du am Boden stehst.
Am Anfang stehst du also still am Boden, dein Geschwindigkeitsvektor ist also 0. Springst du, bekommt dieser einen positiven Y Eintrag, und du bewegst dich nach oben, denn Bewegung funktioniert, indem man den Geschwindigkeitsvektor auf den Ortsvektor addiert. Nachdem du aber angefangen hast, dich zu bewegen, bist du in der Luft, also nicht mehr am Boden, also wirkt die Schwerkraft und verringert deinen Geschwindigkeitsvektor. Am Scheitelpunkt des Sprunges ist dieser dann 0, danach kehrt sich das Vorzeichen um und du beschleunigst Richtung Boden. Sobald du ihn erreicht hast, wird dein Geschwindigkeitvektor durch den Boden wieder auf 0 gesetzt.
Das schöne ist, damit kannst du auch Plattformen auf bleiebiger Höhe haben, alles was du benötigst ist ein "istAufBoden"-Test.
Und weil mein Abendessen noch 10 Minuten braucht, kommt jetzt auch noch Pseudocode:
|
C-/C++-Quelltext
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
vec3 Position;
vec3 Geschwindigkeit;
while(Hauptschleife)
{
Position+=Geschwindigkeit;
if(Sprungtaste && AufBoden())//abspringen
{
Geschwindigkeit.y=20;
}
if( ! AufBoden())//Gravitation
{
Geschwindigkeit.y-=0.6;
//Gravitation wirkt immer, unabhängig davon, ob man gesprungen ist. Läuft man
//über eine Kante hinaus fällt man ja auch runter, ohne vorher gesprungen zu sein.
}
else
{
Geschwindigkeit.y=0;
Position.y=0;
//durch das letzte Position+=Geschwindigkeit könnten wir in den Boden gerutscht sein, das
//gleichen wir hier einfach mal aus, notwendig ist dies aber nicht
}
}
AufBoden()
return Position.y<=0;
|
Und das schöne ist: Diese simple Rechnung ergibt eine physikalisch halbwegs korrekt Flugparabel (Effekte wie Reibung sind halt noch nicht berücksichtigt).
Und was auch schön ist: Der Code ist jetzt nicht nur richtig, sondern er ist auch einfacher geworden. Man erlebt es erstaunlich oft, dass gute Abstraktionen sehr einfach und elegant sind.