Sign in to follow this  
ICUP

Frame Independence and Speed

Recommended Posts

ICUP    140
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
[code]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]

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

Main loop
[code]....
....

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();
.....
....[/code]

Share this post


Link to post
Share on other sites
BeerNutts    4401
[quote name='ICUP' timestamp='1313684117' post='4850818']
Code to move the ball
[code]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]
[/quote]
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.

Share this post


Link to post
Share on other sites
ICUP    140
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.

Share this post


Link to post
Share on other sites
Storyyeller    215
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.

Share this post


Link to post
Share on other sites
BeerNutts    4401
[quote name='ICUP' timestamp='1313691840' post='4850865']
I'm assuming you meant something like:
yOffset += ballVelocity * sin( radians ) * ( deltaTicks / 1000.f )
[/quote]
(I did, was just pointing out you need to include time in position calculations based on velocity)
[quote]
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)
[code]
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.
[/code]

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this