【问题标题】:Why won't Python Turtle respond to my movement inputs?为什么 Python Turtle 不响应我的运动输入?
【发布时间】:2021-05-16 23:52:08
【问题描述】:

这学期我要上一门编码课程,其中一个项目要求我们制作任何类型的游戏。我选择制作一个包含在一个盒子中的游戏,敌人在屏幕上完全移动,然后再次出现在不同的 x 或 y 坐标处以增加一些变化。我正在处理的问题是添加创建“敌人”所需的代码之后,我为玩家乌龟的移动设置的键不再起作用,另一个奇怪的事情是玩家乌龟会在程序运行时原地旋转跑。我完全不知道如何让乌龟在为敌人编写代码之前正确地响应代码。我不相信敌人的代码是问题,因为当它被注释掉时,它的行为仍然相同。为简洁起见,我没有包含敌人代码。此代码是在 Python 3 中完成的。如果可以,请提供帮助! 编辑:我删除了 window.onkeypress(mov_x,"x") 后面的括号,在为敌人添加代码后它不会响应,它在没有敌人代码的情况下工作,但这有点删除了游戏。感谢您的帮助!

import turtle
import random
#screen
window = turtle.Screen()
window.title("Final Project Game")
window.bgcolor("gray")
window.setup(width=600,height=600)
#player
t= turtle.Turtle()
t.speed(5)
t.shape("triangle")
t.color("blue")
t.penup()
#player movement

def mov_rt():
    t.seth(0)
    t.fd(20)
def mov_lt():
    t.seth(180)
    t.fd(20)
def mov_up():
    t.seth(90)
    t.fd(20)
def mov_dw():
    t.seth(270)
    t.fd(20)


window.onkeypress(mov_rt,"d")
window.onkeypress(mov_lt,"a")
window.onkeypress(mov_up,"w")
window.onkeypress(mov_dw,"s")
window.listen()

#enemies
enemies = []
turt_num = turtle.numinput("Final","Number of Enemies", default=5, minval=1,maxval=10)
e_dir= [0,90,180,270]
if turt_num == 1:
    e1= turtle.Turtle("square",visible=False)
    e1.speed(5)
    e1.color("red")
    e1.penup()
    e1.setpos(random.randint(-290,290),random.randint(-290,290))
    e1.seth(random.choice(e_dir))
    enemies.append(e1)
    e1.st()
elif turt_num == 2:
    e1= turtle.Turtle("square",visible=False)
    e1.speed(5)
    e1.color("red")
    e1.penup()
    e1.setpos(random.randint(-290,290),random.randint(-290,290))
    e1.seth(random.choice(e_dir))
    enemies.append(e1)
    e2= turtle.Turtle("square",visible=False)
    e2.speed(5)
    e2.color("red")
    e2.penup()
    e2.setpos(random.randint(-290,290),random.randint(-290,290))
    e2.seth(random.choice(e_dir))
    enemies.append(e2)
    e1.st()
    e2.st()
elif turt_num ==3:
    e1= turtle.Turtle("square",visible=False)
    e1.speed(5)
    e1.color("red")
    e1.penup()
    e1.setpos(random.randint(-290,290),random.randint(-290,290))
    e1.seth(random.choice(e_dir))
    enemies.append(e1)
    e2= turtle.Turtle("square",visible=False)
    e2.speed(5)
    e2.color("red")
    e2.penup()
    e2.setpos(random.randint(-290,290),random.randint(-290,290))
    e2.seth(random.choice(e_dir))
    enemies.append(e2)
    e3= turtle.Turtle("square",visible=False)
    e3.speed(5)
    e3.color("red")
    e3.penup()
    e3.setpos(random.randint(-290,290),random.randint(-290,290))
    e3.seth(random.choice(e_dir))
    enemies.append(e3)
    e1.st()
    e2.st()
    e3.st()

