Funzione per il movimento del sole?


9

Quindi, dato uno sprite del sole impostato all'orizzonte (x = 0, y = worldheight / 2) Sto cercando di escogitare una funzione per far sorgere il sole e poi calare.

Il modo migliore per farlo sarebbe la funzione peccato, ma non ho idea di come usarla.

se si utilizza y = sin (x), allora x dovrebbe variare tra 0 e pi per una curva completa, pur avendo una velocità costante per X.

Qualche idea o suggerimento?

Modifica: grazie ragazzi!

Sun funziona!

Risposte:


7

Per quanto riguarda il problema da 0 a pi, in generale tutto ciò che devi fare è ridimensionare la X di un moltiplicatore. Esempio:

y = sin(x * pi / worldWidth)

http://www.wolframalpha.com/input/?i=Plot%5BSin%5Bx%5D%2C+%7Bx%2C+0%2C+Pi%7D%5D

Tuttavia, questo non ottiene abbastanza la curva che probabilmente stai cercando. È necessario utilizzare il modulo parametrico:

t = 0 -> pi over the course of a day
y = sin(t)   -> goes from 0 up to 1 at noon, then down to 0 again
x = (1-cos(t))/2 -> starts at 0 goes up to 1 by sundown.

http://www.wolframalpha.com/input/?i=ParametricPlot%5B%7B1+-+Cos%5Bt%5D%2C+Sin%5Bt%5D%7D%2C+%7Bt%2C+0%2C+Pi% 7D% 5D

Questa combinazione di peccato per Y e cos per X traccerà un'ellisse.


Grazie, è fantastico. Non sono molto incentrato sulla matematica. Le mie abilità in matematica sono praticamente solo calcoli rudimentali.
Ross,

12

Come Jimmy ha detto che un'ellisse è probabilmente una misura migliore per questo movimento. Ecco alcune idee su come implementarlo effettivamente con un po 'più di dettaglio per gli interessati.

Prendere tempo

Per cominciare, hai bisogno di una variabile per tenere traccia del tempo nel mondo di gioco. Puoi implementarlo come preferisci, ma ecco un esempio. Userò una variabile chiamata hoursche varia da 0 a 24 (anche se quando raggiunge i 24 torna a 0).

A differenza della vita reale, però, prenderò in considerazione quel giorno che inizia a 0 ore e la notte inizia a 12 ore. Ciò renderà alcuni dei calcoli più facili.

Definirò anche la velocità con cui il tempo di gioco cambia rispetto al tempo reale. In questo esempio, ogni due minuti di tempo reale corrisponderanno a un'ora di gioco.

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
}

Configurazione

Ora, prima di impostare il movimento del nostro sole, dobbiamo specificare alcuni dei suoi parametri. In particolare, a quale valore X si alza dall'orizzonte ea quale valore X cade nell'orizzonte. Inoltre, ciò che Y corrisponde all'orizzonte e quanto in alto dovrebbe salire sopra quella linea.

float startX = 0;
float endX = 1000;
float horizonY = worldHeight/2;
float amplitudeY = 200;

Calcolo delle coordinate del sole

Ora è il momento di calcolare la posizione del nostro sole per un determinato momento della giornata. Userò invece la stessa funzione parametrica usata da Jimmy ma con un dominio che va da [0..2PI] (per riportare il sole nella sua posizione originale all'alba):

x = (1-cos (t)) / 2

y = sin (t)

Questa è una buona funzione perché il valore X varia da 0 a 1 e poi di nuovo a 0 (che mapperemo ai valori X di inizio e fine del nostro sole) e il valore Y inizia da 0 e si sposta da 1 a indietro a 0 di nuovo (che sarebbe la nostra porzione del giorno ) e quindi ripete la stessa identica cosa sul lato negativo prima di tornare alla posizione originale (che sarebbe la nostra notte anche se il sole non sarà disegnato a questo punto).

Il primo passo è ridimensionare le ore dall'intervallo [0..24) all'intervallo della nostra funzione che è [0..2PI):

float t = (hours / 24f) * MathHelper.TwoPi;          // Scale: [0..24) to [0..2PI)

Quindi applichiamo le funzioni per recuperare i valori tra 0 e 1 di cui ho parlato sopra:

float horizontal = (float)((1-Math.Cos(t)) / 2f);    // Changes: 0 1 0
float vertical = (float)(Math.Sin(t));               // Changes: 0 1 0 -1 0

E infine scaliamo quei valori usando i parametri del sole:

float sunX = startX + (endX - startX) * horizontal;    // From startX to endX and back
float sunY = horizonY + amplitydeY * vertical;         // Up and down around horizonY

+1 per stupore, il mio unico rimpianto è che non posso segnare due risposte!
Ross,

Nessun problema, comunque ho usato le stesse formule di base di Jimmy. :)
David Gouveia il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.