键盘输入无重复延迟



嘿,我正试图解决一个问题,我让一个角色使用WASD键在2D平面上移动。然而,当我按下按钮时,代码会写一次,然后延迟,然后不停地写。

如何消除这种延迟?我见过一些使用after((和canvas((的解决方案,但不确定如何将其应用于使用";text=";。

谢谢你的任何想法!

from tkinter import *
import tkinter as tk
coordinates = {
"x1y1": "", "x2y1": "", "x3y1": "", "x4y1": "", "x5y1": "", "x6y1": "", "x7y1": "", "x8y1": "", "x9y1": "",
"x1y2": "", "x2y2": "", "x3y2": "", "x4y2": "", "x5y2": "", "x6y2": "", "x7y2": "", "x8y2": "", "x9y2": "",
"x1y3": "", "x2y3": "", "x3y3": "", "x4y3": "", "x5y3": "", "x6y3": "", "x7y3": "", "x8y3": "", "x9y3": "",
"x1y4": "", "x2y4": "", "x3y4": "", "x4y4": "", "x5y4": "", "x6y4": "", "x7y4": "", "x8y4": "", "x9y4": "",
"x1y5": "", "x2y5": "", "x3y5": "", "x4y5": "", "x5y5": "", "x6y5": "", "x7y5": "", "x8y5": "", "x9y5": "",
"x1y6": "", "x2y6": "", "x3y6": "", "x4y6": "", "x5y6": "", "x6y6": "", "x7y6": "", "x8y6": "", "x9y6": "",
"x1y7": "", "x2y7": "", "x3y7": "", "x4y7": "", "x5y7": "", "x6y7": "", "x7y7": "", "x8y7": "", "x9y7": "",
"x1y8": "", "x2y8": "", "x3y8": "", "x4y8": "", "x5y8": "", "x6y8": "", "x7y8": "", "x8y8": "", "x9y8": "",
"x1y9": "", "x2y9": "", "x3y9": "", "x4y9": "", "x5y9": "", "x6y9": "", "x7y9": "", "x8y9": "", "x9y9": "",

}

#Player starting position
player_x = 5
player_y = 5

#Onpress update player X/Y positions and make sure they don't exceed coordinate system
def keypress_w(event):
global player_y
player_y -= 1
if player_y < 1:
player_y += 1
update_world()
def keypress_a(event):
global player_x
player_x -= 1
if player_x < 1:
player_x += 1
update_world()
def keypress_d(event):
global player_x
player_x += 1
if player_x > 9:
player_x -= 1
update_world()
def keypress_s(event):
global player_y
player_y += 1
if player_y > 9:
player_y -= 1
update_world()

def keypress_esc(event):
sys.exit()
def update_world():
#Create string with player coordinates and input into dictionary
player_xy = "x", player_x, "y", player_y
player_coord = ''.join(map(str, player_xy))
#Update previous player tile to map tile
coord_keys = coordinates.keys()
for coords in coord_keys:
if coords == player_coord:
coordinates[player_coord] = '€'
else:
coordinates[coords] = ' '
#Print map
width = 9
coord_values = coordinates.values()
i=0
world=""
for item in coord_values:
world = world + item + " "
i += 1
if i % width == 0:
world = world[:-1] + 'n'
world = world[:-1]
#refresh the label that displays the world
world_label.place(x=220,y=100)
world_label.configure(font=("Courier", 24), text=world, bg="white")

root = Tk() #Create window
world_label = Label() #Create World Label widget
world_label.pack()
update_world() #Function update_world

#Sends pressed key values to functions keypress_"x"
root.bind("<w>", keypress_w)
root.bind("<a>", keypress_a)
root.bind("<s>", keypress_s)
root.bind("<d>", keypress_d)
root.bind("<Escape>", keypress_esc) 

root.geometry("800x600") #Size of window 
root.title('Game 0.1') #Title of window 
root.mainloop() #

您可以使用定时器方法root.after(delay, func)来触发模拟键盘重复的功能。

新的演示代码为您。它对同时按下的两个键都有效。

from time import sleep
import tkinter as tk
class Root(tk.Tk):
def __init__(self, title, width, height):
super().__init__()
self.title(title)
self.width = width
self.height = height
self.canvas = tk.Canvas(self, width=width, height=height, bg='green')
self.canvas.pack()
self.geometry(f'{width}x{height}')
self.radius = 20
self.delay = 20
self.step = 5
self.x = width // 2
self.y = height // 2
self.press_left  = False
self.press_right = False
self.press_up    = False
self.press_down  = False
self.ball = None
self.draw_ball()
self.binding()
def draw_ball(self):
if self.ball:
self.canvas.delete(self.ball)
self.ball = self.canvas.create_oval(self.x - self.radius, self.y - self.radius,
self.x + self.radius, self.y + self.radius, fill='white')
self.canvas.update()
def binding(self):
self.bind("<KeyPress-a>",   self.left_down)
self.bind("<KeyPress-d>",   self.right_down)
self.bind("<KeyPress-w>",   self.up_down)
self.bind("<KeyPress-s>",   self.down_down)
self.bind("<KeyRelease-a>", self.left_up)
self.bind("<KeyRelease-d>", self.right_up)
self.bind("<KeyRelease-w>", self.up_up)
self.bind("<KeyRelease-s>", self.down_up)
self.bind("<Escape>",       self.escape)
def left_down(self, event):
def left():
if self.press_left:
if self.x >= self.radius + self.step:
self.x -= self.step
self.draw_ball()
self.after(self.delay, left)
else:
self.bind("<KeyPress-a>", self.left_down)
self.unbind("<KeyPress-a>")
self.press_left = True
left()
def left_up(self, event):
self.press_left = False
def right_down(self, event):
def right():
if self.press_right:
if self.x <= self.width - self.radius - self.step:
self.x += self.step
self.draw_ball()
self.after(self.delay, right)
else:
self.bind("<KeyPress-d>", self.right_down)
self.unbind("<KeyPress-d>")
self.press_right = True
right()
def right_up(self, event):
self.press_right = False
def up_down(self, event):
def up():
if self.press_up:
if self.y >= self.radius + self.step:
self.y -= self.step
self.draw_ball()
self.after(self.delay, up)
else:
self.bind("<KeyPress-w>", self.up_down)
self.unbind("<KeyPress-w>")
self.press_up = True
up()
def up_up(self, event):
self.press_up = False
def down_down(self, event):
def down():
if self.press_down:
if self.y <= self.height - self.radius - self.step:
self.y += self.step
self.draw_ball()
self.after(self.delay, down)
else:
self.bind("<KeyPress-s>", self.down_down)
self.unbind("<KeyPress-s>")
self.press_down = True
down()
def down_up(self, event):
self.press_down = False
def escape(self, event):
root.destroy()
root = Root("Game 0.1", 800, 600)
root.mainloop()

最新更新