私は太陽系(太陽、地球、月)の単純なゲーム/シミュレーションを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に評価されます。
私が間違って何をしているのですか?
を試してみてください。ありがとうございました。 – Qwurticus
これは本当に質問に答えますか?投稿された質問は、出力書式の問題のようには聞こえません。また、 'printf'に不正な書式指定子を使用すると、未定義の動作になります。この問題に遭遇しないところで 'std :: cout'を使う方が良いでしょう。 – PaulMcKenzie