Wie Jimmy sagte, passt eine Ellipse wahrscheinlich besser zu dieser Bewegung. Hier sind einige Ideen, wie Sie es tatsächlich mit etwas mehr Details für Interessierte implementieren können.
Zeit nehmen
Für den Anfang benötigen Sie eine Variable, um die Zeit in der Spielwelt zu verfolgen. Sie können es beliebig implementieren, aber hier ist ein Beispiel. Ich werde eine Variable namens verwenden hours
, die von 0 bis 24 variiert (obwohl sie bei Erreichen von 24 wieder auf 0 zurückgesetzt wird).
Im Gegensatz zum wirklichen Leben werde ich nur bedenken, dass der Tag um 0 Uhr und die Nacht um 12 Uhr beginnt. Dies erleichtert einige Berechnungen.
Ich werde auch die Geschwindigkeit definieren, mit der sich die Spielzeit im Verhältnis zur Echtzeit ändert. In diesem Beispiel entspricht alle zwei Minuten Echtzeit einer Stunde im Spiel.
float hours = 0.0f; // From 0 to 24 wrapping around
const float HoursPerSecond = 1f / 120f; // E.g. 2 minutes = 1 hour ingame
public void Update(float elapsed)
{
hours += elapsed * HoursPerSecond; // Advance clock
if(hours >= 24f) hours -= 24f; // Wrap around 24 hours
}
Aufbau
Bevor wir die Bewegung unserer Sonne untergehen, müssen wir einige ihrer Parameter angeben. Insbesondere bei welchem X-Wert steigt es vom Horizont an und bei welchem X-Wert fällt es in den Horizont. Außerdem, was Y dem Horizont entspricht und wie hoch er sich über diese Linie erheben soll.
float startX = 0;
float endX = 1000;
float horizonY = worldHeight/2;
float amplitudeY = 200;
Berechnung der Sonnenkoordinaten
Jetzt ist es Zeit, den Sonnenstand für eine bestimmte Tageszeit zu berechnen. Ich werde dieselbe parametrische Funktion verwenden, die auch von Jimmy verwendet wird, jedoch mit einer Domäne zwischen [0..2PI] (um die Sonne bei Tagesanbruch wieder in ihre ursprüngliche Position zu bringen):
x = (1-cos (t)) / 2
y = sin (t)
Dies ist eine gute Funktion, da der X-Wert von 0 bis 1 und dann wieder zurück auf 0 variiert (was wir den X- und End-X-Werten unserer Sonne zuordnen werden) und der Y-Wert bei 0 beginnt und sich auf 1 und zurück bewegt wieder auf 0 (die unsere sein würde Tag Teil) und wiederholt dann die genau die gleiche Sache auf der negativen Seite , bevor sie wieder in die ursprüngliche Position kommt (was unser wäre Nacht , obwohl die Sonne an diesem Punkt nicht gezogen wird).
Der erste Schritt besteht darin, die Stunden vom Bereich [0..24) auf den Bereich unserer Funktion zu skalieren, der [0..2PI) ist:
float t = (hours / 24f) * MathHelper.TwoPi; // Scale: [0..24) to [0..2PI)
Als nächstes wenden wir die Funktionen an, um die Werte zwischen 0 und 1 zurückzugewinnen, die ich oben erwähnt habe:
float horizontal = (float)((1-Math.Cos(t)) / 2f); // Changes: 0 1 0
float vertical = (float)(Math.Sin(t)); // Changes: 0 1 0 -1 0
Und schließlich skalieren wir diese Werte anhand der Parameter der Sonne:
float sunX = startX + (endX - startX) * horizontal; // From startX to endX and back
float sunY = horizonY + amplitydeY * vertical; // Up and down around horizonY