'canvas circle getting distorted in python

I am writing a code where there are multiple balls (or circles) of various sizes in Tkinter canvas. The problem is that during the running process when ever ball gets close to the canvas boundary and sometimes even away from the boundary the shape of the ball gets distorted. I am unsure why this is happening. is there something I am missing during the update of the window object?

This is the main file:

from tkinter import *
from Ball import *
import time


HEIGHT = 500
WIDTH = 500


window = Tk()
canvas = Canvas(window, height=HEIGHT, width=WIDTH)
canvas.pack()

volley_ball = Ball(canvas, 0, 0, 100, 2, 2,'red')
cricket_ball = Ball(canvas, 10, 10, 30, 4, 2,'green')
golf_ball =  Ball(canvas, 100, 100, 20, 8, 6,'white')


while True:
    volley_ball.move()
    cricket_ball.move()
    golf_ball.move()

    window.update()
    time.sleep(0.01)

window.mainloop()

This is the Ball class module code:

class Ball:

    def __init__(self, canvas, x, y, diameter, xVelocity, yVelocity, color):
        self.canvas = canvas
        self.image = canvas.create_oval(x, y, diameter, diameter, fill=color)
        self.xVelocity = xVelocity
        self.yVelocity = yVelocity
        self.diameter = diameter

    def move(self):
        self.coordinates = self.canvas.coords(self.image)
        if(self.coordinates[2] >= self.canvas.winfo_width() or self.coordinates[0] < 0):
            self.xVelocity = -self.xVelocity
        if (self.coordinates[3] >= self.canvas.winfo_height() or self.coordinates[1] < 0):
            self.yVelocity = -self.yVelocity
        self.canvas.move(self.image, self.xVelocity, self.yVelocity)


Solution 1:[1]

The visual artifacts are created by over driving your move function. Try changing delay to 1 millisecond and observe the artifacts! Slow it down a little and use xVelocity, yVelocity to control speed.

Also try changing your while loop for window.after.

def animate():
    volley_ball.move()
    cricket_ball.move()
    golf_ball.move()
    window.after(20, animate)

window.after(500, animate)
window.mainloop()

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Derek