Нарисуйте, а затем сотрите квадрат

#python #turtle-graphics #python-turtle

Вопрос:

Я пытаюсь нарисовать квадрат с помощью графики python, а затем стереть его через 3 секунды. У меня есть код ниже:

 import threading as th
import turtle
import random

thread_count = 0

def draw_square():
    turtle.goto(random.randint(-200,200), random.randint(-200,200))
    for i in range(4):
        turtle.forward(100)
        turtle.left(90)

def erase_square(x,y):
    turtle.pencolor('white')
    turtle.fillcolor('white')
    turtle.goto(x,y)
    turtle.begin_fill()
    for i in range(4):
        turtle.forward(target_size)
        turtle.left(90)
    turtle.end_fill()

def square_timer():
    global thread_count
    if thread_count <= 10: 
        print("Thread count", thread_count)
        draw_square()
        T = th.Timer(3, square_timer)
        T.start()
 

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

Ответ №1:

Самый простой способ очистить рисунок-это использовать этот clear() метод, а не пытаться рисовать белым поверх изображения:

 from turtle import Screen, Turtle
from random import randint

def draw_square():
    turtle.goto(randint(-200, 200), randint(-200, 200))

    turtle.pendown()

    for _ in range(4):
        turtle.forward(100)
        turtle.left(90)

    turtle.penup()

def erase_square():
    turtle.clear()
    screen.ontimer(square_update)  # no time, ASAP

def square_update():
    draw_square()
    screen.ontimer(erase_square, 3000)  # 3 seconds in milliseconds

screen = Screen()

turtle = Turtle()
turtle.hideturtle()
turtle.speed('fastest')
turtle.penup()

square_update()

screen.exitonclick()
 

Вы можете использовать undo() метод, как предлагает @JonathanDrukker, но вам придется отменять каждый шаг. Даже для такой простой формы, как квадрат, это требует небольшого размышления, но со сложной формой это сложно. Количество операций, добавленных в буфер отмены, не всегда совпадает с вызовами, которые вы выполняете для turtle. Но мы можем получить это количество от самой черепахи, если мы не будем выполнять никаких других действий черепахи между рисованием и стиранием:

 def draw_square():
    turtle.goto(randint(-200, 200), randint(-200, 200))

    count = turtle.undobufferentries()
    turtle.pendown()

    for _ in range(4):
        turtle.forward(100)
        turtle.left(90)

    turtle.penup()

    return turtle.undobufferentries() - count

def erase_square(undo_count):
    for _ in range(undo_count):
        turtle.undo()

    screen.ontimer(square_update)

def square_update():
    undo_count = draw_square()
    screen.ontimer(lambda: erase_square(undo_count), 3000)
 

Но что бы я сделал, так это сделал саму черепаху квадратом, а затем просто переместил ее, а не стирал и (повторно)рисовал квадрат:

 from turtle import Screen, Turtle
from random import randint

CURSOR_SIZE = 20

def draw_square():
    turtle.goto(randint(-200, 200), randint(-200, 200))

def square_update():
    turtle.hideturtle()
    draw_square()
    turtle.showturtle()

    screen.ontimer(square_update, 3000)

screen = Screen()

turtle = Turtle()
turtle.hideturtle()
turtle.shape('square')
turtle.shapesize(100 / CURSOR_SIZE)
turtle.fillcolor('white')
turtle.penup()

square_update()

screen.exitonclick()