【问题标题】:Tkinter & Turtle Etch-a-SketchTkinter 和 Turtle Etch-a-Sketch
【发布时间】:2020-05-13 22:52:21
【问题描述】:

我一直在制作一个类似于 etch-a-sketch 的程序,您可以在其中使用箭头键进行绘图。我注意到我不能像向上和向左箭头键那样按住两个键来穿过屏幕。这可能吗?我该怎么做?

到目前为止,这是我的代码:

import tkinter as tk
import turtle

def k1(event):
    t.forward(1)

def k2(event):
    t.left(1)

def k3(event):
    t.right(1)

def k4(event):
    t.back(1)

window = tk.Tk()

window.geometry("750x500")
window.resizable(False, False)

canvas = tk.Canvas(master=window, width=500, height=500, bg="white")
canvas.pack()

t = turtle.RawTurtle(canvas)

window.bind("<Up>", k1)
window.bind("<Left>", k2)
window.bind("<Right>", k3)
window.bind("<Down>", k4)

window.mainloop()

【问题讨论】:

  • 我不明白你的问题。当我按向左或向右箭头时,屏幕上的箭头会旋转,然后我向前按,它会朝那个方向移动。它适用于所有方向,那么“跨屏幕”是什么意思?对我来说,它会在任何方向穿过屏幕。除非您希望它在转动的同时继续前进,否则您应该在问题中澄清这一点。
  • 我的意思是这样你就可以同时按住向上和向左,这样它就会朝 \ 方向移动,而不是在向上和向左键之间切换。
  • 如果是这种情况,请查看这篇文章。 stackoverflow.com/a/44086242/7475225 。单独的普通绑定不能做你想要的。但是有了一些附加功能,您就可以到达那里。

标签: python tkinter turtle-graphics tkinter-canvas


【解决方案1】:

通过将 Josselin 在这篇帖子 Press 2 keys at once to move diagonally tkinter? 上使用的方法与您的海龟相结合,我们可以捕获按下多个键的时间以及如何处理。

此代码允许您一次按多个键以获得至少一个旋转动作。

import tkinter as tk
import turtle


window = tk.Tk()
window.geometry("750x500")
window.resizable(False, False)
pressedStatus = {"Up": False, "Down": False, "Left": False, "Right": False}
canvas = tk.Canvas(master=window, width=500, height=500, bg="white")
canvas.pack()

t = turtle.RawTurtle(canvas)

def pressed(event):
    pressedStatus[event.keysym] = True

def released(event):
    pressedStatus[event.keysym] = False

def set_bindings():
    for char in ["Up", "Down", "Left", "Right"]:
        window.bind("<KeyPress-%s>" % char, pressed)
        window.bind("<KeyRelease-%s>" % char, released)

def animate():
    if pressedStatus["Up"]: t.forward(1)
    if pressedStatus["Down"]: t.back(1)
    if pressedStatus["Left"]: t.left(1)
    if pressedStatus["Right"]: t.right(1)
    canvas.update()
    window.after(10, animate)

set_bindings()
animate()
window.mainloop()

通过更多的工作和另一个字典来跟踪旋转,我们可以得到你想要的任何角度的对角线。我假设 45 度是目标,所以试试下面的。

import tkinter as tk
import turtle


window = tk.Tk()
window.geometry("750x500")
window.resizable(False, False)
pressed_status = {"Up": False, "Down": False, "Left": False, "Right": False}
rotation_lock = {"Left": False, "Right": False}  # use to lock the rotation event so we cont constantly rotate.
canvas = tk.Canvas(master=window, width=500, height=500, bg="white")
canvas.pack()

t = turtle.RawTurtle(canvas)

def pressed(event):
    pressed_status[event.keysym] = True

def released(event):
    pressed_status[event.keysym] = False
    if event.keysym == 'Left' or event.keysym == 'Right':
        rotation_lock[event.keysym] = False

def set_bindings():
    for char in ["Up", "Down", "Left", "Right"]:
        window.bind("<KeyPress-%s>" % char, pressed)
        window.bind("<KeyRelease-%s>" % char, released)

