Right! To make the square move and bounce freely without getting potentially stuck in an edge what you need to do is to reverse the speed (and decrease it by 10%) before you actually move the ball! This is my simple suggestion
if r.left + speed[0] <= 0 or r.right + speed[0] >= width:
speed[0] = - (speed[0])*0.9
if r.top + speed[1] <= 0 or r.bottom + speed[1] >= height:
speed[1] = -(speed[1])*0.9
What the above modifications manages, is that it essentialy does not allow the square to go out of bounds at any time! As far as to what caused your above issue, after doing some debugging, it is apparent that the square manages to move outside the screen! (i.e. negative x,negative y etc), While it might seem harmless, this behaviour especially at lower speeds can cause the square to rapidly reverse and at the same time lower it's speed by 10%!
For example if at any point the square is at position x = - 1
with an xspeed of 1
. Due to this condition: if r.left + speed[0] <= 0 or r.right + speed[0] >= width:
it's speed will reverse multiple times back and forth and decrease at the same time not allowing the square to escape this edge!
Phew! Sorry for the long answer and I hope I helped! Cheers!,
Alex