SFML community forums

Help => General => Topic started by: didii on November 15, 2012, 05:06:33 pm

Title: Slow startup
Post by: didii on November 15, 2012, 05:06:33 pm
This isn't really all too important, but I just wonder why:

I almost finished in remaking pong, but for the player to have time to react at startup (I have no menu screen), I put the ball close to his bat and made sure it could bounce of when he stood still. Problem is that the ball just went right through the bat because my time interval for the first couple of frames was around 0.3 sec (decreasing quickly to 0.004 sec). I called sf::Clock::restart() right before the game-loop.
I guess this has something to do with the graphics card rather than with SFML, correct?

-------------------

Ignore the following, I was too dumb to not thinking about Google or the forum search being able to help me...
And while I'm asking I might as well ask what the PDB-files are. I didn't ask before because I thought I would not understand it yet. I think I will now but just in case I do I might as well ask it :)
I found how to get rid of the errors: by checking the download location of Microsoft Symbol Servers, but I didn't give any difference (or at least not that I noticed) apart from a slower start-up. I do notice there are files in like opengl32.dll or graphic card related dll-s which all seem like necessary files.
Title: Re: Slow startup
Post by: eXpl0it3r on November 15, 2012, 11:24:12 pm
Yeah I guess its OS related at which point in time the window gets fully displayed. Just insert some "press any button to start" functionality into your pong.
Title: Re: Slow startup
Post by: eigenbom on November 16, 2012, 12:24:45 am
Another quick fix could be to clamp the time-step, so it isn't bigger than some small amount (meaning that you won't get huge jumps in the physics):

Code: [Select]
const float MIN_DT = 1./60;
game loop {
  float dt = time_between_frames();
  float clamped_dt = (dt>MIN_DT)?MIN_DT:dt;
  update_world(clamped_dt);
  render();
}

This should be fine for pong, but for more intensive applications consider using a fixed timestep (http://gafferongames.com/game-physics/fix-your-timestep/).
Title: Re: Slow startup
Post by: didii on November 16, 2012, 03:30:30 pm
Thanks for the answers :) clamping the time-step seems like a good idea :) However I don't like the idea of fixed timesteps, if you have a pc that can handle 80fps instead of 60, why not?

Another quick question: when setting sf::RenderWindow::setFrameLimit(60) the movement isn't constant at all. The ball quickly increases and decreases speed in a certain pattern. I guess that when a limit is set and you call sf::RenderWindow::display() before a time of 1/60 has passed after the previous one it waits.
Title: Re: Slow startup
Post by: gyscos on November 16, 2012, 05:03:17 pm
VerticalSync, if it works, could be a better idea than FrameLimit.

How do you make your ball move ? Do you use a sf::Clock to get the exact amount of time elapsed between frames ?
Title: Re: Slow startup
Post by: eigenbom on November 16, 2012, 11:19:26 pm
Thanks for the answers :) clamping the time-step seems like a good idea :) However I don't like the idea of fixed timesteps, if you have a pc that can handle 80fps instead of 60, why not?

The fixed time-step only applies to the physics update. You can still run your main loop and render at 1000fps if u like, but the idea is to stabilise the physics on the machine and across other machines. In my current game, for example, I run everything at 60fps except the physics, which is run at 30fps, and I interpolate frames in the renderer, so it looks smooth but leaves me with enough CPU for all the other tasks.

Quote
Another quick question: when setting sf::RenderWindow::setFrameLimit(60) the movement isn't constant at all. The ball quickly increases and decreases speed in a certain pattern. I guess that when a limit is set and you call sf::RenderWindow::display() before a time of 1/60 has passed after the previous one it waits.

i think you have to setFrameLimit() before you create() the window.
Title: Re: Slow startup
Post by: eXpl0it3r on November 17, 2012, 12:06:21 am
i think you have to setFrameLimit() before you create() the window.
Nope, you can set it whenever you want and it's setFramerateLimit(). ;)
Title: Re: Slow startup
Post by: didii on November 17, 2012, 02:36:59 am
How do you make your ball move ? Do you use a sf::Clock to get the exact amount of time elapsed between frames ?
Yes, I did read the tutorials unlike many others :)

The fixed time-step only applies to the physics update. You can still run your main loop and render at 1000fps if u like, but the idea is to stabilise the physics on the machine and across other machines. In my current game, for example, I run everything at 60fps except the physics, which is run at 30fps, and I interpolate frames in the renderer, so it looks smooth but leaves me with enough CPU for all the other tasks.
Oh that way, I'll keep that in mind if I ever write a bigger game with physics then, thanks :)

i think you have to setFrameLimit() before you create() the window.
No I did not :) it's the first line after sf::RenderWindow::create().
Title: Re: Slow startup
Post by: mercurio7891 on November 17, 2012, 05:30:06 am
if possible, may I know how you did the collision detection between the bat? It might be due to the collision detection algo.
Title: Re: Slow startup
Post by: didii on November 17, 2012, 12:42:00 pm
It's just simple rectangle collision checking, very lightweight. I call it in the main loop 4 times each loop (top wall, bottom wall, player bat and AI bat), the objects all inherit from or are sf::RectangleShapes. Would be a surprise if it was the problem. Here:

void Ball::CheckCollision(sf::RectangleShape &obj) {
        sf::FloatRect obj_bounds(obj.getGlobalBounds());
        sf::FloatRect bounds(getGlobalBounds());

        if (bounds.intersects(obj_bounds)) {
                sf::Vector2f obj_pos1(obj_bounds.left, obj_bounds.top); // upper left corner
                sf::Vector2f obj_pos2(obj_bounds.left+obj_bounds.width, obj_bounds.top+obj_bounds.height); // bottom right corner
                sf::Vector2f pos1(bounds.left, bounds.top);
                sf::Vector2f pos2(bounds.left+bounds.width, bounds.top+bounds.height);
               
                if (pos1.x < obj_pos1.x || obj_pos2.x < pos2.x) { // checks if collision is to the left/right
                        angle = PI - angle; // update angle
                        UpdatePosition();   // move out of object
                }
                else if (pos1.y < obj_pos1.y || obj_pos2.y < pos2.y) { // check if collision is up/down
                        angle = -angle;   // update angle
                        UpdatePosition(); // move out of object
                }
        }
}
Title: Re: Slow startup
Post by: mercurio7891 on November 17, 2012, 04:52:51 pm
maybe as you said, your initial frame time is too large. You may change your collision code to check if the ball pass the bat instead of colliding.

For example if previously the ball is on top of the bat, and in the next frame the ball is below the bat a possible collision might have occurred. (Another check is necessary to determine if this is a false positive)

Next you can then resolve the a 2D line intersection equation to check the exact location of collision with the bat. The first line is from the current ball position to the next ball position. The second line would be your bat.

If an intersection occur, then it means a collision has occur.

Using this method, the collision is not so dependent on the time step being small.

Not sure if this helps
Title: Re: Slow startup
Post by: didii on November 17, 2012, 07:38:02 pm
maybe as you said, your initial frame time is too large. You may change your collision code to check if the ball pass the bat instead of colliding.

For example if previously the ball is on top of the bat, and in the next frame the ball is below the bat a possible collision might have occurred. (Another check is necessary to determine if this is a false positive)

Next you can then resolve the a 2D line intersection equation to check the exact location of collision with the bat. The first line is from the current ball position to the next ball position. The second line would be your bat.

If an intersection occur, then it means a collision has occur.

Using this method, the collision is not so dependent on the time step being small.

Not sure if this helps
And what has this to do with ball speeding and slowing with sf::RenderWindow::setFramerateLimit()?
I know what you mean, and if it were a bigger program I would have implemented it :)