#borders
def border(): #if you hold down the button it wont reappear bc youre still moving while the turtle is trying to move to the desired target
    tx, ty= t.pos()
    if t.xcor() >295:
        t.ht()
        t.setpos(-295,ty)
        t.st()
    if t.xcor() <-295:
        t.ht()
        t.setpos(295,ty)
        t.st()
    if t.ycor() >295:
        t.ht()
        t.setpos(tx,-295)
        t.st()
    if t.ycor() <-295:
        t.ht()
        t.setpos(tx,295)
        t.st()



#main game loop
while True:
    window.update()
    border()
turtle.mainloop()

【问题讨论】:

  • 我对海龟很生疏,但底部的循环很可疑。 while True 循环永远不会退出,所以turtle.mainloop() 永远不会运行。
  • window.onkeypress(mov_rt(),"d") 只调用了一次mov_rt 函数,就在那个时刻,然后将其返回值(即None)分配为稍后按下“d”的处理程序钥匙。您想在此处将 函数本身(因此只需 mov_rt 不带括号)作为参数传递。

标签: python python-turtle


【解决方案1】:

尝试使用

window.onkey()

这是一种不同的聆听方式,它的作用完全相同。 另外,请记住您需要的代码的末尾

window.listen()

【讨论】:

    【解决方案2】:

    初学者的常见错误。而不是:

    window.onkeypress(mov_rt(),"d")
    window.onkeypress(mov_lt(),"a")
    window.onkeypress(mov_up(),"w")
    window.onkeypress(mov_dw(),"s")
    

    做:

    window.onkeypress(mov_rt, "d")
    window.onkeypress(mov_lt, "a")
    window.onkeypress(mov_up, "w")
    window.onkeypress(mov_dw, "s")
    

    也就是说,您不想调用您的事件处理函数,而是想传递您的事件处理函数的名称以便系统稍后调用,当事情真正发生时。

    以下是您的代码的修改,以解决此问题以及其他一些海龟和 Python 问题:

    from turtle import Screen, Turtle
    
    def border():
        x, y = turtle.position()
    
        if x > 295:
            turtle.hideturtle()
            turtle.setx(-295)
            turtle.showturtle()
        elif x < -295:
            turtle.hideturtle()
            turtle.setx(295)
            turtle.showturtle()
    
        if y > 295:
            turtle.hideturtle()
            turtle.sety(-295)
            turtle.showturtle()
        elif y < -295:
            turtle.hideturtle()
            turtle.sety(295)
            turtle.showturtle()
    
    # player movement
    def mov_rt():
        turtle.setheading(0)
        turtle.forward(20)
        border()
    
    def mov_lt():
        turtle.setheading(180)
        turtle.forward(20)
        border()
    
    def mov_up():
        turtle.setheading(90)
        turtle.forward(20)
        border()
    
    def mov_dw():
        turtle.setheading(270)
        turtle.forward(20)
        border()
    
    screen = Screen()
    screen.title("Final Project Game")
    screen.bgcolor('gray')
    screen.setup(width=600, height=600)
    
    # player
    turtle = Turtle()
    turtle.speed('normal')
    turtle.shape('triangle')
    turtle.color('blue')
    turtle.penup()
    
    screen.onkeypress(mov_rt, 'd')
    screen.onkeypress(mov_lt, 'a')
    screen.onkeypress(mov_up, 'w')
    screen.onkeypress(mov_dw, 's')
    screen.listen()
    
    screen.mainloop()
    

    注意删除while True: 循环,因为它在turtle 这样的事件驱动环境中没有位置——它可能会阻止事件被处理。

    【讨论】:

    • 只是为了澄清开始位,screen.onkeypress() 位中没有括号。他们在你回答之前吗?
    • @PythonProgrammer,是的,我相信他们在我的回答和大约同时出现的 jasonharper 的评论后大约 10 分钟编辑了他们的代码。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-11-25
    • 1970-01-01
    • 1970-01-01
    • 2021-01-12
    • 2023-01-27
    • 1970-01-01
    • 2017-12-05
    相关资源
    最近更新 更多