Reputation: 1909
When you press a button to move the "tank", it starts, but then it stops and starts again. Any way to make it not do that?
from tkinter import *
from tkinter.constants import LEFT
root = Tk()
c = Canvas(root, width=400, height=400)
tank = c.create_rectangle(200,200,250, 250, outline = 'dark green',
fill='dark green')
c.pack()
class Tank:
def move_left(self):
c.move(tank, -5, 0)
def move_right(self):
c.move(tank, 5,0)
def move_up(self):
c.move(tank, 0, -5)
def move_down(self):
c.move(tank, 0, 5)
c.bind('<Left>', Tank.move_left)
c.bind('<Right>', Tank.move_right)
c.bind('<Up>', Tank.move_up)
c.bind('<Down>', Tank.move_down)
c.focus_set()
root.mainloop()
Upvotes: 2
Views: 1691
Reputation: 531
You can use several booleans(up, right, left, down) representing if the tank is going a direction. When a key is pressed, set the boolean to true, and when it is released set the boolean false. Make a game loop using a seperate thread/while loop withimport threading
and in the game loop check if one of the booleans is true. For example, if the boolean representing right is true, then the program would add to the x-coordinate of the tank.
Upvotes: 1
Reputation: 365915
The first part of your problem is to capture KeyPress
and KeyRelease
events instead of key events.
But then things get complicated. You want the tank to move every, say, 120ms, not as fast as possible, right? So, the only thing you can do is setup an after
callback, so you can run some code every 120ms, and have the key events just set some flag that tells you how to move the tank (or not to move it) based on what's been pressed.
This is doable, but the next problem is even bigger: Tkinter captures key events at a high level—after any remapping your OS does (so you get E
instead of shift
and e
), which includes auto-repeat. To get around that, you have to write some code to do "debouncing" manually.
This is still doable, but it's not easy. And it's not perfect—pressing the keys rapidly can fool whatever debouncing algorithm you come up with, and pressing the keys rapidly is something you often want to allow in a game.
A better solution is probably to start over with a completely different library, like PyGame Zero, instead of Tkinter. A library designed for games will have a frame loop so you don't need to use after
and check a bunch of flags, will capture "raw" keyboard events so you can respond to them immediately, etc. And when you get further along and want to, e.g., use sprites for your tanks, you won't have to reinvent those wheels either, the way you would with Tkinter.
Upvotes: 0