Como Jimmy disse, uma elipse é provavelmente a melhor opção para esse movimento. Aqui estão algumas idéias sobre como realmente implementá-lo com um pouco mais de detalhes para os interessados.
Tomando tempo
Para iniciantes, você precisa de uma variável para acompanhar o tempo no mundo do jogo. Você pode implementá-lo como quiser, mas aqui está um exemplo. Vou usar uma variável chamadahours que varia de 0 a 24 (embora, quando chegue a 24, volte a 0).
Ao contrário da vida real, considerarei que o dia começa às 0 horas e a noite às 12 horas. Isso facilitará alguns dos cálculos.
Também vou definir a taxa em que o tempo do jogo muda em relação ao tempo real. Neste exemplo, a cada dois minutos em tempo real corresponderá a uma hora no jogo.
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
}
Configuração
Agora, antes de definir o movimento do sol, precisamos especificar alguns de seus parâmetros. Em particular, em qual valor X ele eleva do horizonte e em qual valor X ele cai no horizonte. Além disso, o que Y corresponde ao horizonte, e quão alto ele deveria subir acima dessa linha.
float startX = 0;
float endX = 1000;
float horizonY = worldHeight/2;
float amplitudeY = 200;
Cálculo das coordenadas do sol
Agora é hora de calcular a posição do nosso sol para uma determinada hora do dia. Usarei a mesma função paramétrica usada por Jimmy, mas com o domínio variando entre [0..2PI] (para trazer o sol de volta à sua posição original ao amanhecer):
x = (1-cos (t)) / 2
y = pecado (t)
Essa é uma boa função porque o valor X varia de 0 a 1 e depois volta a 0 novamente (que mapearemos para os valores X de início e fim do sol) e o valor Y começa em 0 e move-se até 1 e vice-versa. para 0 novamente (que seria a nossa parte do dia ) e depois repete exatamente a mesma coisa no lado negativo antes de voltar à posição original (que seria a nossa noite, embora o sol não seja atraído neste momento).
O primeiro passo é escalar as horas do intervalo [0..24) para o intervalo da nossa função que é [0..2PI):
float t = (hours / 24f) * MathHelper.TwoPi; // Scale: [0..24) to [0..2PI)
Em seguida, aplicamos as funções para recuperar os valores entre 0 e 1, como falei acima:
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 finalmente escalamos esses valores usando os parâmetros do sol:
float sunX = startX + (endX - startX) * horizontal; // From startX to endX and back
float sunY = horizonY + amplitydeY * vertical; // Up and down around horizonY