Frame Independence and Speed

Started by
3 comments, last by BeerNutts 12 years, 8 months ago
I tried using the methods on lazyfoo's site for frame rate independence. One problem I'm having though is that my game is running at different speeds on different computers. The differences are drastic. For example, on a Core 2 Duo 2.4 ghz 2gb ram PC, the ball will move extremely fast, but the paddle moves slowly. On an Intel Centrino laptop running Win7 w/plenty of ram, the ball moves slowly, but the paddle moves fast. On older computers like a Pentium 4 2.4 ghz, 768 ram computer, the ball moves realllllllllyyyyyyy sllllooowwww. Yes, that slow.

What might be some reasons this is happening, and how can I fix it? I can only assume that the code I wrote that deals with frame rate independence is wrong. Here are the relevant parts of the code. (btw, it's a breakout clone).

Code to move the ball
bool Ball::MoveBall( Uint32 deltaTicks ) {
.....

// X-COORDINATE
xOffset += cos( radians ) * ( ballVelocity / 1000.f ) * flipx;
ballPosition.x = (Sint16)xOffset;

.......

// Y-COORDINATE
yOffset += sin( radians ) * ( ballVelocity / 1000.f ) * flipy;
ballPosition.y = (Sint16)yOffset;

.....
}


Code to move the paddle
void Paddle::Move( Uint32 deltaTicks ) {
xOffset += xVel * ( deltaTicks / 1000.f );
paddlePosition.x = (Sint16)xOffset;
}


Main loop
....
....

while ( SDL_PollEvent( &gEvent ) ) {
handle.PaddleInput( &gEvent, stick );

if ( gEvent.type == SDL_QUIT || gEvent.key.keysym.sym == SDLK_ESCAPE )
quit = true;
}
stick.Move( time.GetTicks() );

if ( ball.MoveBall( time.GetTicks() ) )
wallSound.Play();

if ( ball.CheckPaddleCollision( stick ) )
paddleSound.Play();

if ( ball.CheckBrickCollision( brickmap ) )
brickSound.Play();

if ( ball.IsBallDead() ) {
ball.ResetBallPosition();
stick.ResetPaddlePosition();
stick.SetPaddleState( Paddle::RESET );
launched = false;
draw.GameObjects( lvl, brickmap, stick, ball );
}

draw.GameObjects( lvl, brickmap, stick, ball );
time.Start();
draw.Refresh();
.....
....
Advertisement

Code to move the ball
bool Ball::MoveBall( Uint32 deltaTicks ) {
.....

// X-COORDINATE
xOffset += cos( radians ) * ( ballVelocity / 1000.f ) * flipx;
ballPosition.x = (Sint16)xOffset;

.......

// Y-COORDINATE
yOffset += sin( radians ) * ( ballVelocity / 1000.f ) * flipy;
ballPosition.y = (Sint16)yOffset;

.....
}


You're not applying the time to the velocity when moving the ball.

If the velocity is 30 pixel/second, and the time different is .04 seconds, then the ball should move:
30p/s * .04 = 1.2 pixels. You seem to have it in the paddle movement.

My Gamedev Journal: 2D Game Making, the Easy Way

---(Old Blog, still has good info): 2dGameMaking
-----
"No one ever posts on that message board; it's too crowded." - Yoga Berra (sorta)

I'm assuming you meant something like:
yOffset += ballVelocity * sin( radians ) * ( deltaTicks / 1000.f )

The problem with that is that the ball, when launched, is suddenly drawn 30 pixels in the angle direction.
On another note, frame independence is almost always a very bad idea. At the very least, your physics should always happen at fixed length substeps. For a pixel art game, you should also keep the graphics at a fixed framerate since interpolation looks terrible.
I trust exceptions about as far as I can throw them.

I'm assuming you meant something like:
yOffset += ballVelocity * sin( radians ) * ( deltaTicks / 1000.f )

(I did, was just pointing out you need to include time in position calculations based on velocity)

The problem with that is that the ball, when launched, is suddenly drawn 30 pixels in the angle direction.
[/quote]


That doesn't make any sense. Why would it be launched in the air? Is the deltaTicks massive? What is flipx?

Also, don't store coordinates as integers, store them as floats. You'll be getting poor results. if you have a very fast computer, then the frame could go very fast, and the pixel offsets could be < 1, and that's going to cause problems.

Why are you doing yOffset += ... and not just yOffset = ? Then you should assign ballposition.y += yOffset

For my example, if the ball was moving straight up (radians = PI/2), and the ball was just launched (let's assume it's the 2nd frame, and delta is .30 milliseconds)

yOffset += ballVelocity * sin( radians ) * ( deltaTicks / 1000.f );

ballVelocity = 10 pixels/second
sin(radians)= 1
deltTicks/1000 = 0.03

yOffset = 10 * 1 * 0.03 = 0.3 pixels movement for that frame. After 100 0.03 frames (3 seconds), the ball would have travelled 100 * 0.3 = 30 pixels, which is right.

My Gamedev Journal: 2D Game Making, the Easy Way

---(Old Blog, still has good info): 2dGameMaking
-----
"No one ever posts on that message board; it's too crowded." - Yoga Berra (sorta)

This topic is closed to new replies.

Advertisement