#python #tkinter
#питон #tkinter
Вопрос:
Эй, я пытаюсь решить проблему, в которой персонаж перемещается по 2D-плоскости с помощью клавиш WASD. Однако, когда я удерживаю кнопку, код записывается один раз, затем делает задержку, а затем пишет без остановки.
Как устранить эту задержку? Я видел некоторые решения, использующие 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 lt; 1: player_y = 1 update_world() def keypress_a(event): global player_x player_x -= 1 if player_x lt; 1: player_x = 1 update_world() def keypress_d(event): global player_x player_x = 1 if player_x gt; 9: player_x -= 1 update_world() def keypress_s(event): global player_y player_y = 1 if player_y gt; 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("lt;wgt;", keypress_w) root.bind("lt;agt;", keypress_a) root.bind("lt;sgt;", keypress_s) root.bind("lt;dgt;", keypress_d) root.bind("lt;Escapegt;", keypress_esc) root.geometry("800x600") #Size of window root.title('Game 0.1') #Title of window root.mainloop() #
Комментарии:
1. Это конфигурация системы на клавиатурном устройстве.
Ответ №1:
Вы можете использовать метод таймера 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("lt;KeyPress-agt;", self.left_down) self.bind("lt;KeyPress-dgt;", self.right_down) self.bind("lt;KeyPress-wgt;", self.up_down) self.bind("lt;KeyPress-sgt;", self.down_down) self.bind("lt;KeyRelease-agt;", self.left_up) self.bind("lt;KeyRelease-dgt;", self.right_up) self.bind("lt;KeyRelease-wgt;", self.up_up) self.bind("lt;KeyRelease-sgt;", self.down_up) self.bind("lt;Escapegt;", self.escape) def left_down(self, event): def left(): if self.press_left: if self.x gt;= self.radius self.step: self.x -= self.step self.draw_ball() self.after(self.delay, left) else: self.bind("lt;KeyPress-agt;", self.left_down) self.unbind("lt;KeyPress-agt;") 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 lt;= self.width - self.radius - self.step: self.x = self.step self.draw_ball() self.after(self.delay, right) else: self.bind("lt;KeyPress-dgt;", self.right_down) self.unbind("lt;KeyPress-dgt;") 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 gt;= self.radius self.step: self.y -= self.step self.draw_ball() self.after(self.delay, up) else: self.bind("lt;KeyPress-wgt;", self.up_down) self.unbind("lt;KeyPress-wgt;") 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 lt;= self.height - self.radius - self.step: self.y = self.step self.draw_ball() self.after(self.delay, down) else: self.bind("lt;KeyPress-sgt;", self.down_down) self.unbind("lt;KeyPress-sgt;") 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()
Комментарии:
1. Большое спасибо! Я поиграю с этим и попытаюсь внедрить в свой код!