Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>Unfortunately, you are somewhat at the mercy of the underlying auto-repeat mechanism of your system. For example, on the mac I'm using at the moment if I press and hold "w" I'll get a stream of press and release events. While pressed, if I press "o" I get a stream of presses and releases for "o" but no more events for "w".</p> <p>You will need to set up a mini state machine, and bind to both key press and key release events. This will let you track which keys are pressed and which are not. Then, each time you draw a frame you can query the machine to see which keys are pressed and act accordingly.</p> <p>Here's a quick hack I threw together. I've only tested it on my mac, and only with python 2.5. I've made no real attempt at being "pythonic" or efficient. The code merely serves to illustrate the technique. With this code you can simultaneously press either "w" or "s" and "o" or "l" to move two paddles up and down. </p> <pre><code>'''Example that demonstrates keeping track of multiple key events''' from Tkinter import * class Playfield: def __init__(self): # this dict keeps track of keys that have been pressed but not # released self.pressed = {} self._create_ui() def start(self): self._animate() self.root.mainloop() def _create_ui(self): self.root = Tk() self.p1label = Label(text="press w, s to move player 1 up, down", anchor="w") self.p2label = Label(text="press o, l to move player 2 up, down", anchor="w") self.canvas = Canvas(width=440, height=440) self.canvas.config(scrollregion=(-20, -20, 420, 420)) self.p1label.pack(side="top", fill="x") self.p2label.pack(side="top", fill="x") self.canvas.pack(side="top", fill="both", expand="true") self.p1 = Paddle(self.canvas, tag="p1", color="red", x=0, y=0) self.p2 = Paddle(self.canvas, tag="p2", color="blue", x=400, y=0) self._set_bindings() def _animate(self): if self.pressed["w"]: self.p1.move_up() if self.pressed["s"]: self.p1.move_down() if self.pressed["o"]: self.p2.move_up() if self.pressed["l"]: self.p2.move_down() self.p1.redraw() self.p2.redraw() self.root.after(10, self._animate) def _set_bindings(self): for char in ["w","s","o", "l"]: self.root.bind("&lt;KeyPress-%s&gt;" % char, self._pressed) self.root.bind("&lt;KeyRelease-%s&gt;" % char, self._released) self.pressed[char] = False def _pressed(self, event): self.pressed[event.char] = True def _released(self, event): self.pressed[event.char] = False class Paddle(): def __init__(self, canvas, tag, color="red", x=0, y=0): self.canvas = canvas self.tag = tag self.x = x self.y = y self.color = color self.redraw() def move_up(self): self.y = max(self.y -2, 0) def move_down(self): self.y = min(self.y + 2, 400) def redraw(self): x0 = self.x - 10 x1 = self.x + 10 y0 = self.y - 20 y1 = self.y + 20 self.canvas.delete(self.tag) self.canvas.create_rectangle(x0,y0,x1,y1,tags=self.tag, fill=self.color) if __name__ == "__main__": p = Playfield() p.start() </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload