Tell me more ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I'm starting out writing a game in C++ and SFML, I have a lot of experience writing business software for servers in C# but very little experience in C++ and none in game development.

I have tried to draw a bouncing square to acquaint myself with C++, SFML and VS2012 and I got it to work, but it works funny. It stalls sometimes and the square that I'm jumping sometimes gains momentum from hitting the ground. What's the problem with my code?

void Square::Update(float elapsedTime)
{
    sf::Vector2f currentPosition = _sprite.getPosition();
    _velocity.y+=elapsedTime*GRAVITY;
    currentPosition.x+=_velocity.x;
    currentPosition.y+=_velocity.y;
    if (currentPosition.y + _velocity.y>=Game::SCREEN_HEIGHT)
    {
        //_sprite.setPosition(_sprite.getPosition().x,0);
        _velocity.y = std::abs(_velocity.y)*-0.95;
    }
    _sprite.setPosition(currentPosition);
}
share|improve this question
You could write this routine in C# using just a simple display to test it out in familiar territory. A graph of captured values over time would help visualize the error, you will need to run both simulated elapsed times and captured real time sequences. Set it up as a unit test to limit the variables you're testing. As a side note, you'll want to force the currentPosition to the SCREEN_HEIGHT cutoff in the if(), it's going to drop beneath the floor otherwise and not mimic the bounce. – Patrick Hughes Feb 9 at 21:28
1  
You're adding velocity to position on y, then checking to see if position + velocity > height. Perhaps set it equal to height if it's greater, ELSE add velocity, instead? – Robinson Feb 10 at 0:23
1  
This "debug my code" question is too localized, and more of a programming question than a game development question. – Gigggas Feb 10 at 4:36
How do you retrieve the elapsed time? Also which Version of SFML are you using? There are different ways measuring the time passed, and it's possible you're running into timing and/or rounding issues here. Personally, I prefer fixed time steps due to this. – Mario Feb 10 at 10:00
@Mario I'm using float elapsed=clock.restart().asSeconds(); using SFML 2.0, is there something wrong with that? – Ziv Feb 10 at 19:24
show 1 more comment

closed as too localized by Byte56, bummzack, Sean Middleditch, Kylotan, ClassicThunder Feb 11 at 15:08

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, see the FAQ.

1 Answer

Assuming the code surrounding your snippet is coded correctly, it looks like the problem is that your simulation code assumes a bottom-left origin but SFML has the origin at the top-left corner. So current position should be updated as currentPosition.y-=_velocity.y;

Also if you haven't already its worth taking the time to understand a bit more about the math behind your simulation. A lot of actual quantities are missing (e.g. MASS, Forces acting along X & Y Axis) and you've taken a very high COR (Coefficient of restitution). Heres a simplified sample:

struct vec2
{
    float x;
    float y;
};

struct sprite
{
    vec2 pos;
    vec2 vel;
    sprite *next;    
};

sprite s;
s.pos.x = ...
s.pox.y = ...
s.vel.x = ...
s.vel.y = ...


deltaT = the fractional time for which we're simulating. 
(deltaT = step size for euler's method)
void SimulateOneFrame (float deltaT)
{
    const float MASS = 1.0f; // point mass..
    const float GRAVITY = 9.8f;
    const float COR = 0.6f; // Coefficient of Restitution

    float forcex = 0.0f //force acting along x axis
    float forcey = - MASS * GRAVITY; // force acting along y axis


    //a first-order approximation of the solution to motion ODE's using Eulers method
    // x(t+1) = x(t) + v(t) * dt
    // v(t+1) = v(t) + a(t) * dt        
    // x = position, v = velocity, a = acceleration


    s.pos.x += s.vel.x * deltaT;
    s.pos.y += s.vel.y * deltaT;       // assumes origin (0,0) is bottom left 

    s.vel.x += forcex / MASS * deltaT;
    s.vel.y += forcey / MASS * deltaT;

    if (s.pos.y <= SPRITE_HEIGHT)  // assumes origin is bottom-left 
    {
        s.vel.y = -s.vel.y; //reverse velocity vector direction i.e. "bounce"

        s.vel.x *= COR;   
        s.vel.y *= COR;  // damp velocity after bouncing because of a non-elastic collision.
    }
}
share|improve this answer

Not the answer you're looking for? Browse other questions tagged or ask your own question.