Почему новые формы черепах имеют странную ориентацию (а не ту, которую я определил)? - PullRequest
0 голосов
/ 27 марта 2019

Я хочу создать еще один клон Понга с Python и Turtle. Моя цель - позволить моим ученикам (которые начинают кодировать на 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()

Итак, как вы можете видеть, запускаете ли вы код, первый рисунок в порядке с горизонтальной формой. Но когда я ставлю Черепаху t1, форма становится вертикальной.

Та же проблема со 2-й формой, определенной через polyNotOk (со значениями для координат x и y, которые позволяют получить горизонтальное весло). Мне нужно создать "вертикальный" поли, чтобы получить горизонтальное весло.

Так что я могу найти обходной путь. Тем не менее, я все еще не удовлетворен этим решением, поэтому я прошу блестящих объяснений ;-) Заранее спасибо.

1 Ответ

1 голос
/ 28 марта 2019

Я надеюсь пролить свет на это странное поведение, а не защищать его.Первое, что нужно помнить о нарисованных курсорах, это то, что когда (0, 0) попадает в ваш курсор, это центральная точка, вокруг которой вращается ваш курсор, и пиксель в вашем курсоре, который попадает в любую точку, которую вы goto().

* 1004.* Некоторое понимание может быть найдено в документации 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

Больше, чем мы могли бы ожидать,учитывая, что ориентация по умолчанию в режиме «логотип» - северная, и более последовательная, чем раньше.

В любом случае, я бы сделал весла по-другому.Вместо пользовательского курсора я бы использовал квадрат курсора черепахи и изменил бы его по мере необходимости, используя 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, где игрок направлен вверх, но движется вбок.

...