One more approach using after. It's a shot though.
import tkinter as tk
def window():
window.canvas = getattr(window, 'canvas', tk.Canvas())
window.canvas.pack(fill='both', expand=True)
window.canvas.configure(bg='ivory')
window.canvas.update()
window.width = window.canvas.winfo_width()
window.height = window.canvas.winfo_height()
window.font = ('times 30 bold')
def target():
target.center = getattr(target, 'center', (window.width-150, round(window.height/2)))
target.linex = window.canvas.create_line(0, target.center[1], 800, target.center[1], fill='black')
target.liney = window.canvas.create_line(target.center[0], 0, target.center[0], window.height, fill='black')
target.target = window.canvas.create_rectangle(target.center[0]-30, target.center[1]-30, \
target.center[0]+30, target.center[1]+30, fill='blue')
def ball():
ball.ballx = 30
ball.speed = 0.2
ball.ball = window.canvas.create_oval(ball.ballx-25, target.center[1]-25, \
ball.ballx+25, target.center[1]+25, fill='red')
def ballstop(stop=False):
ballstop.msg = getattr(ballstop, 'msg', None)
ballstop.score = getattr(ballstop, 'score', None)
ballstop.stop = stop
if round(ball.ballx)+25 < target.center[0]-30:
ballstop.msg = 'Too Soon!'
ballstop.score = 0
elif round(ball.ballx)-25 > target.center[0]+30:
ballstop.msg = 'Missed It!'
ballstop.score = 0
elif round(ball.ballx)-25 < target.center[0]-30 and round(ball.ballx)+25 > target.center[0]-30:
ballstop.msg = 'Just Made It!'
ballstop.score = 50
elif round(ball.ballx)-25 < target.center[0]+30 and round(ball.ballx)+25 > target.center[0]+30:
ballstop.msg = 'Almost Missed!'
ballstop.score = 50
else:
ballstop.msg = 'Bulls Eye!'
ballstop.score = 100
def update():
ball.ballx = ball.ballx + ball.speed
root.bind('<space>', lambda stop: ballstop(stop=True))
if round(ball.ballx) >= 200:
ball.speed = 1.35
if round(ball.ballx) == 750:
ball.ballx = 750
ballstop.msg = 'Missed'
ballstop.stop = True
window.canvas.coords(ball.ball, ball.ballx-25, target.center[1]-25, ball.ballx+25, target.center[1]+25)
if ballstop.stop != True:
root.after(1, update)
else:
color = 'red' if ballstop.score == 0 else ('orange' if ballstop.score == 50 else 'blue')
window.canvas.create_text(10, 30, font=window.font, text=ballstop.msg, fill=color, anchor='w')
window.canvas.create_text(10, window.height-100, font=window.font, text=f'Score: {ballstop.score}', fill=color, anchor='w')
root.after_cancel(root)
root = tk.Tk()
root.geometry('800x600+200+200')
root.resizable(False, False)
window()
target()
ball()
ballstop()
update()
root.mainloop()
with reset button
import tkinter as tk
def window():
window.canvas = getattr(window, 'canvas', tk.Canvas())
window.canvas.pack(fill='both', expand=True)
window.canvas.configure(bg='ivory')
window.canvas.update()
window.width = window.canvas.winfo_width()
window.height = window.canvas.winfo_height()
window.font = ('times 30 bold')
window.button = tk.Button(window.canvas, text='Reset')
window.button.pack_forget()
def target():
target.center = getattr(target, 'center', (window.width-150, round(window.height/2)))
target.linex = window.canvas.create_line(0, target.center[1], 800, target.center[1], fill='black')
target.liney = window.canvas.create_line(target.center[0], 0, target.center[0], window.height, fill='black')
target.target = window.canvas.create_rectangle(target.center[0]-30, target.center[1]-30, \
target.center[0]+30, target.center[1]+30, fill='blue')
def ball():
ball.ballx = 30
ball.speed = 0.2
ball.ball = window.canvas.create_oval(ball.ballx-25, target.center[1]-25, \
ball.ballx+25, target.center[1]+25, fill='red', tags=('ball',))
def ballstop(stop=False):
ballstop.msg = getattr(ballstop, 'msg', None)
ballstop.score = getattr(ballstop, 'score', None)
ballstop.stop = stop
if round(ball.ballx)+25 < target.center[0]-30:
ballstop.msg = 'Too Soon!'
ballstop.score = 0
elif round(ball.ballx)-25 > target.center[0]+30:
ballstop.msg = 'Missed It!'
ballstop.score = 0
elif round(ball.ballx)-25 < target.center[0]-30 and round(ball.ballx)+25 > target.center[0]-30:
ballstop.msg = 'Just Made It!'
ballstop.score = 50
elif round(ball.ballx)-25 < target.center[0]+30 and round(ball.ballx)+25 > target.center[0]+30:
ballstop.msg = 'Almost Missed!'
ballstop.score = 50
else:
ballstop.msg = 'Bulls Eye!'
ballstop.score = 100
def update():
ball.ballx = ball.ballx + ball.speed
root.bind('<space>', lambda stop: ballstop(stop=True))
if round(ball.ballx) >= 200:
ball.speed = 1.35
if round(ball.ballx) == 750:
ball.ballx = 750
ballstop.msg = 'Missed'
ballstop.stop = True
window.canvas.coords(ball.ball, ball.ballx-25, target.center[1]-25, ball.ballx+25, target.center[1]+25)
if ballstop.stop != True:
root.after(1, update)
else:
color = 'red' if ballstop.score == 0 else ('orange' if ballstop.score == 50 else 'blue')
window.canvas.create_text(10, 30, font=window.font, text=ballstop.msg, fill=color, anchor='w', tags=('msg',))
window.canvas.create_text(10, window.height-100, font=window.font, text=f'Score: {ballstop.score}', fill=color, anchor='w', tags=('score',))
window.button.pack(side='bottom', pady=10)
window.button['command'] = reset
root.after_cancel(root)
def reset():
window.button.pack_forget()
window.canvas.delete('all')
window()
target()
ball()
ballstop()
update()
root = tk.Tk()
root.geometry('800x600+200+200')
root.resizable(False, False)
window()
target()
ball()
ballstop()
update()
root.mainloop()