How can I make the ball move instead of stretch in pygame?

You have to clear the display in every frame with pygame.Surface.fill:

while True:
    # [...]

    screen.fill(0) # <---

    main.draw_elements()
    main.move_ball()
    main.ball.x_pos += main.ball.speed
    pygame.display.flip()

    # [...]

Everything that is drawn is drawn on the target surface. The entire scene is redraw in each frame. Therefore the display needs to be cleared at the begin of every frame in the application loop. The typical PyGame application loop has to:

  • handle the events by either pygame.event.pump() or pygame.event.get().
  • update the game states and positions of objects dependent on the input events and time (respectively frames)
  • clear the entire display or draw the background
  • draw the entire scene (blit all the objects)
  • update the display by either pygame.display.update() or pygame.display.flip()