【问题标题】:How to know when a certain sequence of chars is typed?如何知道何时输入了某个字符序列?
【发布时间】:2015-08-24 13:43:55
【问题描述】:

我正在编写一个类似愤怒的小鸟的游戏,我希望当玩家输入“g”,然后是“o”,然后是“d”(“god”,代表“上帝模式”)时,一个目标将出现在鸟当前(给定度数和初始速度)降落的地方(如果你开火的话)。 - 神模式在游戏中可用 3 次。

所以我尝试了类,并存储每个最后两个键入的字符: [我使用 tkinter 和 Image,来自 PIL 的 ImageTk]

class GodMode:

times_left = 3   # Default

def __init__(self, master, image_file):
    self.master = master
    self.target_image = Image.open(image_file) 
    self.target = ImageTk.PhotoImage(self.target_image.resize((RED_CROSS_WIDTH, RED_CROSS_HEIGHT), Image.ANTIALIAS))

def display(self, bird):
    self.times_left -= 1
    self.x = physics.distance_traveled(bird)
    self.y = TARGET_Y_LOCATION
    self.master.create_image(self.x, self.y, image = self.target)

def typing_god(self, keystroke, bird):
    '''This function is first called when "g" is typed, from another 
    function (who is binded in the "main" function)
    '''
    if keystroke is None:
        self.last_char = "g"
    else:
        if keystroke.char == "d" or keystroke.char == "D":
            if self.last_char == "o" and self.char_before_last == "g":
                if self.times_left == 3:
                    self.god_mode_start(bird)
                elif 0 < self.times_left:
                    self.god_mode_alert(bird)
                else:
                    help_over()
                    return
        else:
            self.char_before_last = self.last_char
            self.last_char = keystroke.char
    self.master.bind('<Key>', lambda event: typing_god(event, bird))

def god_mode_start(self):
    start_input = messagebox.askyesno(title = "GOD Mode", message = "The god mode is only optional 3 times. Are you sure?")
    if not start_input:
        return
    self.display(bird)

def god_mode_alert(self, bird):
    start = messagebox.showinfinfo(title = "GOD Mode", message = GOD_MODE_FORMAT % self.gode_mode_left)
    if not start:
        return
    self.display(bird)

@staticmethod
def help_over():
    messagebox.showinfo(title = "GOD Mode not available", message = "You have used all your help.")

...但这不起作用,我不知道为什么。

非常感谢您的帮助!

大卫

【问题讨论】:

  • 但究竟是什么错误?
  • 没有错误,它根本不起作用。如果你开火,目标不会出现在鸟会着陆的地方。
  • self.master.bind('&lt;Key&gt;', lambda event: typing_god(event, bird)) 看起来很可疑 - 您是否尝试在 GodMode 类中调用 typing_god?如果是这样,那么您应该将其更改为self.typing_god
  • 你是对的。我改了,还是不行。
  • 对于额外的挑战,编写一个同样适用于作弊码“XYZZY”和“idspispopd”的解决方案,并且不使用名为char_before_char_before_char_before_char_before_char_before_char_before_char_before_char_before_char_before_last的变量。

标签: python tkinter key-bindings


【解决方案1】:

看起来self.master.bind('&lt;Key&gt;', lambda event: typing_god(event, bird)) 可能永远不会被调用,您是否在此语句周围添加了打印以检查?

你可能想把它放在构造函数中,并使用self.typing_god

def __init__(self, master, image_file):
    self.master = master
    self.target_image = Image.open(image_file) 
    self.target = ImageTk.PhotoImage(self.target_image.resize((RED_CROSS_WIDTH, RED_CROSS_HEIGHT), Image.ANTIALIAS))
    # Add a debug statement to check that this method is getting called
    print "Binding key events to self.typing_god"
    # Bind the key down event in the constructor
    self.master.bind('<Key>', lambda event: self.typing_god(event, bird))

【讨论】:

    【解决方案2】:

    您可以在进行绑定时将事件串在一起。因此,例如,您可以绑定三个字符序列“上帝”(例如:"&lt;g&gt;&lt;o&gt;&lt;d&gt;"

    def god_mode(event):
        print("god mode is activated")
    some_widget.bind("<g><o><d>", god_mode)
    

    假设some_widget 具有键盘焦点,当您按“g”、“o”和“d”键的顺序时,将打印消息。

    这是使用虚拟事件的好机会。您可以定义自己的事件并绑定到它:

    some_widget.event_add("<<GodMode>>", "<g><o><d>")
    some_widget.bind("<<GodMode>>", god_mode)
    

    【讨论】:

      【解决方案3】:

      我会为此使用deque。您可以设置maxlen = 3。当您获得新的击键时,您可以附加到它。检查deque 中是否有god 也很容易:

      In [1]: from collections import deque
      In [2]: d = deque(maxlen=3)
      In [3]: d.append('g') # new keystroke
      In [4]: d.append('o') # new keystroke
      In [5]: d.append('d') # new keystroke
      In [6]: d
      Out[6]: deque(['g', 'o', 'd'], maxlen=3)
      In [7]: ''.join(d) == 'god'  # check if we already in the god mode
      Out[7]: True
      In [8]: d.append('x') # new keystroke
      In [9]: d
      Out[9]: deque(['o', 'd', 'x'], maxlen=3)
      In [10]: ''.join(d) == 'god' # check if we already in the god mode
      Out[10]: False
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-08-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-05-08
        • 1970-01-01
        • 2021-05-31
        相关资源
        最近更新 更多