def animate():
    # By first checking if 2 keys are pressed we can make sure we get the rotation we are looking for.
    # Then if not 2 keys then process single keys.
    # We also want to lock the rotation after our first rotation as to not constantly turn at a 45 degree angle.
    if pressed_status["Up"] and pressed_status["Left"]:
        t.forward(1)
        if not rotation_lock['Left']:
            rotation_lock['Left'] = True
            t.left(45)
    elif pressed_status["Up"] and pressed_status["Right"]:
        t.forward(1)
        t.right(1)
        if not rotation_lock['Right']:
            rotation_lock['Right'] = True
            t.right(45)
    elif pressed_status["Down"] and pressed_status["Left"]:
        t.back(1)
        if not rotation_lock['Left']:
            rotation_lock['Left'] = True
            t.left(45)
    elif pressed_status["Down"] and pressed_status["Right"]:
        t.back(1)
        if not rotation_lock['Right']:
            rotation_lock['Right'] = True
            t.right(45)

    elif pressed_status["Up"]: t.forward(1)
    elif pressed_status["Down"]: t.back(1)
    elif pressed_status["Left"]: t.left(1)
    elif pressed_status["Right"]: t.right(1)
    canvas.update()
    window.after(40, animate)

set_bindings()
animate()
window.mainloop()

如果我们在混音中添加第三个键,我们可以选择在对角线和曲线之间切换。

看看这个例子:

import tkinter as tk
import turtle


window = tk.Tk()
window.geometry("750x500")
window.resizable(False, False)
pressed_status = {"Up": False, "Down": False, "Left": False, "Right": False, "Control_L": False}
rotation_lock = {"Left": False, "Right": False}  # use to lock the rotation event so we cont constantly rotate.
canvas = tk.Canvas(master=window, width=500, height=500, bg="white")
canvas.pack()

t = turtle.RawTurtle(canvas)

def pressed(event):
    pressed_status[event.keysym] = True

def released(event):
    pressed_status[event.keysym] = False
    if event.keysym == 'Left' or event.keysym == 'Right':
        rotation_lock[event.keysym] = False

def set_bindings():
    for char in ["Up", "Down", "Left", "Right", "Control_L"]:
        window.bind("<KeyPress-%s>" % char, pressed)
        window.bind("<KeyRelease-%s>" % char, released)

def animate():
    # By first checking if 2 keys are pressed we can make sure we get the rotation we are looking for.
    # Then if not 2 keys then process single keys.
    # We also want to lock the rotation after our first rotation as to not constantly turn at a 45 degree angle.
    if pressed_status["Up"] and pressed_status["Left"]:
        t.forward(1)
        if pressed_status["Control_L"]:
            t.left(1)
        else:
            if not rotation_lock['Left']:
                rotation_lock['Left'] = True
                t.left(45)
    elif pressed_status["Up"] and pressed_status["Right"]:
        t.forward(1)
        if pressed_status["Control_L"]:
            t.right(1)
        else:
            if not rotation_lock['Right']:
                rotation_lock['Right'] = True
                t.right(45)
    elif pressed_status["Down"] and pressed_status["Left"]:
        t.back(1)
        if pressed_status["Control_L"]:
            t.left(1)
        else:
            if not rotation_lock['Left']:
                rotation_lock['Left'] = True
                t.left(45)
    elif pressed_status["Down"] and pressed_status["Right"]:
        t.back(1)
        if pressed_status["Control_L"]:
            t.right(1)
        else:
            if not rotation_lock['Right']:
                rotation_lock['Right'] = True
                t.right(45)

    elif pressed_status["Up"]: t.forward(1)
    elif pressed_status["Down"]: t.back(1)
    elif pressed_status["Left"]: t.left(1)
    elif pressed_status["Right"]: t.right(1)
    canvas.update()
    window.after(40, animate)

set_bindings()
animate()
window.mainloop()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-06-26
    • 1970-01-01
    • 1970-01-01
    • 2017-10-11
    • 1970-01-01
    • 2020-05-17
    • 2016-09-12
    • 1970-01-01
    相关资源
    最近更新 更多