C++ 浮点/双比较在太阳系模拟中不起作用
我正在用SDL2做一个简单的太阳系游戏/模拟(只有太阳、地球和月亮)。我用一个浮点来表示地球相对于太阳的度数(即0度为东方,90度为向下,等等)。当我尝试将值锁定在0和360之间时,它不起作用 我目前将模拟速度限制为90 fps,并希望每60秒旋转1圈C++ 浮点/双比较在太阳系模拟中不起作用,c++,animation,floating-point,sdl-2,C++,Animation,Floating Point,Sdl 2,我正在用SDL2做一个简单的太阳系游戏/模拟(只有太阳、地球和月亮)。我用一个浮点来表示地球相对于太阳的度数(即0度为东方,90度为向下,等等)。当我尝试将值锁定在0和360之间时,它不起作用 我目前将模拟速度限制为90 fps,并希望每60秒旋转1圈 // The desired FPS and the number of milliseconds (ticks) between frame draws. const int FPS = 90; const int TICKS_PER_FRAM
// The desired FPS and the number of milliseconds (ticks) between frame draws.
const int FPS = 90;
const int TICKS_PER_FRAME = 1000 / FPS;
// The number of seconds it will take for Earth to make one revolution around the sun.
const int EARTH_REVOLUTION_IN_SECONDS = 1 * 60;
// Number of degrees per millisecond for the Earth.
const float EARTH_DEGREES_PER_MILLISECOND = (float)EARTH_REVOLUTION_IN_SECONDS / 360000.0f;
我把地球放在离太阳约1/3电脑屏幕高度的地方,在0.0度时启动地球,然后启动计时器
// The distance from the Sun's center to the Earth's center. This will be
// a quarter of the screen height (presumed to be the smaller dimension).
int distSunToEarth = resolution_y * 0.3;
// Starting degrees of Earth relative to the Sun. 0.0 degrees is East.
float earthDegrees = 0.0f;
// Amount of time between now and the last frame draw.
Uint32 deltaTime = 0;
// The start time. No frames have been drawn yet.
Uint32 startedTime = SDL_GetTicks();
// Set current time to the started time.
Uint32 currentTime = startedTime;
在主循环开始时,我检查经过的时间量是否大于帧之间的时间量
// Get the current time in milliseconds.
currentTime = SDL_GetTicks();
// Calculate how much time has passed since the last frame draw.
deltaTime = currentTime - startedTime;
// If the amount of time that has passed is greater than our desired
// delay between frames, draw the next frame.
if (deltaTime > TICKS_PER_FRAME) {
/* Draw Frame */
}
这是绘制和移动地球的逻辑。地球度数应该保持在0到360之间,但事实并非如此。但是,代码仍然报告它在这些值内
/* Earth */
// Determine the center of the Earth. Start from the Sun's center and calculate the
// x and y values relative to it using Soh-Cah-Toa (Yay, trigonometry!). The degrees must
// be converted to radians using <degrees> * PI / 180.
int earthCenterX = backgroundCenterX + (distSunToEarth * cos(earthDegrees * M_PI / 180));
int earthCenterY = backgroundCenterY + (distSunToEarth * sin(earthDegrees * M_PI / 180));
// Determine the x and y values needed to center the Earth sprite at the above coordinates.
int earthSpriteX = earthCenterX - (earthSpriteSheet.GetClipWidth() / 2);
int earthSpriteY = earthCenterY - (earthSpriteSheet.GetClipHeight() / 2);
// Render the next frame.
earthSpriteSheet.RenderNextFrame(earthSpriteX, earthSpriteY);
// Move the Earth aroudn the Sun. Multiply the number of milliseconds that
// have passed by the number of degrees the Earth moves per millisecond.
earthDegrees += ((float)deltaTime * EARTH_DEGREES_PER_MILLISECOND);
//printf("degrees: %f.\n", (float)deltaTime * EARTH_DEGREES_PER_MILLISECOND);
//printf("earthDegrees: %f.\n\n", earthDegrees);
// If the degrees become negative, loop back to 360.
//
// e.g. if earthDegrees become -2.5 degrees, the new degrees would be:
// 360 deg - abs(-2.5 deg) => 357.5 deg.
if (earthDegrees < 0.0)
{
printf("Less than 0.0");
earthDegrees = 360.0f - abs(earthDegrees);
}
// Else if the Earth becomes greater than 2PI, round back to 0.
//
// e.g. if degrees become 362.5, the new degrees would be:
// 362.5 deg - 360 deg => 2.5 deg.
else if (earthDegrees > 360.0f)
{
printf("Greater than 360.0");
earthDegrees = earthDegrees - 360.0;
}
else if (earthDegrees >= 0.0f && earthDegrees <= 360.0f)
{
printf("Between 0 and 360\n");
}
printf("earthDegrees: %d.\n", earthDegrees);
/*
...
Render code
...
*/
// Reset the started time and current time to now.
startedTime = SDL_GetTicks();
currentTime = startedTime;
// Reset the change in time to 0.
deltaTime = 0;
/*地球*/
//确定地球的中心。从太阳中心开始,计算
//使用Soh-Cah-Toa(耶,三角学!)相对于它的x和y值。学位必须
//可以使用*PI/180转换为弧度。
int earthCenterX=backgroundCenterX+(distSunToEarth*cos(earthDegrees*M_PI/180));
int earthCenterY=backgroundCenterY+(distSunToEarth*sin(earthDegrees*M_PI/180));
//确定将地球精灵置于上述坐标中心所需的x和y值。
int earthSpriteX=earthCenterX-(earthSpriteSheet.GetClipWidth()/2);
int earthSpriteY=earthCenterY-(earthSpriteSheet.GetClipHeight()/2);
//渲染下一帧。
earthSpriteSheet.RenderNextFrame(earthSpriteX,earthSpriteY);
//使地球绕着太阳转。乘以所需的毫秒数
//已经超过了地球每毫秒移动的度数。
earthDegrees+=((浮点)deltaTime*地球度数/u毫秒);
//printf(“度数:%f.\n”,(浮点)增量时间*地球度数/u毫秒);
//printf(“地球度数:%f.\n\n”,地球度数);
//如果度变为负,则循环回360度。
//
//例如,如果地球度数变为-2.5度,则新度数将为:
//360度-abs(-2.5度)=>357.5度。
如果(地球度<0.0)
{
printf(“小于0.0”);
地球度=360.0f-绝对值(地球度);
}
//否则,如果地球变得大于2PI,则返回0。
//
//例如,如果度数变为362.5,则新度数将为:
//362.5度-360度=>2.5度。
否则,如果(地球度>360.0f)
{
printf(“大于360.0”);
地球度=地球度-360.0;
}
否则,如果(earthDegrees>=0.0f&&earthDegreesprintf(“earthDegrees:%d.\n”,earthDegrees);
不打印float
则打印整数
尝试打印(“地球度数:%f.\n”,地球度数)
这似乎是问题所在…我的地球精灵没有移动,但至少度数明显在变化。谢谢。这真的回答了问题吗?发布的问题听起来不像是输出格式问题。另外,使用不正确的格式说明符进行打印是未定义的行为。最好使用std::cout
这样你就不会陷入麻烦。