如何实现小球从画布顶部中心下落至底部?Python Tkinter问题求助
问题:Tkinter实现青色小球循环下落效果出错
我是Python与Tkinter的新手,正在开发一个项目,期望实现一个青色小球从画布顶部中心位置循环下落至画布底部的效果,但当前代码存在问题,不清楚错误出在哪里,恳请帮助。
原代码:
def moveDown(): canvas.data.cy += 5 if (canvas.data.cy + canvas.data.radius >= canvasWidth ): canvas.data.cy = canvas.data.radius def doTimerFired(): moveDown() redrawAll() def timerFired(): doTimerFired() delay = canvas.data.delay # milliseconds canvas.after(delay, timerFired) # pause, then call timerFired again def redrawAll(): canvas.delete(ALL) # draw the circle r = canvas.data.radius cx = canvas.data.cx cy = canvas.data.cy canvas.create_oval(cx-r, cy-r, cx+r, cy+r, fill="cyan") def init(): canvas.data.radius = 10 canvas.data.cx = 10 canvas.data.cy = 14 canvas.data.delay = 100 #milliseconds def run(): # create the root and the canvas global canvas, canvasWidth, canvasHeight root = Tk() canvasWidth = 500 canvasHeight = 500 canvas = Canvas(root, width=canvasWidth, height=canvasHeight) canvas.pack() # Set up canvas data and call init class Struct: pass canvas.data = Struct() canvas.data.canvasWidth = canvasWidth canvas.data.canvasHeight = canvasHeight init() timerFired() # and launch the app root.mainloop() # This call BLOCKS if __name__ == "__main__": run()
错误分析
- 初始位置错误:
init函数里canvas.data.cx = 10把小球初始x坐标设为10,并非画布顶部中心;canvas.data.cy = 14也不是顶部正确位置,应该让小球顶部对齐画布顶部,即cy = radius。 - 下落边界判断错误:
moveDown里判断条件用了canvasWidth(画布宽度),应该用canvasHeight(画布高度),否则会在横向边界触发重置,而非底部。 - 缺失模块导入:原代码未导入Tkinter相关模块,运行会直接报错。
修正后的代码
from tkinter import Tk, Canvas, ALL def moveDown(): canvas.data.cy += 5 # 改为判断画布高度,当小球底部触底时重置到顶部 if canvas.data.cy + canvas.data.radius >= canvas.data.canvasHeight: canvas.data.cy = canvas.data.radius def doTimerFired(): moveDown() redrawAll() def timerFired(): doTimerFired() delay = canvas.data.delay canvas.after(delay, timerFired) def redrawAll(): canvas.delete(ALL) r = canvas.data.radius cx = canvas.data.cx cy = canvas.data.cy canvas.create_oval(cx-r, cy-r, cx+r, cy+r, fill="cyan") def init(): canvas.data.radius = 10 # 设置初始x坐标为画布宽度的一半,即顶部中心 canvas.data.cx = canvas.data.canvasWidth // 2 # 初始y坐标设为radius,让小球顶部刚好对齐画布顶部 canvas.data.cy = canvas.data.radius canvas.data.delay = 100 def run(): global canvas, canvasWidth, canvasHeight root = Tk() canvasWidth = 500 canvasHeight = 500 canvas = Canvas(root, width=canvasWidth, height=canvasHeight) canvas.pack() class Struct: pass canvas.data = Struct() canvas.data.canvasWidth = canvasWidth canvas.data.canvasHeight = canvasHeight init() timerFired() root.mainloop() if __name__ == "__main__": run()
修正说明
- 补充导入
from tkinter import Tk, Canvas, ALL,解决模块未定义的报错。 init里将cx设为canvas.data.canvasWidth // 2,确保小球在顶部中心位置;cy设为radius,让小球顶部贴合画布顶部。moveDown里把判断条件改为canvas.data.canvasHeight,正确检测小球是否触底。- 重置位置时保持
cy = radius,确保小球回到顶部初始位置,实现循环下落。
内容的提问来源于stack exchange,提问作者Mrcode374
相关产品推荐
相关产品推荐

