Tkinter双弹跳球未触边界提前反弹且偏移递增问题求助
Hey there! Let's get those balls bouncing correctly. The root cause of your issue is that both the green and red ball are sharing the same xspeed and yspeed variables. When one ball triggers a bounce and reverses the speed, it directly alters the other ball's movement logic—this creates conflicting speed changes that make the balls bounce early and drift away from the boundaries over time.
The Fixed Code
Here's the adjusted version with independent speed variables for each ball, so their movements don't interfere with each other:
from tkinter import * import time root = Tk() def balls(): # Separate speed variables for each ball green_xspeed = 5 green_yspeed = 3 red_xspeed = -green_xspeed # Red moves opposite to green red_yspeed = -green_yspeed canvas = Canvas(root, width=1000, height=1000, bg="grey") root.title("collision detection") canvas.grid() greenBall = canvas.create_oval(5, 5, 35, 35, fill="green") redBall = canvas.create_oval(970, 970, 1000, 1000, fill="red") while True: # Green ball movement & bounce logic canvas.move(greenBall, green_xspeed, green_yspeed) posgreen = canvas.coords(greenBall) if posgreen[3] >= 1000 or posgreen[1] <= 0: green_yspeed = -green_yspeed if posgreen[2] >= 1000 or posgreen[0] <= 0: green_xspeed = -green_xspeed # Red ball movement & bounce logic canvas.move(redBall, red_xspeed, red_yspeed) posred = canvas.coords(redBall) if posred[3] >= 1000 or posred[1] <= 0: red_yspeed = -red_yspeed if posred[2] >= 1000 or posred[0] <= 0: red_xspeed = -red_xspeed root.update() time.sleep(0.01) balls() root.mainloop()
Key Changes Explained
- Independent Speed Variables: Each ball now has its own
xspeedandyspeed(e.g.,green_xspeedvsred_xspeed). This way, bouncing one ball doesn't affect the other's speed. - Isolated Bounce Logic: When a ball hits a boundary, only its own speed is reversed—no more cross-contamination between the two balls.
A Quick Optimization Tip
Using while True + time.sleep() can block Tkinter's main event loop, which might cause your window to freeze or become unresponsive. For smoother Tkinter animations, consider using the built-in after() method instead. Here's a quick example of how that could look:
from tkinter import * root = Tk() def balls(): green_xspeed = 5 green_yspeed = 3 red_xspeed = -green_xspeed red_yspeed = -green_yspeed canvas = Canvas(root, width=1000, height=1000, bg="grey") root.title("collision detection") canvas.grid() greenBall = canvas.create_oval(5, 5, 35, 35, fill="green") redBall = canvas.create_oval(970, 970, 1000, 1000, fill="red") def animate(): # Green ball logic canvas.move(greenBall, green_xspeed, green_yspeed) posgreen = canvas.coords(greenBall) nonlocal green_xspeed, green_yspeed if posgreen[3] >= 1000 or posgreen[1] <= 0: green_yspeed = -green_yspeed if posgreen[2] >= 1000 or posgreen[0] <= 0: green_xspeed = -green_xspeed # Red ball logic canvas.move(redBall, red_xspeed, red_yspeed) posred = canvas.coords(redBall) nonlocal red_xspeed, red_yspeed if posred[3] >= 1000 or posred[1] <= 0: red_yspeed = -red_yspeed if posred[2] >= 1000 or posred[0] <= 0: red_xspeed = -red_xspeed canvas.after(10, animate) # Repeat every 10ms animate() balls() root.mainloop()
This approach plays nicer with Tkinter's event model and avoids potential freezing issues.
内容的提问来源于stack exchange,提问作者michael fisher

