太阳运动功能?


9

因此,考虑到将太阳精灵设置在地平线上(x = 0,y = worldheight / 2),我试图设计一个使太阳升起然后掉落的函数。

最好的方法是使用sin函数,但我不知道如何使用它。

如果使用y = sin(x),则对于完整的曲线,x的范围必须在0到pi之间,而对于X的速度必须恒定。

有什么想法或建议吗?

编辑:谢谢大家!

太阳工作!

Answers:


7

关于从0到pi的问题,通常您要做的就是用乘数缩放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的sin和X的cos的这种组合将描绘出一个椭圆。


谢谢,太好了。我不是很以数学为中心。我的数学技能几乎只是基本的演算。
罗斯

12

就像吉米(Jimmy)所说,椭圆形可能更适合此议案。对于感兴趣的人,这里有一些关于如何实际实现它的想法。

花时间

对于初学者,您需要一个变量来跟踪游戏世界中的时间。您可以按自己喜欢的任何方式实施它,但这是一个示例。我将使用一个称为hours0到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;

计算太阳的坐标

现在是时候计算一天中给定时间的太阳位置。我将使用与Jimmy相同的参数函数,但取而代之的是[0..2PI]范围(以便在黎明之前将太阳恢复到原来的位置):

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

y =罪恶(t)

这是个好函数,因为X值从0变到1,然后又变回0(我们将其映射到太阳的起始X值和结束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令人惊讶,我唯一的遗憾是我无法标记两个答案!
罗斯2012年

没问题,无论如何,我都使用与吉米相同的基本公式。:)
David Gouveia 2012年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.