Please stop attaching source files and follow the rules stated here (http://en.sfml-dev.org/forums/index.php?topic=5559.msg36368#msg36368). Instead of adding more features that further complicate the code and make it more difficult for everyone to find the original problem, you should reduce your code as much as possible.
Okay, I reduced the code:
// #include...
int width = GetSystemMetrics(SM_CXSCREEN); // Get the Screen-Width
int height = GetSystemMetrics(SM_CYSCREEN); //Get the Screen-Height
int ballradius = 50;
int mass = ballradius;
int ballcount = 10;
// ... some functions ...
int main()
{
//...
vector <sf::CircleShape> Ball(10);
for(int i = 0; i < ballcount; i++ )
{
Ball[i].setRadius(ballradius);
Ball[i].setPointCount(100);
Ball[i].setFillColor(sf::Color(rgb(engine) ,rgb(engine) ,rgb(engine)));
Ball[i].setOutlineThickness(0);
Ball[i].setOutlineColor(sf::Color(88, 97, 97));
Ball[i].setPosition( i * 140 , i * 70);
}
sf::Clock clock;
sf::ContextSettings settings;
settings.antialiasingLevel = 8;
sf::RenderWindow window(sf::VideoMode(width, height), "Bouncing Balls", sf::Style::Fullscreen, settings);
window.setVerticalSyncEnabled(true);
window.setMouseCursorVisible(true);
while (window.isOpen())
{
//...event handling...
auto dt = clock.restart().asSeconds();
window.clear(sf::Color::White);
for(int i = 0; i < ballcount; i++ )
{
Ball[i].move(xSpeed[i] * dt, ySpeed[i] * dt );
}
for(int i = 0; i < ballcount; i++ )
{
window.draw(Ball[i]);
}
window.display();
//...Checking and handling Wall-Collisions here...
//Here's the ball to ball collision detection and handling code:
for (int i = 0; i < ballcount; i++)
{
for (int j = i + 1; j < ballcount; j++)
{
if (Collision(Ball[i].getPosition(), Ball[j].getPosition()))
{
sf::Vector2f v1(xSpeed[i], ySpeed[i]);
sf::Vector2f v2(xSpeed[j], ySpeed[j]);
sf::Vector2f n = Ball[i].getPosition() - Ball[j].getPosition();
n = Normalize(n);
float a1 = dotProduct(v1, n);
float a2 = dotProduct(v2, n);
float optimizedP = (2.0 * (a1 - a2)) / (mass + mass);
v1 = v1 - optimizedP * mass * n;
v2 = v2 + optimizedP * mass * n;
xSpeed[i] = v1.x;
ySpeed[i] = v1.y;
xSpeed[j] = v2.x;
ySpeed[j] = v2.y;
Ball[i].move(xSpeed[i] * dt, ySpeed[i] * dt);
Ball[j].move(xSpeed[j] * dt, ySpeed[j] * dt);
}
}
}
}
return 0;
}
I hope the code is more readable now! :)
If you want to compile it, just download the code from the post I made before.
Does somebody have an idea? Because the timestep shouldn't be the problem anymore.
Here's my loop:
while (window.isOpen())
{
sf::Time elapsedTime = clock.restart();
timeSinceLastUpdate += elapsedTime;
while (timeSinceLastUpdate > TimePerFrame)
{
timeSinceLastUpdate -= TimePerFrame;
processEvents();
update(TimePerFrame);
}
render();
}
I did implement it like it's shown in the code-example. Or did I do something wrong? I really don't know how to solve this problem... :(
Okay, so now my calculate-collisions part of my code looks like this:
for (int i = 0; i < ballcount; i++)
{
for (int j = i + 1; j < ballcount; j++)
{
sf::Vector2f newPosI(xSpeed[i] * dt.asSeconds(), ySpeed[i] * dt.asSeconds());
sf::Vector2f newPosJ(xSpeed[j] * dt.asSeconds(), ySpeed[j] * dt.asSeconds());
if (Collision(Ball[i].getPosition() + newPosI , Ball[j].getPosition() + newPosJ))
{
//Calculate and set the new Velocities
haveCollided = true;
}
else haveCollided = false;
}
}
if(!haveCollided)
{
for(int i = 0; i < ballcount; i++ )
{
Ball[i].move(xSpeed[i] * dt.asSeconds(), ySpeed[i] * dt.asSeconds() );
}
}
And this seems to work quite well!
I hope I did everything right, didn't I? :)
Now I'm going to spend one hour watching bouncing circles bounce around my screen and see if the circles still stick together sometimes ;D
Don't stop all movement just because one circle collided. Check my logic (https://bitbucket.org/zsbzsb/bouncing-circles/src/85695b64a1df996a1b22ecce5fe738dccc1f2d7c/BouncingCircles/Program.cs?at=master#cl-73) and see how it is done.
Only do collision detection for a single circle at a time using only that single circles new position. If that single circle's new position collides with any of the other circle's old position then simply don't move that single circle.
else haveCollided = false;
Don't set it to false, it should already start with a value of false outside your inner loop (but still inside your outer loop :)). And if a collision happens within your inner loop call break to avoid checking for any other collision.
for (int j = i + 1; j < ballcount; j++)
You inner loop still needs to loop over every single circle, not just the circles that come after the one that collision is currently being preformed on. Just add a single check inside the inner loop to avoid checking for collision against the same circle. A simple if (i == j) continue; will work (same as in my code). ;)
On a side note, if you hop on IRC (http://en.sfml-dev.org/forums/index.php?topic=2997.0) I would be glad to help get you straightened out (with this or any other problems). ;D