Jun-20-2022, 07:18 AM
(Jun-04-2022, 10:25 AM)menator01 Wrote: Here is my go at it using after.
import tkinter as tk import time class View: def __init__(self, parent): self.parent = parent self.canvas = tk.Canvas(self.parent, bg='#ffffcc') self.canvas.pack(expand=True, fill='both') self.ballx, self.bally = 2, 275 self.ball_size, self.targetsize = 50, 50 * 1.25 self.targetx, self.targety = 800 - self.targetsize * 2.5, 300 - self.targetsize/2 self.target = self.canvas.create_rectangle(self.targetx, self.targety, self.targetx+self.targetsize*1.125, self.targety+self.targetsize, outline='#0000bb', fill='blue') self.ball = self.canvas.create_oval(self.ballx, self.bally, self.ballx+self.ball_size, self.bally+self.ball_size, outline='#bb0000', fill='red', width=3) self.text = self.canvas.create_text(10, 15, font=('tahoma 50 bold'), anchor='nw') self.text2 = self.canvas.create_text(10, 540, font=('tahoma 50 bold'), anchor='w') class Controller: def __init__(self, view): self.view = view self.view.parent.bind('<space>', self.ballstop) self.counter, self.speed = 0, 0.2 self.key = False self.msg = None self.color = None self.score = None self.view.btn = tk.Button(self.view.parent, text='Reset', command=self.reset) self.view.btn.pack_forget() self.update() def update(self): if self.key != True: if self.counter > 1000: self.speed = 1.35 self.counter += 1 self.view.ballx = self.view.ballx + self.speed if self.view.ballx > 725: self.view.ballx = 725 self.view.canvas.coords(self.view.ball, self.view.ballx, self.view.bally, self.view.ballx+self.view.ball_size, self.view.bally+self.view.ball_size) if self.counter == 1400: self.msg = 'Missed It!' self.score = 0 self.color = 'red' self.key = True self.view.btn.pack(side='bottom') else: if self.view.ballx + self.view.ball_size < self.view.targetx: self.msg = 'Too Soon!' self.score = 0 self.color = 'red' elif self.view.ballx > self.view.targetx + self.view.targetsize: self.msg = 'Missed It!' self.score = 0 self.color = 'red' elif self.view.ballx < self.view.targetx and self.view.ballx + self.view.ball_size > self.view.targetx: self.msg = 'Just Made It!' self.score = 50 self.color= 'orange' elif self.view.ballx + self.view.ball_size > self.view.targetx + self.view.targetsize and self.view.ballx < self.view.targetx + self.view.targetsize: self.msg = 'Almost Missed It!' self.score = 50 self.color = 'orange' elif self.view.ballx + self.view.ball_size > self.view.targetx and self.view.ballx + self.view.ball_size < self.view.targetx + self.view.targetsize: self.msg = 'Bulls Eye!' self.score = 100 self.color = 'blue' self.message(self.msg, self.color, f'Score: {self.score}') self.view.parent.after(1, self.update) def reset(self): self.key = False self.view.canvas.itemconfigure(self.view.text, text='') self.view.canvas.itemconfigure(self.view.text2, text='') self.view.ballx, self.speed, self.counter = 2, 0.2, 0 self.view.btn.pack_forget() self.msg, self.score = None, None def ballstop(self, event): if event.keysym: self.key = True self.view.btn.pack(side='bottom') def message(self, msg, color, score): self.view.canvas.itemconfigure(self.view.text, text=msg, fill=color) self.view.canvas.itemconfigure(self.view.text2, text=score, fill=color) if __name__ == '__main__': root = tk.Tk() root.geometry('800x600+200+200') controller = Controller(View(root)) root.mainloop()
(Jun-08-2022, 09:52 AM)menator01 Wrote: 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()
Hello.
The use of getattr is superfluous. It makes the code unnecessarily heavy...
I speak Python but I don't speak English (I just read it a little). If I express myself badly, please blame the translator^^.