Do not use time.sleep()
because its interface becomes irresponsible.
Instead, create a function to refresh the ball’s position, and use tela.after()
to schedule the execution of this function from time to time.
Inside the function, use canvas.coords()
to pick up the coordinates of the ball and see if it has passed the limits of the screen (400x400 in your case). If you have passed, reverse the direction.
from tkinter import *
tela = Tk()
tela.geometry('500x500')
tela.resizable(False, False)
canvas = Canvas(tela, width=400, height=400, bg='black')
ball = canvas.create_oval(20,20,50,50, fill='red')
canvas.pack()
x = 6
y = 8
def atualiza_posicao_bola():
global x, y
canvas.move(ball, x, y)
xb, yb, xs, ys = canvas.coords(ball)
if xs > 400 or xb < 0:
x = -x # inverte a direcao eixo x
if ys > 400 or yb < 0:
y = -y # inverte a direcao eixo y
tela.after(25, atualiza_posicao_bola) # agenda pra daqui a pouco
tela.after(0, atualiza_posicao_bola) # agendamento inicial
sair = Button(tela, text='Sair', bg='red', command=tela.destroy)
sair.pack()
tela.mainloop()
Note that I chose to keep the code structure similar to yours to facilitate understanding. In a future evolution of this code, I suggest using a class for the ball, and storing the steering variables as attributes of this class, thus avoiding the use of global and enabling more flexibility such as the creation of multiple balls and/or other elements.