May-10-2022, 02:55 PM
Here is my next submission, one of my favorite demos... bouncing balls. from 150 lines, I managed to drop it down to 30 with the help a dictionary rather than multiple lists. I could get the last five, but that would tip it into unreadable.
import tkinter, time, math, random def onTimer(): if len(ballstats) < 100: ballstats.append({"shape": None, "x":random.randrange(0,winWid),"y":random.randrange(0,winHei), "spdx":(random.random() * 2)-1, "spdy":(random.random() * 2)-1}) color = "#" for i in range(0,6): color = color + random.choice(["0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F"]) ballstats[len(ballstats)-1]["shape"] = canvas.create_oval(ballstats[len(ballstats)-1]["x"],ballstats[len(ballstats)-1]["y"], ballstats[len(ballstats)-1]["x"]+balldiameter,ballstats[len(ballstats)-1]["y"]+balldiameter, outline=color, fill=color) for i in range(0,len(ballstats)): ballstats[i]["x"] = ballstats[i]["x"] + ballstats[i]["spdx"] ballstats[i]["y"] = ballstats[i]["y"] + ballstats[i]["spdy"] for j in range(i+1,len(ballstats)): dist = math.sqrt(( (ballstats[i]["x"]+(balldiameter/2)) - (ballstats[j]["x"]+(balldiameter/2)))**2 + ( (ballstats[i]["y"]+(balldiameter/2)) - (ballstats[j]["y"]+(balldiameter/2)))**2) if dist < balldiameter: ballstats[i]["spdx"], ballstats[j]["spdx"] = ballstats[j]["spdx"], ballstats[i]["spdx"] ballstats[i]["spdy"], ballstats[j]["spdy"] = ballstats[j]["spdy"], ballstats[i]["spdy"] if ballstats[i]["x"] < 0 or ballstats[i]["x"] > winWid-balldiameter: ballstats[i]["spdx"] = ballstats[i]["spdx"] * -1 if ballstats[i]["y"] < 0 or ballstats[i]["y"] > winHei-balldiameter: ballstats[i]["spdy"] = ballstats[i]["spdy"] * -1 canvas.coords(ballstats[i]["shape"], (ballstats[i]["x"], ballstats[i]["y"], ballstats[i]["x"]+balldiameter, ballstats[i]["y"]+balldiameter)) timerhandle = window.after(2,onTimer) winWid = 640 winHei = 480 balldiameter = 7 ballstats = [] window = tkinter.Tk() canvas = tkinter.Canvas(window, width=winWid, height=winHei, bg="white") canvas.pack() timerhandle = window.after(2,onTimer) window.mainloop()