【问题标题】:Get keybindings to work in Python turtle获取在 Python turtle 中工作的键绑定
【发布时间】:2018-08-12 00:22:56
【问题描述】:

我正在尝试用 Python 和海龟制作一款寻宝游戏
目标是在屏幕上写入一个随机步骤,然后用户将使用箭头键按照指示进行操作,完成后按 Enter,然后将显示另一个步骤

我正在使用 trinket.io 对其进行编码

我知道我必须有一些方法来停止程序,但仍然允许用户在每一步之后用箭头移动海龟,但到目前为止我尝试过的方法没有奏效。

这是目前为止的程序:

################################################
##  This program simulates following a series ## 
##  of directions in a random order to see if ##
##  You will end up at the same place         ##
################################################

import turtle
import random

#############################
### Variable declareation ###
#############################

unit = 10 # this is the distance the turtle will move each time a key is pressed
hunt1 = turtle.Turtle() # turtle used in the first hunt
hunt2 = turtle.Turtle()# turtle used in the sedond hunt
hunt3 = turtle.Turtle()#turtle used in the third hunt

directions = turtle.Turtle()#used to print the steps
screen = turtle.Screen()# creates a Screen

koopa = [hunt1,hunt2,hunt3] # a collection of 'hunt' turtles
color = ['black','green','red']

map = ['Step 1', 'step 2', 'step3'] #this holds all the steps in the treasure hunt
x = random.randint(-50,0)
y = random.randint(-50,0)

next_step = False
#################
##  Functions  ##
#################
def set_koopa():
  c=0
  for i in koopa:
    i.penup()
    i.goto(x,y)
    i.color(color[c])
    i.pendown()
    c=c+1

def east():
  k.setheading(180)
  k.forward(unit)

def west():
  k.setheading(0)
  k.forward(unit)

def north():
  k.setheading(90)
  k.forward(unit)

def south():
  k.setheading(270)
  k.forward(unit)

def enter():
  next_step = True

##################
## key bindings ##
##################
screen.onkey(east, 'left')
screen.onkey(west, 'right')
screen.onkey(north, 'up')
screen.onkey(south, 'down')
screen.onkey(enter, 'enter')
screen.listen()# tells the compouter to listen for keystrokes

z=0 #debug
############
##  Main  ##
############
directions.goto(0,0)
directions.ht()
set_koopa()
for k in koopa:
  while len(map)!=0:   # checks if there are items left in the list
    l = len(map)       # returns the number if items
    directions.write(map.pop(random.randint(0,l-1))) #randomly takes an item and removes it and writes in on the screen
    while not next_step:  #gives time for user to move
      z=z+1#debug
      print z  #debug
      print next_step #debug

    directions.clear()

有问题的代码在底部。

我尝试的第一件事没有循环:

while not next_step:  #gives time for user to move
    z=z+1#debug
    print z  #debug
    print next_step #debug

相反,我有代码要求输入,但不允许用户移动海龟。

【问题讨论】:

    标签: python-3.x key-bindings turtle-graphics


    【解决方案1】:

    我不相信您的代码可以在标准 Python 附带的常规海龟下运行。首先,您标记了 [python-3.x],但您使用 Python 2 样式的打印语句。

    但更重要的是,您的事件逻辑被误导了。你不应该在等待海龟事件的时候紧紧循环:

    while not next_step:  #gives time for user to move
          z=z+1#debug
          print z  #debug
          print next_step #debug
    

    因为您可能会通过不将控制权交给事件处理程序来阻止事件。加上代码中的其他小错误(例如,缺少global 语句。)以下是我在标准 Python 2 或 Python 3 龟下大致运行的返工:

    ################################################
    ##  This program simulates following a series ##
    ##  of directions in a random order to see if ##
    ##  you will end up at the same place         ##
    ################################################
    
    from turtle import Turtle, Screen, mainloop
    from random import randint, choice
    
    #############################
    ### Variable declarations ###
    #############################
    
    unit = 10  # this is the distance the turtle will move each time a key is pressed
    
    directions = Turtle(visible=False)  # used to print the steps
    directions.penup()
    
    screen = Screen()  # creates a Screen
    
    koopa = {  # a collection of 'hunt' turtles
        'black': Turtle(visible=False),  # turtle used in the first hunt,
        'green': Turtle(visible=False),  # turtle used in the second hunt, 
        'red': Turtle(visible=False),  # turtle used in the third hunt,
    }
    
    steps = ['Step 1', 'Step 2', 'Step 3']  # this holds all the steps in the treasure hunt
    
    x = randint(-50, 0)
    y = randint(-50, 0)
    
    next_step = True
    
    active = None
    
    #################
    ##  Functions  ##
    #################
    
    def set_koopa():
        for color, hunt in koopa.items():
            hunt.penup()
            hunt.goto(x, y)
            hunt.color(color)
            hunt.pendown()
    
    def east():
        active.setheading(0)
        active.forward(unit)
    
    def west():
        active.setheading(180)
        active.forward(unit)
    
    def north():
        active.setheading(90)
        active.forward(unit)
    
    def south():
        active.setheading(270)
        active.forward(unit)
    
    def enter():
        global next_step
    
        next_step = True
    
    ##################
    ## key bindings ##
    ##################
    screen.onkey(east, 'Right')
    screen.onkey(west, 'Left')
    screen.onkey(north, 'Up')
    screen.onkey(south, 'Down')
    screen.onkey(enter, 'Return')
    screen.listen()  # tells the computer to listen for keystrokes
    
    ############
    ##  Main  ##
    ############
    
    set_koopa()
    
    def check_step():
        global active, next_step
    
        if next_step:
            next_step = False
    
            directions.clear()
    
            active = choice(list(koopa.values()))  # or somesuch
    
            active.showturtle()
    
            if steps:
                l = len(steps)  # returns the number if items
    
                directions.write(steps.pop(randint(0, l - 1)))  # randomly takes an item and removes it and writes in on the screen
    
            else:
                return
    
        screen.ontimer(check_step, 100)
    
    check_step()
    
    mainloop()
    

    【讨论】:

    • 感谢您的帮助。我确实错误地将帖子标记为 python 3。问题是缺少全局语句。您可以将 onkey() 和 listen() 与 trinket 一起使用。箭头键在我发布的代码中起作用,并且 trinket 有使用它们的示例。至少在 Trinket 和 Repl.it 中,onkey() 和 listen() 在程序运行的任何时候都可以工作。感谢您提供的详细程序。字典是我教的初学者课程中不需要的东西,所以我从没想过要使用它们,这是一个更好的解决方案。 (似乎我从来没有时间锻炼我的编码大脑,超出了我需要教的内容)
    • @Amber,我正在使用免费示例 Trinket 进行测试,因此可能不支持事件——我将编辑掉我的答案的那部分。我认为字典应该早点而不是晚点推出——我不敢相信教科书要等多久才会提到它们。 (特别是在 Perl 中,只有三种数据类型!)例如,JavaScript 更多的是关于字典而不是数组。我被指责使用字典来解决所有问题。有罪。
    猜你喜欢
    • 2021-09-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-08
    • 2013-07-22
    • 1970-01-01
    • 2022-11-25
    • 1970-01-01
    相关资源
    最近更新 更多