Well, years ago I made the program like you presented here.
There is one hidden problem (or many, depends on point of view):
- If the speed of the ball is too
high, you can miss the collision.
And also, almost in 100% cases your new speeds will be wrong. Well, not speeds, but positions. You have to calculate new speeds precisely in the correct place. Otherwise you just shift balls on some small “error” amount, which is available from the previous discrete step.
The solution is obvious: you have to split the timestep so, that first you shift to correct place, then collide, then shift for the rest of the time you have.