Как двигать две черепашки одновременно?

def item_animate(turtle):
    turtle.setheading(90)
    for i in range(60):
        turtle.forward(0.5)
        sleep(0.001)
    for i in range(150):
        sleep(0.001)
    for i in range(60):
        turtle.forward(-0.5)
        sleep(0.001)
    for i in range(50):
        sleep(0.001)

    def um1():
        sck.addshape("C:\Ricksappllering/textures/brat_snezha2.gif")
        e.shape("C:\Ricksappllering/textures/brat_snezha2.gif")
        e.showturtle()
        e.speed('fastest')
        e.goto(0,0)
        if touch(e,t,200,200):
            e.goto(-240,-300)
            e.speed(1)
            if randint(0,1)==0:
                if randint(0,1)==0:
                    e.goto(-250,0)
                else:
                    e.goto(250,0)
            else:
                if randint(0,1)==0:
                    e.goto(0,-250)
                else:
                    e.goto(0,250)
        else:
            e.goto(-240,-300)
            e.speed(1) 
            e.goto(0,0)
        sleep(1)
        voic('1',3)
        voic('2',1.5)
        sck.addshape("C:\Ricksappllering/textures\mini_write_joe.gif")
        tt=Turtle()
        tt.penup()
        tt.shape("C:\Ricksappllering/textures\mini_write_joe.gif")
        tt.speed(100000000)
        tt.goto(x=e.xcor(),y=e.ycor())
        tt.speed(1)
        item_animate(tt)
        e.speed(5) 
        e.goto(-240,-300)
        e.hideturtle()

Функция item_animate(tt) занимает некоторое время. Мне нужно, чтобы она выполнялась, но чтобы при этом выполнялся и #код после одновременно или параллельно.


Ответы (2 шт):

Автор решения: Evgenii Evstafev

Возможно Вы ищите, что-то вроде:

import multiprocessing
import time
import os


def item_animate(duration):
    pid = os.getpid() # Получаем ID процесса
    print(f"[Процесс {pid}] Анимация началась (длительность {duration} сек)...")
    # Здесь какая-то логика
    # ...
    time.sleep(duration) # просто ожидание / имитация длительной операции
    print(f"[Процесс {pid}] Анимация завершена.")


def um1():
    tt = 3 # Пример параметра для item_animate

    print("# Код ДО вызова item_animate")

    # Создаем процесс для выполнения функции item_animate
    animation_process = multiprocessing.Process(target=item_animate, args=(tt,))

    # Запускаем процесс. Функция start() возвращает управление немедленно.
    animation_process.start()

    print("# Код ПОСЛЕ вызова item_animate (выполняется параллельно)")
    print("Основная программа продолжает работу...")
    time.sleep(1) # Имитация другой работы в основной программе
    print("Основная программа все еще работает...")


if __name__ == '__main__':
    um1()
    print("Основная функция um1() завершила выполнение.")
    # Процессы обычно завершаются корректно при выходе основной программы,
    # но использование join() - хорошая практика для явного ожидания.
→ Ссылка
Автор решения: Stanislav Volodarskiy

Вот код, который запускает параллельно две черепашки. К сожалению, есть проблема: хотя скорости черепашек установлены разные, они синхронизируются. Пока не придумал как это обойти.

Основная идея: каждая черепашка работает в своей нити. Но команды через очередь направляются в основную нить, которая выполняет рисование.

import threading
import turtle
import queue


class ThreadedTurtle:
    def __init__(self, queue, *args, **kwargs):
        self._turtle = turtle.Turtle(*args, **kwargs)
        self._queue = queue

    def __getattr__(self, name):
        method = getattr(self._turtle, name)
        return lambda *args, **kwargs: \
            self._queue.put(lambda: method(*args, **kwargs))


def main():
    q = queue.Queue(maxsize=1)
    t1 = ThreadedTurtle(q, 'square')
    t2 = ThreadedTurtle(q, 'circle')

    def draw1():
        t1.speed('slow')
        while True:
            t1.forward(90)
            t1.right(90)

    def draw2():
        t2.speed('fastest')
        while True:
            t2.forward(5)
            t2.right(5)

    threads = [threading.Thread(None, t) for t in (draw1, draw2)]
    for t in threads:
        t.start()

    while any(t.is_alive() for t in threads):
        try:
            a = q.get(block=False, timeout=0.1)
        except queue.Empty:
            continue
        a()

    for t in threads:
        t.join()


main()
→ Ссылка