为什么新的 Turtle 形状有奇怪的方向(不是我定义的那个)?
Why new Turtle shapes have odd orientation (not the one I defined)?
我想用 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()
因此,正如您所看到的,如果您 运行 代码,第一个绘图就可以了,具有水平形状。但是当我戳龟的时候t1
,形状是垂直的
通过 polyNotOk
定义的第二个形状存在相同问题(具有允许获得水平桨的 x 和 y 坐标值)。我需要创建一个 "vertical" 多边形以获得水平桨。
所以我能够找到解决方法。但是我仍然对这个解决方案不满意,所以我要求出色的解释;-)提前致谢。
我希望阐明这种奇怪的行为,而不是为它辩护。关于绘制的光标,首先要记住的是 (0, 0)
落在光标绘图中的位置,即光标围绕其旋转的中心点和光标中落在任何点上的像素 goto()
。
可以在 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()
class 的错误,而是隐藏在游标逻辑中。它可能是历史文物——如果我们更改为 mode("logo")
和 运行 您的代码,我们将得到:
考虑到 "logo" 模式的默认方向是北,并且比以前更一致,我们可能会期待更多。
无论如何,我会以不同的方式制作我的球拍。我不使用自定义光标,而是使用 turtle 的 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 玩家面朝上但向侧面移动的入侵者类型游戏。
我想用 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()
因此,正如您所看到的,如果您 运行 代码,第一个绘图就可以了,具有水平形状。但是当我戳龟的时候t1
,形状是垂直的
通过 polyNotOk
定义的第二个形状存在相同问题(具有允许获得水平桨的 x 和 y 坐标值)。我需要创建一个 "vertical" 多边形以获得水平桨。
所以我能够找到解决方法。但是我仍然对这个解决方案不满意,所以我要求出色的解释;-)提前致谢。
我希望阐明这种奇怪的行为,而不是为它辩护。关于绘制的光标,首先要记住的是 (0, 0)
落在光标绘图中的位置,即光标围绕其旋转的中心点和光标中落在任何点上的像素 goto()
。
可以在 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()
class 的错误,而是隐藏在游标逻辑中。它可能是历史文物——如果我们更改为 mode("logo")
和 运行 您的代码,我们将得到:
考虑到 "logo" 模式的默认方向是北,并且比以前更一致,我们可能会期待更多。
无论如何,我会以不同的方式制作我的球拍。我不使用自定义光标,而是使用 turtle 的 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 玩家面朝上但向侧面移动的入侵者类型游戏。