Float / Double比较不适用于太阳系仿真

时间:2016-05-13 16:32:29

标签: 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_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 */
   }

这是绘制和移动地球的逻辑。 earthDegrees应保持在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;

这是代码的输出。尽管earthDegrees不在0和360之内,但检查它是否在0到360之间的else-if语句的计算结果为true。

enter image description here

我做错了什么?

1 个答案:

答案 0 :(得分:2)

printf("earthDegrees: %d.\n", earthDegrees);不会打印float打印整数。

尝试printf("earthDegrees: %f.\n", earthDegrees);