首页 > 解决方案 > 为什么新的 Turtle 形状有奇怪的方向(不是我定义的那个)?

问题描述

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

我想创建一个海龟,它的形状是一个水平填充的矩形,就像一个风格化的桨。但是当我创建一个我认为方便的形状时,我得到了一个旋转的(垂直)桨而不是我希望的水平桨。

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

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()

所以,你可以看到,如果你运行代码,第一张图是可以的,它是一个水平的形状。但是当我戳 Turtlet1时,形状是垂直的。

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

所以我能够找到解决方法。但是我仍然对这个解决方案不满意,所以我要求提供出色的解释;-) 在此先感谢。

标签: pythonturtle-graphics

解决方案


我希望阐明这种奇怪的行为,而不是为其辩护。关于绘制的光标,首先要记住的是,(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()类的错,而是隐藏在游标逻辑中。它可能是一个历史产物——如果我们更改mode("logo")并运行您的代码,我们会得到:

在此处输入图像描述

鉴于“徽标”模式的默认方向是北,我们可能会期待更多,并且比以前更加一致。

无论如何,我会让我的桨以不同的方式。而不是自定义光标,我会使用海龟的方形光标并根据需要使用以下方法对其进行整形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 类型游戏。


推荐阅读