Nightcracker это правильно. Вы понимаете, что вы делаете в этом цикле (который должен работать максимально быстро)? Вы создаете 2 новых шарика, загружаете изображение с hd, помещаете их в (0,0) и затем печатаете их вручную на экране в заданной позиции. Эта последняя часть означает, что вы отображаете их где-то, но не там, где они есть (вы установили их реальную позицию с помощью ball.rect = ball.image.get_rect ()). Они действительно в (0,0) и все время сталкиваются.
То, как вы их перетаскиваете на экран, не очень хорошо, вы должны использовать рендерер. В любом случае, вам, вероятно, стоит сначала попробовать несколько уроков, узнать, что такое Surface и что такое Sprite. Будьте осторожны с тем, что вы помещаете в основной цикл (почему вы все время создаете новые шары? Они могут быть созданы один раз при запуске), ваш код будет красивее, а ваш FPS увеличится