如何重置 python turtle 中的屏幕以便为对象设置动画?
How do I reset the screen in python turtle so that I can animate an object?
我想画一张乌龟图,上面有森林、山脉和漂浮在屏幕顶部的云。
我无法导入任何需要下载的模块,它必须是原生的。
要在 python turtle 中为背景之上的对象设置动画,我需要绘制对象,然后重绘背景,然后在新位置重绘对象。问题是,我用来绘制背景的代码导致树木和山脉处于随机位置(看起来更自然)。我的 setup() 函数绘制了一个随机背景。我想知道的是如何在我的 main() 中重新绘制完全相同的背景?
这是我正在使用的代码:
# Elan Shetreat-Klein, 4/9/2019, Project 4
# A program to draw a landscape
from shapes import *
import random
import time
def background():
s.bgcolor('#87ceeb')
turtle.pencolor('#402905')
draw_rectangle(-500, -350, 1000, 200, c='#402905')
def tree(x, scale, leaf_color, trunk_color):
y = -350 + 200 * scale
draw_rectangle(x, y, 30 * scale, 200 * scale, c=trunk_color)
draw_tri(x + 15 * scale, y + 25 * scale, 175 * scale, c=leaf_color)
draw_tri(x + 15 * scale, y + 100 * scale, 150 * scale, c=leaf_color)
draw_tri(x + 15 * scale, y + 175 * scale, 100 * scale, c=leaf_color)
def forest():
dark_greens = ['#006400', '#008000', '#556B2F', '#00611C', '#003300', '#004F00']
light_greens = ['#397D02', '#476A34', '#308014', '#3D8B37', '#00CD00', '#0AC92B']
tree_locations = 3 * [x for x in range(-500, 600, 100)]
random.shuffle(tree_locations)
draw_rectangle(-500, -150, 1000, 200, c='#3B5323')
for xPos in tree_locations:
Xvary = random.randrange(-50, 50)
Svary = random.randrange(60, 80) / 100
tree(xPos + Xvary, Svary, dark_greens[random.randrange(0, 5)], '#603311')
for xPos in tree_locations:
Xvary = random.randrange(-40, 40)
Svary = random.randrange(70, 90) / 100
tree(xPos + Xvary, Svary, light_greens[random.randrange(0, 5)], '#734A12')
def mountain_range():
mountX = [x for x in range(-450, 550, 150)]
random.shuffle(mountX)
mountain_colors = ['#6F4242', '#856363', '#8B6969']
for xPos in mountX:
Xvary = random.randrange(-25, 25)
Svary = random.randrange(90, 110) / 100
x = xPos + Xvary
side = 600 * Svary
y = -350 + (sqrt((3 * side ** 2) / 4)) // 2
draw_tri(x, y, side, c=mountain_colors[mountX.index(xPos) % 3])
def create_cloud():
global cloud
cloud = {}
for i in range(20):
x2, y2 = random.randrange(-90, 90), random.randrange(-25, 25)
cloud[x2] = y2
print(cloud)
def draw_cloud(x, y):
turtle.pu()
turtle.goto(x, y)
turtle.dot(100, 'white')
for x2, y2 in cloud.items():
turtle.goto(x2 + x, y2 + y)
size = abs((1 - (turtle.distance(x, y)//100)) * 100)
turtle.dot(size, 'white')
turtle.speed(0)
s = turtle.getscreen()
def setup():
turtle.tracer(0, 0)
s.title("Forest with mountains in the backround")
s.bgcolor('white')
background()
mountain_range()
forest()
def main():
create_cloud()
for xPos in range(-500, 500, 1):
setup()
draw_cloud(xPos, 300)
turtle.update()
time.sleep(0.0001)
main()
turtle.done()
随机化相当简单,它只是稍微改变每棵树和山的大小和 X 位置。我已经想出了如何保持相同的云,这不是问题。
在代码中,重新绘制了一个新的随机背景,并开始减速。当我使用 turtle.clear() 或 turtle.reset() 时,屏幕一直闪烁蓝色,所以我不知道该怎么办。
感谢任何帮助!
有几种选择:您可以在绘制之前做出随机决定并保存所有这些决定以供重绘,或者通过提供种子使随机模块的输出具有确定性。第二种是更 hacky 的解决方案,但需要对代码进行较少的更改。
将第二行改为:import random as really_random
然后,在您的主循环中,就在调用 setup()
之前添加一行:random = really_random.Random(0)
。您可能在 create_cloud() 之前也需要这一行,因此您可以参考 random.
如果您想在每次执行程序时更改背景,请将 0 更改为其他随机种子。例如,您的主要内容可能如下所示:
def main():
my_random_seed = really_random.randint(0,10000000)
random = really_random.Random(my_random_seed)
create_cloud()
for xPos in range(-500, 500, 1):
random = really_random.Random(my_random_seed)
setup()
draw_cloud(xPos, 300)
turtle.update()
time.sleep(0.0001)
您遇到的困难是由于使用了一只乌龟。这可以在不完全重绘 整个 场景的情况下完成,只需对撤消缓冲区大小进行一些棘手的监控——在重绘之前仅撤消云的绘制。
或者,可以更简单地分配第二只乌龟来绘制云,并在更新之间对那只乌龟使用 clear()
和 draw_cloud()
,留下其余的风景完整。下面是您按照这些思路修改的代码以及其他调整:
from shapes import *
from random import choice, randrange, shuffle
MOUNTAIN_COLORS = ['#6F4242', '#856363', '#8B6969']
DARK_GREENS = ['#006400', '#008000', '#556B2F', '#00611C', '#003300', '#004F00']
LIGHT_GREENS = ['#397D02', '#476A34', '#308014', '#3D8B37', '#00CD00', '#0AC92B']
def background():
screen.bgcolor('#87ceeb')
default_turtle.pencolor('#402905')
draw_rectangle(-500, -350, 1000, 200, c='#402905')
def tree(x, scale, leaf_color, trunk_color):
y = -350 + 200 * scale
draw_rectangle(x, y, 30 * scale, 200 * scale, c=trunk_color)
draw_tri(x + 15 * scale, y + 25 * scale, 175 * scale, c=leaf_color)
draw_tri(x + 15 * scale, y + 100 * scale, 150 * scale, c=leaf_color)
draw_tri(x + 15 * scale, y + 175 * scale, 100 * scale, c=leaf_color)
def forest():
tree_locations = 3 * [x for x in range(-500, 600, 100)]
shuffle(tree_locations)
draw_rectangle(-500, -150, 1000, 200, c='#3B5323')
for xPos in tree_locations:
Xvary = randrange(-50, 50)
Svary = randrange(60, 80) / 100
tree(xPos + Xvary, Svary, choice(DARK_GREENS), '#603311')
for xPos in tree_locations:
Xvary = randrange(-40, 40)
Svary = randrange(70, 90) / 100
tree(xPos + Xvary, Svary, choice(LIGHT_GREENS), '#734A12')
def mountain_range():
mountX = [x for x in range(-450, 550, 150)]
shuffle(mountX)
for xPos in mountX:
Xvary = randrange(-25, 25)
Svary = randrange(90, 110) / 100
x = xPos + Xvary
side = 600 * Svary
y = -350 + (sqrt((3 * side ** 2) / 4)) // 2
draw_tri(x, y, side, c=choice(MOUNTAIN_COLORS))
def create_cloud():
positions = []
for _ in range(20):
x, y = randrange(-90, 90), randrange(-25, 25)
positions.append((x, y))
return positions
def draw_cloud(x, y):
cloud_turtle.clear()
cloud_turtle.penup()
cloud_turtle.goto(x, y)
cloud_turtle.dot(100, 'white')
for x2, y2 in cloud:
cloud_turtle.goto(x2 + x, y2 + y)
size = abs((1 - (cloud_turtle.distance(x, y) // 100)) * 100)
cloud_turtle.dot(size, 'white')
def setup():
screen.title("Forest with mountains in the background")
background()
mountain_range()
forest()
def animate(xPos=-500):
draw_cloud(xPos, 300)
screen.update()
if xPos < 625: # have draw_cloud() return cloud width & replace this number
screen.ontimer(lambda x=xPos + 1: animate(x), 100)
else:
screen.tracer(True) # stop animation
screen = turtle.Screen()
screen.tracer(False)
default_turtle = turtle.getturtle()
default_turtle.hideturtle()
cloud_turtle = turtle.Turtle()
cloud_turtle.hideturtle()
cloud = create_cloud()
setup()
screen.update()
animate()
screen.exitonclick()
我将您的云存储方式从字典更改为元组位置列表,因为字典不适合此目的。
我想画一张乌龟图,上面有森林、山脉和漂浮在屏幕顶部的云。
我无法导入任何需要下载的模块,它必须是原生的。
要在 python turtle 中为背景之上的对象设置动画,我需要绘制对象,然后重绘背景,然后在新位置重绘对象。问题是,我用来绘制背景的代码导致树木和山脉处于随机位置(看起来更自然)。我的 setup() 函数绘制了一个随机背景。我想知道的是如何在我的 main() 中重新绘制完全相同的背景?
这是我正在使用的代码:
# Elan Shetreat-Klein, 4/9/2019, Project 4
# A program to draw a landscape
from shapes import *
import random
import time
def background():
s.bgcolor('#87ceeb')
turtle.pencolor('#402905')
draw_rectangle(-500, -350, 1000, 200, c='#402905')
def tree(x, scale, leaf_color, trunk_color):
y = -350 + 200 * scale
draw_rectangle(x, y, 30 * scale, 200 * scale, c=trunk_color)
draw_tri(x + 15 * scale, y + 25 * scale, 175 * scale, c=leaf_color)
draw_tri(x + 15 * scale, y + 100 * scale, 150 * scale, c=leaf_color)
draw_tri(x + 15 * scale, y + 175 * scale, 100 * scale, c=leaf_color)
def forest():
dark_greens = ['#006400', '#008000', '#556B2F', '#00611C', '#003300', '#004F00']
light_greens = ['#397D02', '#476A34', '#308014', '#3D8B37', '#00CD00', '#0AC92B']
tree_locations = 3 * [x for x in range(-500, 600, 100)]
random.shuffle(tree_locations)
draw_rectangle(-500, -150, 1000, 200, c='#3B5323')
for xPos in tree_locations:
Xvary = random.randrange(-50, 50)
Svary = random.randrange(60, 80) / 100
tree(xPos + Xvary, Svary, dark_greens[random.randrange(0, 5)], '#603311')
for xPos in tree_locations:
Xvary = random.randrange(-40, 40)
Svary = random.randrange(70, 90) / 100
tree(xPos + Xvary, Svary, light_greens[random.randrange(0, 5)], '#734A12')
def mountain_range():
mountX = [x for x in range(-450, 550, 150)]
random.shuffle(mountX)
mountain_colors = ['#6F4242', '#856363', '#8B6969']
for xPos in mountX:
Xvary = random.randrange(-25, 25)
Svary = random.randrange(90, 110) / 100
x = xPos + Xvary
side = 600 * Svary
y = -350 + (sqrt((3 * side ** 2) / 4)) // 2
draw_tri(x, y, side, c=mountain_colors[mountX.index(xPos) % 3])
def create_cloud():
global cloud
cloud = {}
for i in range(20):
x2, y2 = random.randrange(-90, 90), random.randrange(-25, 25)
cloud[x2] = y2
print(cloud)
def draw_cloud(x, y):
turtle.pu()
turtle.goto(x, y)
turtle.dot(100, 'white')
for x2, y2 in cloud.items():
turtle.goto(x2 + x, y2 + y)
size = abs((1 - (turtle.distance(x, y)//100)) * 100)
turtle.dot(size, 'white')
turtle.speed(0)
s = turtle.getscreen()
def setup():
turtle.tracer(0, 0)
s.title("Forest with mountains in the backround")
s.bgcolor('white')
background()
mountain_range()
forest()
def main():
create_cloud()
for xPos in range(-500, 500, 1):
setup()
draw_cloud(xPos, 300)
turtle.update()
time.sleep(0.0001)
main()
turtle.done()
随机化相当简单,它只是稍微改变每棵树和山的大小和 X 位置。我已经想出了如何保持相同的云,这不是问题。
在代码中,重新绘制了一个新的随机背景,并开始减速。当我使用 turtle.clear() 或 turtle.reset() 时,屏幕一直闪烁蓝色,所以我不知道该怎么办。
感谢任何帮助!
有几种选择:您可以在绘制之前做出随机决定并保存所有这些决定以供重绘,或者通过提供种子使随机模块的输出具有确定性。第二种是更 hacky 的解决方案,但需要对代码进行较少的更改。
将第二行改为:import random as really_random
然后,在您的主循环中,就在调用 setup()
之前添加一行:random = really_random.Random(0)
。您可能在 create_cloud() 之前也需要这一行,因此您可以参考 random.
如果您想在每次执行程序时更改背景,请将 0 更改为其他随机种子。例如,您的主要内容可能如下所示:
def main():
my_random_seed = really_random.randint(0,10000000)
random = really_random.Random(my_random_seed)
create_cloud()
for xPos in range(-500, 500, 1):
random = really_random.Random(my_random_seed)
setup()
draw_cloud(xPos, 300)
turtle.update()
time.sleep(0.0001)
您遇到的困难是由于使用了一只乌龟。这可以在不完全重绘 整个 场景的情况下完成,只需对撤消缓冲区大小进行一些棘手的监控——在重绘之前仅撤消云的绘制。
或者,可以更简单地分配第二只乌龟来绘制云,并在更新之间对那只乌龟使用 clear()
和 draw_cloud()
,留下其余的风景完整。下面是您按照这些思路修改的代码以及其他调整:
from shapes import *
from random import choice, randrange, shuffle
MOUNTAIN_COLORS = ['#6F4242', '#856363', '#8B6969']
DARK_GREENS = ['#006400', '#008000', '#556B2F', '#00611C', '#003300', '#004F00']
LIGHT_GREENS = ['#397D02', '#476A34', '#308014', '#3D8B37', '#00CD00', '#0AC92B']
def background():
screen.bgcolor('#87ceeb')
default_turtle.pencolor('#402905')
draw_rectangle(-500, -350, 1000, 200, c='#402905')
def tree(x, scale, leaf_color, trunk_color):
y = -350 + 200 * scale
draw_rectangle(x, y, 30 * scale, 200 * scale, c=trunk_color)
draw_tri(x + 15 * scale, y + 25 * scale, 175 * scale, c=leaf_color)
draw_tri(x + 15 * scale, y + 100 * scale, 150 * scale, c=leaf_color)
draw_tri(x + 15 * scale, y + 175 * scale, 100 * scale, c=leaf_color)
def forest():
tree_locations = 3 * [x for x in range(-500, 600, 100)]
shuffle(tree_locations)
draw_rectangle(-500, -150, 1000, 200, c='#3B5323')
for xPos in tree_locations:
Xvary = randrange(-50, 50)
Svary = randrange(60, 80) / 100
tree(xPos + Xvary, Svary, choice(DARK_GREENS), '#603311')
for xPos in tree_locations:
Xvary = randrange(-40, 40)
Svary = randrange(70, 90) / 100
tree(xPos + Xvary, Svary, choice(LIGHT_GREENS), '#734A12')
def mountain_range():
mountX = [x for x in range(-450, 550, 150)]
shuffle(mountX)
for xPos in mountX:
Xvary = randrange(-25, 25)
Svary = randrange(90, 110) / 100
x = xPos + Xvary
side = 600 * Svary
y = -350 + (sqrt((3 * side ** 2) / 4)) // 2
draw_tri(x, y, side, c=choice(MOUNTAIN_COLORS))
def create_cloud():
positions = []
for _ in range(20):
x, y = randrange(-90, 90), randrange(-25, 25)
positions.append((x, y))
return positions
def draw_cloud(x, y):
cloud_turtle.clear()
cloud_turtle.penup()
cloud_turtle.goto(x, y)
cloud_turtle.dot(100, 'white')
for x2, y2 in cloud:
cloud_turtle.goto(x2 + x, y2 + y)
size = abs((1 - (cloud_turtle.distance(x, y) // 100)) * 100)
cloud_turtle.dot(size, 'white')
def setup():
screen.title("Forest with mountains in the background")
background()
mountain_range()
forest()
def animate(xPos=-500):
draw_cloud(xPos, 300)
screen.update()
if xPos < 625: # have draw_cloud() return cloud width & replace this number
screen.ontimer(lambda x=xPos + 1: animate(x), 100)
else:
screen.tracer(True) # stop animation
screen = turtle.Screen()
screen.tracer(False)
default_turtle = turtle.getturtle()
default_turtle.hideturtle()
cloud_turtle = turtle.Turtle()
cloud_turtle.hideturtle()
cloud = create_cloud()
setup()
screen.update()
animate()
screen.exitonclick()
我将您的云存储方式从字典更改为元组位置列表,因为字典不适合此目的。