当前位置: 首页 > 面试题库 >

动画化对象以在Tkinter中的圆形路径中移动

尹兴生
2023-03-14
问题内容

我正在尝试使用圆在Tkinter中为一个简单的太阳系建模,并在画布中四处移动。但是,我一直在努力寻找一种使它们动起来的方法。我环顾四周,发现该move功能after创建动画循环结合在一起。我尝试使用参数来烦躁,以改变y偏移量并在弯曲路径中创建运动,但是在尝试递归或while循环执行时却失败了。这是我到目前为止的代码:

import tkinter

class celestial:
    def __init__(self, x0, y0, x1, y1):
        self.x0 = x0
        self.y0 = y0
        self.x1 = x1
        self.y1 = y1

sol_obj = celestial(200, 250, 250, 200)
sx0 = getattr(sol_obj, 'x0')
sy0 = getattr(sol_obj, 'y0')
sx1 = getattr(sol_obj, 'x1')
sy1 = getattr(sol_obj, 'y1')
coord_sol = sx0, sy0, sx1, sy1

top = tkinter.Tk()

c = tkinter.Canvas(top, bg='black', height=500, width=500)
c.pack()

sol = c.create_oval(coord_sol, fill='black', outline='white')

top.mainloop()

问题答案:

这里显示了一种使用tkinterafter方法更新对象和关联的画布oval对象的位置的方法。它使用生成器函数沿圆形路径计算坐标,该圆形路径表示Celestial实例之一(名为planet_obj1)的轨道。

import math
try:
    import tkinter as tk
except ImportError:
    import Tkinter as tk  # Python 2

DELAY = 100
CIRCULAR_PATH_INCR = 10

sin = lambda degs: math.sin(math.radians(degs))
cos = lambda degs: math.cos(math.radians(degs))

class Celestial(object):
    # Constants
    COS_0, COS_180 = cos(0), cos(180)
    SIN_90, SIN_270 = sin(90), sin(270)

    def __init__(self, x, y, radius):
        self.x, self.y = x, y
        self.radius = radius

    def bounds(self):
        """ Return coords of rectangle surrounding circlular object. """
        return (self.x + self.radius*self.COS_0,   self.y + self.radius*self.SIN_270,
                self.x + self.radius*self.COS_180, self.y + self.radius*self.SIN_90)

def circular_path(x, y, radius, delta_ang, start_ang=0):
    """ Endlessly generate coords of a circular path every delta angle degrees. """
    ang = start_ang % 360
    while True:
        yield x + radius*cos(ang), y + radius*sin(ang)
        ang = (ang+delta_ang) % 360

def update_position(canvas, id, celestial_obj, path_iter):
    celestial_obj.x, celestial_obj.y = next(path_iter)  # iterate path and set new position
    # update the position of the corresponding canvas obj
    x0, y0, x1, y1 = canvas.coords(id)  # coordinates of canvas oval object
    oldx, oldy = (x0+x1) // 2, (y0+y1) // 2  # current center point
    dx, dy = celestial_obj.x - oldx, celestial_obj.y - oldy  # amount of movement
    canvas.move(id, dx, dy)  # move canvas oval object that much
    # repeat after delay
    canvas.after(DELAY, update_position, canvas, id, celestial_obj, path_iter)

top = tk.Tk()
top.title('Circular Path')

canvas = tk.Canvas(top, bg='black', height=500, width=500)
canvas.pack()

sol_obj = Celestial(250, 250, 25)
planet_obj1 = Celestial(250+100, 250, 15)
sol = canvas.create_oval(sol_obj.bounds(), fill='yellow', width=0)
planet1 = canvas.create_oval(planet_obj1.bounds(), fill='blue', width=0)

orbital_radius = math.hypot(sol_obj.x - planet_obj1.x, sol_obj.y - planet_obj1.y)
path_iter = circular_path(sol_obj.x, sol_obj.y, orbital_radius, CIRCULAR_PATH_INCR)
next(path_iter)  # prime generator

top.after(DELAY, update_position, canvas, planet1, planet_obj1, path_iter)
top.mainloop()

这是运行的样子:

动画图像显示它正在运行



 类似资料:
  • 这是一个非常基本的程序,我想用它来制作两个移动的球,但实际上只有一个在移动。 我也尝试过一些变化,但无法让第二个球移动;另一个相关问题-一些人使用方法来实现这一点,而其他人则执行然后重新绘制。我应该使用哪一个?为什么? 这是我的代码,它只设置/移动一个球的动画:

  • 问题内容: 我做了一个绘制椭圆并相互链接的迷你代码,现在我尝试移动椭圆(圆),但是我在编码时遇到了问题 移动两个圆圈,并且直线一定不能移动(Graph节点),请帮帮我,谢谢:)更新后(感谢MadProgrammer),现在我可以移动所有 图形了 问题答案: 基本上,因为可以使用而不是使用 这将确保整个组件被重新粉刷。 虽然我不反对使用repaint(int, int),因为您的绘画过程相对简单,但

  • 是否可以删除对象内部的圆形类型? 比方说 到 我想过滤掉对象中的所有圆形类型。 尝试1: 因为每个对象的名称在子对象中也是相同的。我试图删除它,因为大多数孩子的圆形对象只指向父母。(事实上,我对这部分感到困惑)。这是我试图使用的代码。

  • 使用另一个问题中的代码,我在tkinter窗口中嵌入了一个pygame窗口,我试图制作一个tkbutton,在pygame窗口上画一个圆圈,已经试验了一段时间,到目前为止还没有任何结果。任何想法都会很棒!这是我到目前为止的代码。。。

  • 我正在尝试制作一个傀儡头像,用于一个利用语音识别和与用户对话的项目。我计划用的主要图书馆是三个。js,它有两种不同的动画方法——动画剪辑和变形目标。 多个动画片段对于项目来说可能太麻烦了,但变形目标似乎符合能够根据存在的特定声音设置人脸动画的标准。我想使用Blender设置变形目标,但我正在回顾的许多文献似乎相互矛盾。Blender手册本身似乎暗示它们是同义词,但本文认为它们并不相同(尽管它们试图

  • 本文向大家介绍在弯曲的路径中移动HTML div,包括了在弯曲的路径中移动HTML div的使用技巧和注意事项,需要的朋友参考一下 要在弯曲的路径中移动HTML div,请使用以下任一方法:  CSS过渡  JavaScript(jQuery)  HTML5画布 尝试使用JavaScript,使其在所有浏览器中都能正常工作。 使用方法。该方法对一组CSS属性执行自定义动画。 以下是语法: 这是此方