Моделирование одновременно движущихся тел на холсте

Я борюсь с canvas.move в симуляции небесной системы. Как я могу одновременно перемещать несколько объектов в определенном экземпляре Space? Думаю, мне нужно что-то сделать с идентификацией объектов тела. Но я не могу это узнать. Возможно, мне следует использовать повторяющиеся методы рисования и удаления вместо canvas.move? См. упрощенную версию кода ниже. У кого-то есть предложение? Большое спасибо

import tkinter as tk

class Space(tk.Frame):
    def __init__(self, master, size, bg=None):
        super().__init__(master)
        frame = tk.Frame(master, border = 5)
        frame.pack()
        self.width, self.height = size[0], size[1]
        self.canvas = tk.Canvas(frame,
                                width = self.width,
                                height = self.height,
                                borderwidth= 0,
                                highlightthickness= 0,
                                bg=bg)
        self.canvas.pack()

    def place_body(self, body):
        x1, y1 = body.loc[0], body.loc[1]
        x2, y2 = x1+body.size, y1+body.size
        self.canvas.create_oval(x1,y1,x2,y2, fill=body.color)

    def distance_step(self):
        pass

    def move_body(self, body):
        # in stead of distance_step:
        dx, dy = body.speed[0], body.speed[1]
        self.canvas.move(body, dx, dy)
        self.canvas.after(1, lambda: self.move_body(body))         

class CelestialBody:
    def __init__(self, name, size, mass, loc, speed, color = "white"):
        self.name = name
        self.size = size
        self.mass = mass
        self.loc = loc
        self.speed = speed
        self.color = color

    def __repr__(self):
        return f"{self.name}"

class App:
    def __init__(self):
        x, y = 1000, 800
        size = (x,y)
        space = Space(root,size, bg = 'black')         
        sun1_size = 30
        sun1_mass = 10
        sun1_loc = (700, 450)        
        sun1_speed = (-200,0)
        
        sun2_size = 30
        sun2_mass = 10        
        sun2_loc = (300, 350)
        sun2_speed = (200,0)       
       
        sun1 = CelestialBody("sun1", sun1_size, sun1_mass, sun1_loc, sun1_speed, color = "yellow")
        sun2 = CelestialBody("sun2", sun2_size, sun2_mass, sun2_loc, sun2_speed,  color  = "yellow")

        space.place_body(sun1)
        space.place_body(sun2)
        
        space.move_body(sun1)
        space.move_body(sun2)       

        print(sun1, sun2)
        root.mainloop()

root = tk.Tk()
root.title('UNIVERSE')
app = App()```
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
0
57
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вам нужно отслеживать тег, возвращенный из canvas.create_oval(). Смотрите .tk_tag ниже. Мне пришлось замедлить вашу скорость, потому что объект немедленно покинул экран. Также обратите внимание: вместо dx, dy = body.speed[0], body.speed[1] можно просто dx, dy = body.speed.

import tkinter as tk


class Space(tk.Frame):
    def __init__(self, master, size, bg=None):
        super().__init__(master)
        frame = tk.Frame(master, border=5)
        frame.pack()
        self.width, self.height = size
        self.canvas = tk.Canvas(frame,
                                width=self.width,
                                height=self.height,
                                borderwidth=0,
                                highlightthickness=0,
                                bg=bg)
        self.canvas.pack()

    def place_body(self, body):
        x1, y1 = body.loc
        x2, y2 = x1 + body.size, y1 + body.size
        body.tk_tag = self.canvas.create_oval(x1, y1, x2, y2, fill=body.color)

    def distance_step(self):
        pass

    def move_body(self, body):
        # in stead of distance_step:
        dx, dy = body.speed
        dx, dy = dx/100, dy/100
        self.canvas.move(body.tk_tag, dx, dy)
        self.canvas.after(1, lambda: self.move_body(body))


class CelestialBody:
    def __init__(self, name, size, mass, loc, speed, color = "white"):
        self.name = name
        self.size = size
        self.mass = mass
        self.loc = loc
        self.speed = speed
        self.color = color
        self.tk_tag = None

    def __repr__(self):
        return f"{self.name}"


class App:
    def __init__(self):
        x, y = 1000, 800
        size = (x, y)
        space = Space(root, size, bg='black')
        sun1_size = 30
        sun1_mass = 10
        sun1_loc = (700, 450)
        sun1_speed = (-200, 0)

        sun2_size = 30
        sun2_mass = 10
        sun2_loc = (300, 350)
        sun2_speed = (200, 0)

        sun1 = CelestialBody("sun1", sun1_size, sun1_mass, sun1_loc, sun1_speed, color = "yellow")
        sun2 = CelestialBody("sun2", sun2_size, sun2_mass, sun2_loc, sun2_speed, color = "yellow")

        space.place_body(sun1)
        space.place_body(sun2)

        space.move_body(sun1)
        space.move_body(sun2)

        print(sun1, sun2)
        root.mainloop()


root = tk.Tk()
root.title('UNIVERSE')
app = App()

Это работает. Теперь я понимаю, что вы можете использовать идентификатор объекта класса в качестве атрибута того же объекта. Большое спасибо, Гленн, Сьяак.

Sjaak 23.12.2020 14:21

Другие вопросы по теме