如何防止乌龟向相反方向移动

How to prevent turtle from moving in opposite direction

代码:

import turtle
import random
import time

s = turtle.getscreen()
turtle.screensize(canvwidth=400, canvheight=400)
t = turtle.Turtle()
t.pensize(0)
t.shape('square')
t.color("black")
t.speed(0)
t.penup()

def moveu(num):
    t.setheading(num)
    t.forward(20)
    

s.onkey(lambda : moveu(90), 'w')
s.onkey(lambda : moveu(270), 's')
s.onkey(lambda : moveu(180), 'a')
s.onkey(lambda : moveu(0), 'd')
    
s.listen()

我还没有完成这个项目,但我 运行 遇到了一些问题。我想在 turtle 模块中创建一个游戏。但是我不知道如何防止块向后移动。我见过其他人使用 t.direction 之类的。但是我已经尝试过了,但它并没有真正奏效,也许我只是愚蠢而且我做错了什么。如何防止正方形向相反方向移动?

I don't know how to prevent the block from moving backward.

实际上,您的方块只是向前移动。如果将方块的形状从 'square' 更改为 'arrow',您会发现它始终朝着它所面对的方向移动。如果您想以某种方式限制它,我们需要更好地描述您想要或不想要的运动类型。

您的代码经过一些小调整的简化版本:

from turtle import Screen, Turtle

def moveu(angle):
    turtle.setheading(angle)
    turtle.forward(20)

screen = Screen()
screen.setup(400, 400)

turtle = Turtle()
turtle.shape('arrow')
turtle.speed('fastest')
turtle.penup()

screen.onkey(lambda: moveu(90), 'w')
screen.onkey(lambda: moveu(270), 's')
screen.onkey(lambda: moveu(180), 'a')
screen.onkey(lambda: moveu(0), 'd')

screen.listen()
screen.mainloop()

cdlane said in their 一样,你的乌龟只会向前移动。但是,你总是它朝向你想要的方向,然后让它往前走。相反,你应该检查它的当前方向,只有当它不与当前方向相反时才允许它移动。

这只需要对您的 moveu() 函数稍作修改:

def moveu(angle):
    current_heading = turtle.heading()
    if abs(angle - current_heading) != 180:
        turtle.setheading(angle)
        turtle.forward(20)

现在,如果您先按 w 再按 s,您的乌龟将不会向下移动。但是,如果你按w,然后按a,再按s,你的乌龟会先向左移动,然后向下移动。

这是一个演示:我修改了 cdlane 的演示,在 canvas 的底部添加了另一个乌龟来打印状态消息 Code。我在 moveu() 函数中添加了几行来打印按下了哪个键。

可以加上条件if (t.heading() + 180) % 360 != num:,意思是如果海龟当前航向的相反方向不是传入函数的数字方向,则继续:

import turtle
import random
import time

s = turtle.getscreen()
turtle.screensize(canvwidth=400, canvheight=400)
t = turtle.Turtle()
t.pensize(0)
t.shape('square')
t.color("black")
t.speed(0)
t.penup()

def moveu(num):
    if (t.heading() + 180) % 360 != num:
        t.setheading(num)
        t.forward(20)
    

s.onkey(lambda : moveu(90), 'w')
s.onkey(lambda : moveu(270), 's')
s.onkey(lambda : moveu(180), 'a')
s.onkey(lambda : moveu(0), 'd')
    
s.listen()
turtle.mainloop()

解决方案

所以,第一个问题是我没有在代码中看到 turtle.mainloop()。这意味着它不会保持打开状态。所以,这是对代码的第一次添加。

其次,使用简单的 if 语句可能就是您的答案。它比你想象的要简单得多。

但是,首先,让我们看看方向。


             90
              ↑
              |
              |
180  ←---- 'turtle' ----→ 0
              |
              |
              ↓
             270

因为,我假设,180 度是您认为向后的方向。如果不是,只需在最终代码中换入您想要的角度即可。


if语句如下。我已经在你的 moveu 功能中展示了它。


def moveu(num):
    if num != 180:
        t.setheading(num)
        t.forward(20)

这意味着,如果角度不是180,它会移动。因此,它不会向后移动。


最终代码


import turtle
import random
import time

s = turtle.getscreen()
turtle.screensize(canvwidth=400, canvheight=400)
t = turtle.Turtle()
t.pensize(0)
t.shape('square')
t.color('black')
t.speed(0)
t.penup()

def moveu(num):
    if num != 180:
        t.setheading(num)
        t.forward(20)
    

s.onkey(lambda : moveu(90), 'w')
s.onkey(lambda : moveu(270), 's')
s.onkey(lambda : moveu(180), 'a')
s.onkey(lambda : moveu(0), 'd')
    
s.listen()
s.mainloop()

如您所见,我添加了 turtle.mainloop()if 语句。