Функция для движения солнца?

9

Итак, учитывая солнечный спрайт, установленный на горизонте (x = 0, y = worldheight / 2), я пытаюсь разработать функцию, которая заставляет солнце подниматься, а затем падать.

Лучший способ сделать это - функция sin, но я не знаю, как ее использовать.

если использовать y = sin (x), то x должен находиться в диапазоне от 0 до pi для полной кривой, имея постоянную скорость для X.

Есть мысли или предложения?

Редактировать: Спасибо, ребята!

Солнце работает!

Росс
источник

Ответы:

7

Что касается вопроса от 0 до пи, в общем, все, что вам нужно сделать, это масштабировать X с помощью множителя. Пример:

y = sin(x * pi / worldWidth)

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

Однако, это не совсем та кривая, которую вы, вероятно, ищете. Вам следует использовать параметрическую форму:

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

Эта комбинация греха для Y и cos для X отследит эллипс.

Джимми
источник
Спасибо, это круто. Я не очень ориентирован на математику. Мои навыки в математике в значительной степени просто элементарное исчисление.
Росс
12

Как сказал Джимми, эллипс, вероятно, лучше подходит для этого движения. Вот несколько идей о том, как на самом деле реализовать это, с некоторыми подробностями для тех, кто заинтересован.

Принимая время

Для начала вам нужна переменная, чтобы отслеживать время в игровом мире. Вы можете реализовать это так, как вам нравится, но вот пример. Я буду использовать переменную с именем hoursот 0 до 24 (хотя, когда она достигает 24, она возвращается к 0).

В отличие от реальной жизни, я просто считаю, что день начинается в 0 часов, а ночь начинается в 12 часов. Это облегчит некоторые расчеты.

Я также определю скорость изменения игрового времени относительно реального времени. В этом примере каждые две минуты реального времени будут соответствовать одному часу в игре.

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
}

конфигурация

Теперь перед настройкой движения нашего солнца нам нужно указать несколько его параметров. В частности, при каком значении X он поднимается с горизонта, а при каком значении X он падает на горизонте. Кроме того, то, что Y соответствует горизонту, и как высоко он должен подняться выше этой линии.

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

Расчет координат Солнца

Теперь пришло время рассчитать положение нашего солнца для данного времени дня. Я буду использовать ту же параметрическую функцию, которую использовал Джимми, но с доменом в диапазоне от [0..2PI] вместо этого (для того, чтобы солнце вернулось в исходное положение к рассвету):

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

у = грех (т)

Это хорошая функция, потому что значение X изменяется от 0 до 1, а затем снова возвращается к 0 (которое мы будем сопоставлять с начальным и конечным значениями нашего Солнца X), а значение Y начинается с 0 и перемещается до 1 и обратно. до 0 снова (что будет нашей дневной частью), а затем повторяет ту же самую вещь на отрицательной стороне, прежде чем вернуться к исходной позиции (которая будет ночью хотя солнце не будет рисоваться в этой точке).

Первым шагом является масштабирование часов от диапазона [0..24) до диапазона нашей функции, который равен [0..2PI):

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

Затем мы применяем функции для возврата значений между 0 и 1, о которых я говорил выше:

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

И, наконец, мы масштабируем эти значения, используя параметры солнца:

float sunX = startX + (endX - startX) * horizontal;    // From startX to endX and back
float sunY = horizonY + amplitydeY * vertical;         // Up and down around horizonY
Дэвид Гувея
источник
+1 за удивительность, я сожалею только о том, что не могу отметить два ответа!
Росс
Нет проблем, я все равно использовал те же базовые формулы, что и Джимми. :)
Дэвид Гувея