为什么新的Turtle形状具有奇怪的方向(不是我定义的形状)?

时间:2019-03-27 18:37:32

标签: python turtle-graphics

我想用Python和Turtle创建Pong的另一个克隆。我的目标是让我的学生(开始使用Python进行编码)进一步练习。

我想创建一个Turtle,其形状为水平填充的矩形,就像一个程式化的桨一样。但是,当我创建一个方便的形状时,会得到一个旋转的(垂直)桨,而不是希望的水平桨。

这是演示这种奇怪行为的代码。

from turtle import *

begin_poly()
fd(200)
left(90)
fd(40)
left(90)
fd(200)
left(90)
fd(40)
left(90)
end_poly()
shape = get_poly()
register_shape("drawn", shape)

polyNotOk = ( (0,0), (100, 0), (100, 20), (0, 20) ) 
register_shape("polyNotOk", polyNotOk)

polyOk = ( (0,0), (0, 100), (20, 100), (20, 0) ) 
register_shape("polyOk", polyOk)

t1 = Turtle(shape="drawn")
t2 = Turtle(shape="polyNotOk")
t3 = Turtle(shape="polyOk")

t1.color("black")
t2.color("red")
t3.color("blue")

t1.stamp()
t2.stamp()
t3.stamp()

t1.goto(100,200)
t2.goto(100,-50)
t3.goto(100,-150)

t1.forward(100)
t2.forward(100)
t3.forward(100)

mainloop()

因此,如您所见,如果您运行代码,则第一个工程图是确定的,具有水平形状。但是当我在Turtle t1上盖章时,形状是垂直的。

通过polyNotOk定义的第二个形状有相同的问题(x和y坐标值允许获得水平桨叶)。我需要创建一个“垂直”多边形以获取水平桨。

因此,我能够找到一种解决方法。但是,我仍然对这种解决方案不满意,因此我想提出出色的解释;-)预先感谢。

1 个答案:

答案 0 :(得分:1)

我希望阐明这种奇怪的行为,而不是捍卫它。关于绘制的光标,要记住的第一件事是,(0, 0)落在光标绘图中的任何位置,这就是光标旋转的中心点,并且光标中的像素落在goto()的任何点上。 / p>

shapesize()方法文档中可以找到一些见解:

shapesize(stretch_wid=None, stretch_len=None, outline=None)

stretch_wid is stretchfactor perpendicular to orientation
stretch_len is stretchfactor in direction of turtles orientation.

也就是说,如果光标处于默认(东)方向,则将反转X和Y的方向。我相信这就是您在图形中看到的内容。 X平面垂直于方向(垂直),Y平面沿方向(水平)。与我们通常期望的相反。

这似乎不是Shape()类的错误,而是埋在游标逻辑中。这可能是历史的人工产物-如果我们更改为mode("logo")并运行您的代码,则会得到:

enter image description here

鉴于“徽标”模式的默认方向为北,并且比以前更一致,因此我们可以期望的更多。

无论如何,我都会用不同的方式来制作桨。我会使用乌龟的 square 光标代替自定义光标,并根据需要使用shapesize()对其进行整形:

from turtle import Screen, Turtle

CURSOR_SIZE = 20

screen = Screen()

t0 = Turtle("square")
t0.shapesize(20 / CURSOR_SIZE, 100 / CURSOR_SIZE)

t0.color("green")

screen.exitonclick()

仍然按照您的期望旋转逻辑(不是图形),但是至少文档告诉了我们。但是,我真的倾向于做的是使拨片的方向错误,并使用settiltangle(),但并不是像您所做的那样变通,而是使拨片的面朝一个方向,但移至另一个:

from turtle import Screen, Turtle

CURSOR_SIZE = 20

screen = Screen()

t0 = Turtle("triangle")
t0.shapesize(100 / CURSOR_SIZE, 20 / CURSOR_SIZE)
t0.settiltangle(90)
t0.penup()

t0.color("green")
t0.speed("slowest")  # for demonstration purposes

t0.forward(300)
t0.backward(600)
t0.forward(300)

screen.exitonclick()

请注意,我可以使用forward(10)backward(10)来移动我的球拍,而不必做类似t0.setx(t0.xcor() + 10)这样的可怕事情。对于玩家朝上但侧身移动的Space Invader型游戏非常有用。