【发布时间】:2020-07-10 18:39:00
【问题描述】:
我想通过点击画布来移动一只乌龟,乌龟应该指向它移动的方向。移动部分可以工作,但旋转功能会导致图像变形和损坏。
我做错了什么,我该如何解决?
我有一个类可以将乌龟的图像添加到画布上:
class TurtleImage:
"""
A Turtle image that will be placed on the canvas that is given in the ctor.
The turtle can be moved around the canvas with the move() method.
"""
def __init__(self, canvas : Canvas):
self.__turtle_file : str = self.__find_file("turtle_example/turtle.png")
self.__canvas = canvas
self.__pilImage : PngImagePlugin.PngImageFile = PILImage.open(self.__turtle_file)
self.__pilTkImage : ImageTk.PhotoImage = ImageTk.PhotoImage(self.__pilImage)
self.__turtle_id : int = canvas.create_image(100,100, image=self.__pilTkImage)
self.__is_moving = False
这个类还有一个方法可以让海龟在画布上移动。它在 x 方向、y 方向或两者上将海龟移动 1 个像素,然后在速度参数确定的时间延迟后重新调用自身。它还应该旋转海龟,使其指向正确的方向:
def move(self, dest_x : int, dest_y :int, speed : float = 0.1):
self.__is_moving = True
delay_ms = math.floor(1/speed)
current_x, current_y = self.__canvas.coords(self.__turtle_id)
delta_x = 1 if current_x < dest_x else -1 if current_x > dest_x else 0
delta_y = 1 if current_y < dest_y else -1 if current_y > dest_y else 0
angle = math.atan2(delta_y,delta_x)
self.__rotate(angle)
if (delta_x, delta_y) != (0, 0):
self.__canvas.move(self.__turtle_id, delta_x, delta_y)
if (current_x, current_y) != (dest_x, dest_y):
self.__canvas.after(delay_ms, self.move, dest_x, dest_y, speed)
else:
self.__is_moving = False
由于画布没有旋转对象的能力,我必须将对象替换为自身的旋转版本:
def __rotate(self, angle : float):
self.__pilImage = self.__pilImage.rotate(angle)
self.__pilTkImage = ImageTk.PhotoImage(self.__pilImage)
self.__replace_image(self.__pilTkImage)
def __replace_image(self, new_image : ImageTk.PhotoImage):
self.__canvas.itemconfig(self.__turtle_id, image = new_image)
四处移动可以正常工作,但是旋转功能会导致图像失真和损坏,并且每次调用都会变得更糟。
你能告诉我为什么这不起作用,我需要做什么来解决它?
这是该乌龟旋转前后的截图:
【问题讨论】:
-
你要分享原始的乌龟图像吗?并向我们展示一只“畸形”乌龟的样子?
-
@MarkSetchell 我明天会编辑并上传截图
标签: python-3.x tkinter python-imaging-library