[英]Tkinter - bouncing icon script
我正在编写一个简单的弹跳图标程序(Python 3.7,Windows 10 x64),以获得Tkinter和画布的感觉。 我已经在下面发布了我的代码。 该程序的问题是它会修剪图标的边缘(沿运动方向)。 如果我将运动放慢一点(通过在after方法中增加该值),它将不再裁剪,但运动不稳定。 也许我想得太多,它基本上可以实现我想要的目标。 但是,如果这是重要的游戏或其他项目,那么如何防止这种情况发生?
from tkinter import *
import os
from PIL import Image, ImageTk
xinc, yinc = 5, 5
def load_image(width, height, imgpath):
loadimg = Image.open(imgpath)
pwid, phi = loadimg.size
pf1, pf2 = 1.0*width/pwid, 1.0*height/phi
pfactor = min([pf1, pf2])
pwidth, pheight = int(pwid*pfactor), int(phi*pfactor)
loaded = loadimg.resize((pwidth, pheight), Image.ANTIALIAS)
loaded = ImageTk.PhotoImage(loaded)
return loaded
def bounce():
global xinc
global yinc
cwid = int(dash.cget('width'))
chi = int(dash.cget('height'))
x = dash.coords(dashposition)[0]
y = dash.coords(dashposition)[1]
if x > cwid-10 or x < 10:
xinc = -xinc
if y > chi-10 or y < 10:
yinc = -yinc
dash.move(dashposition, xinc, yinc)
dash.after(15, bounce)
root = Tk()
root.configure(bg='black')
dash = Canvas(root, bg='black', highlightthickness=0, width=400, height=300)
dash.grid(row=0, column=0, padx=2, pady=2)
imagepath = os.getcwd() + '/img/cloudy.png'
image = load_image(20, 20, imagepath)
x, y = 10, 10
dashposition = dash.create_image(x, y, anchor=CENTER, image=image, tags=('current'))
bounce()
root.mainloop()
裁剪有两个因素。 主要问题是,如果原始图像为正方形load_image(20, 20, imagepath)
仅会导致20x20对象。 但是您的云对象不是方形的。 并且仅当重新缩放的云对象为20x20时,边界碰撞计算才有效。 所以我们需要修改它。 另一个问题是您无法补偿Canvas的边界。 最简单的方法是使用bd=0
将其设置为零。
在GUI开发期间使用各种颜色通常是个好主意,这样您就可以准确知道小部件的位置。 为了让我们更容易看到云何时到达Canvas边界,我将根窗口颜色设置为红色。 我还增加了.after
延迟,因为我只是看不到以您设置的速度正在发生什么。 ;)我使云变得更大了。
我对您的代码做了其他一些小的更改,主要是我摆脱了“星号”导入,该导入将100多个Tkinter名称转储到您的命名空间中。
我将xinc
& yinc
减小到1,并改进了反弹范围的计算。 (并结合jasonharper的建议re cwid
& chi
)。 我不再在机器上看到任何剪裁,并且运动更加顺畅。 我也将Canvas填充减少到1像素,但这对剪切没有影响。 我只是用padx=10, pady=10
尝试过,它按预期工作。
import tkinter as tk
import os
from PIL import Image, ImageTk
def load_image(width, height, imgpath):
loadimg = Image.open(imgpath)
pwid, phi = loadimg.size
pf1, pf2 = width / pwid, height / phi
pfactor = min(pf1, pf2)
pwidth, pheight = int(pwid * pfactor), int(phi * pfactor)
loaded = loadimg.resize((pwidth, pheight), Image.ANTIALIAS)
loaded = ImageTk.PhotoImage(loaded)
return loaded, pwidth // 2, pheight // 2
xinc = yinc = 1
def bounce():
global xinc, yinc
x, y = dash.coords(dashposition)
if not bx <= x < cwid-bx:
xinc = -xinc
if not by <= y < chi-by:
yinc = -yinc
dash.move(dashposition, xinc, yinc)
dash.after(5, bounce)
root = tk.Tk()
root.configure(bg='red')
dash = tk.Canvas(root, bg='black',
highlightthickness=0, width=800, height=600, bd=0)
dash.grid(row=0, column=0, padx=1, pady=1)
cwid = int(dash.cget('width'))
chi = int(dash.cget('height'))
imagepath = 'cloudy.png'
size = 50
image, bx, by = load_image(size, size, imagepath)
# print(bx, by)
dashposition = dash.create_image(bx * 2, by * 2,
anchor=tk.CENTER, image=image, tags=('current'))
bounce()
root.mainloop()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.