Как запустить один и тот же метод одновременно, не дожидаясь окончания цикла? - PullRequest
0 голосов
/ 22 сентября 2018

Как видно из моего кода ниже, у меня есть функция, которая создает анимацию круга, когда пользователь нажимает на окно.Моя проблема в том, что для того, чтобы другой круг появился и начал двигаться после того, как он уже создан, я должен ждать, пока предыдущий завершит цикл движения.После того, как один круг завершил цикл «Я в диапазоне» в конце функции снегопада, я могу щелкнуть и создать другой круг.Я хочу иметь возможность щелкать в любое время и иметь столько кругов, которые движутся одновременно, сколько я хочу (я знаю, что я ограничил это 10 раз в коде под функцией).Похоже, мне нужно убрать один и тот же метод несколько раз одновременно.

from graphics import*
from random import*


win = GraphWin("Graphics Practice", 500, 500)

colours = ["blue", "red", "orange", "purple", "green", "black", "brown", "yellow", "pink"]

def snowfall(randColour):
    point = win.getMouse()
    circle = Circle(point, 40)
    circle.draw(win)
    circle.setFill(colours[randColour])
    for i in range(1000):
        circle.move(0, 1)
        time.sleep(0.002)

randColour = randint(0, 8)
for i in range (10):
    repeatColour = randColour
    snowfall(randColour)
    randColour = randint(0, 8)
    while randColour == repeatColour:
        randColour = randint(0, 8)

win.getMouse()
win.close()

Одна из моих неудачных попыток многопоточности:

from graphics import*
from random import*


win = GraphWin("Graphics Practice", 500, 500)

colours = ["blue", "red", "orange", "purple", "green", "black", "brown", "yellow", "pink"]

def snowfall(randColour):
    point = win.getMouse()
    circle = Circle(point, 40)
    circle.draw(win)
    circle.setFill(colours[randColour])
    for i in range(1000):
        circle.move(0, 1)
        time.sleep(0.002)

randColour = randint(0, 8)
t1 = threading.Thread(target = snowfall, args = randColour)
for i in range (10):
    repeatColour = randColour
    t1.start()
    t1.join()
    randColour = randint(0, 8)
    while randColour == repeatColour:
        randColour = randint(0, 8)

win.getMouse()
win.close()

Самый последний код:

from graphics import*
from random import*


win = GraphWin("Graphics Practice", 500, 500)

colours = ["blue", "red", "orange", "purple", "green", "black", "brown", "yellow", "pink"]

class Snowflake(object):
    def __init__(self, randColour):
        self.circle = Circle(point, 40)
        self.circle.draw(win)
        self.circle.setFill(colours[randColour])

    def next_frame(self):
        self.circle.move(0, 1)

randColour = randint(0, 8)
sprites = []    
for i in range (100):
    repeatColour = randColour
    point = win.getMouse()
    sprites.append(Snowflake(randColour))
    randColour = randint(0, 8)
    while randColour == repeatColour:
        randColour = randint(0, 8)
    for s in sprites:
        while True:
            s.next_frame()
            time.sleep(0.02)
    win.getMouse()
    randColour = randint(0, 8)
    sprites.append(Snowflake(randColour, point))

win.getMouse()
win.close()

1 Ответ

0 голосов
/ 24 сентября 2018

Одной из проблем является то, что вы пытаетесь join нить t1 сразу после запуска.Для join поток должен ждать его завершения, поэтому вместо запуска десяти потоков вы запускаете, а затем ожидаете поток десять раз.

Тем не менее, потоковый подход здесь неправильный. Большинство графических пакетов не позволяют нескольким потокам рисовать в одном и том же графическом контексте из соображений производительности и плавности.Это означает, что вам нужно вывернуть потоки чертежа «наизнанку», поместив состояние каждого анимированного объекта в «спрайт», чтобы состояние каждого анимированного объекта находилось в своем собственном экземпляре.Затем вместо использования отдельных потоков для каждого спрайта вы запускаете все свои спрайты и обновляете их в одном цикле, как показано ниже.

(Обратите внимание, что я ввел win.checkMouse(), который выполняет неблокированиепроверять наличие события мыши и, следовательно, позволяет добавлять спрайт за клик, что, как я полагаю, вы и предполагали.)

from graphics import *
from random import *

win = GraphWin("Graphics Practice", 500, 500)

colours = ["blue", "red", "orange", "purple", "green", "black", "brown", "yellow", "pink"]

class Snowflake(object):
    def __init__(self, randColour, point):
        self.circle = Circle(point, 40)
        self.circle.draw(win)
        self.circle.setFill(colours[randColour])

    def next_frame(self):
        self.circle.move(0, 1)

randColour = randint(0, 8)
sprites = []
for i in range(100):
    point = win.checkMouse()
    if point:
        randColour = randint(0, 8)
        sprites.append(Snowflake(randColour, point))
    for s in sprites:
        s.next_frame()
    time.sleep(0.1)
win.close()
...