Answers:
关于从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.
Y的sin和X的cos的这种组合将描绘出一个椭圆。
就像吉米(Jimmy)所说,椭圆形可能更适合此议案。对于感兴趣的人,这里有一些关于如何实际实现它的想法。
花时间
对于初学者,您需要一个变量来跟踪游戏世界中的时间。您可以按自己喜欢的任何方式实施它,但这是一个示例。我将使用一个称为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;
计算太阳的坐标
现在是时候计算一天中给定时间的太阳位置。我将使用与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