我最近開始學習 Python,昨天我開始制作一種在 10x10 的 '#'-chars 地圖上移動 '@'-char(玩家)的基本方法。整個程序在以 while 回圈運行的 Shell 中運行良好。
今天我開始了嘗試學習 Tkinter 并將此代碼轉移到可重繪 視窗的冒險。我設法在視窗中列印了“地圖”,并讓鍵更新了表示“玩家位置”或玩家坐標的變數。
然而,我似乎無法輕松解決的一個大問題是如何真正使視窗重繪 或按鈕按下?或者不斷地為此。
希望代碼不會太難理解,我已經嘗試添加注釋來描述段。
對于這里的大多數人,我相信這段代碼會讓你的眼睛像我試圖解決的那樣流血,但請耐心等待!干杯!
import tkinter as tk
coordinates = {
"x1y1": "#", "x1y2": "#", "x1y3": "#", "x1y4": "#", "x1y5": "#", "x1y6": "#", "x1y7": "#", "x1y8": "#", "x1y9": "#", "x1y10": "#",
"x2y1": "#", "x2y2": "#", "x2y3": "#", "x2y4": "#", "x2y5": "#", "x2y6": "#", "x2y7": "#", "x2y8": "#", "x2y9": "#", "x2y10": "#",
"x3y1": "#", "x3y2": "#", "x3y3": "#", "x3y4": "#", "x3y5": "#", "x3y6": "#", "x3y7": "#", "x3y8": "#", "x3y9": "#", "x3y10": "#",
"x4y1": "#", "x4y2": "#", "x4y3": "#", "x4y4": "#", "x4y5": "#", "x4y6": "#", "x4y7": "#", "x4y8": "#", "x4y9": "#", "x4y10": "#",
"x5y1": "#", "x5y2": "#", "x5y3": "#", "x5y4": "#", "x5y5": "#", "x5y6": "#", "x5y7": "#", "x5y8": "#", "x5y9": "#", "x5y10": "#",
"x6y1": "#", "x6y2": "#", "x6y3": "#", "x6y4": "#", "x6y5": "#", "x6y6": "#", "x6y7": "#", "x6y8": "#", "x6y9": "#", "x6y10": "#",
"x7y1": "#", "x7y2": "#", "x7y3": "#", "x7y4": "#", "x7y5": "#", "x7y6": "#", "x7y7": "#", "x7y8": "#", "x7y9": "#", "x7y10": "#",
"x8y1": "#", "x8y2": "#", "x8y3": "#", "x8y4": "#", "x8y5": "#", "x8y6": "#", "x8y7": "#", "x8y8": "#", "x8y9": "#", "x8y10": "#",
"x9y1": "#", "x9y2": "#", "x9y3": "#", "x9y4": "#", "x9y5": "#", "x9y6": "#", "x9y7": "#", "x9y8": "#", "x9y9": "#", "x9y10": "#",
"x10y1":"#","x10y2": "#", "x10y3":"#", "x10y4":"#", "x10y5":"#", "x10y6":"#", "x10y7":"#", "x10y8":"#", "x10y9":"#", "x10y10":"#",
}
#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_x
player_x -= 1
if player_x < 1:
player_x = 1
def keypress_a(event):
global player_y
player_y -= 1
if player_y < 1:
player_y = 1
def keypress_d(event):
global player_y
player_y = 1
if player_y > 10:
player_y -= 1
def keypress_s(event):
global player_x
player_x = 1
if player_x > 10:
player_x -= 1
#Create string with player coordinates and input into dictionary
player_xy = "x", player_x, "y", player_y
player_coord = ''.join(map(str, player_xy))
coordinates[player_coord] = '@ '
#Update previous player tile to map tile
coord_keys = coordinates.keys()
for coords in coord_keys:
if coords != player_coord:
coordinates[coords] = '# '
#Print map
width = 10
coord_values = coordinates.values()
i=0
world=''
for item in coord_values:
world = world " " item
i = 1
if i % width == 0:
world = world '\n'
root = Tk()
label = tk.Label(text=world)
label.pack()
root.bind("<w>", keypress_w)
root.bind("<a>", keypress_a)
root.bind("<s>", keypress_s)
root.bind("<d>", keypress_d)
root.mainloop()
uj5u.com熱心網友回復:
基本策略是創建一個函式來更新螢屏上的世界。然后在游戲資料發生變化時呼叫該函式。
在您的特定情況下,這非常簡單 - 只需創建一個名為的函式update_world,其中包含繪制電路板的所有代碼。作為該功能的最后一步,您可以使用新資料更新標簽。
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))
coordinates[player_coord] = '@ '
#Update previous player tile to map tile
coord_keys = coordinates.keys()
for coords in coord_keys:
if coords != player_coord:
coordinates[coords] = '# '
#Print map
width = 10
coord_values = coordinates.values()
i=0
world=''
for item in coord_values:
world = world " " item
i = 1
if i % width == 0:
world = world '\n'
# refresh the label that displays the world.
label.configure(text=world)
需要修改創建的代碼,創建標簽后直接label呼叫update_world():
label = tk.Label()
label.pack()
update_world()
最后,您可以呼叫update_world()每個更新板資料的函式。
def keypress_w(event):
global player_x
player_x -= 1
if player_x < 1:
player_x = 1
update_world()
在您的特定情況下,這是非常低效的,因為您每次移動都要重新繪制整個板。更好的解決方案是使用比標簽更直接訪問的東西,例如Canvas小部件。這樣,您無需在每次迭代時重新繪制整個板,而只需移動用戶,而保持板的其余部分不變。例如,而不是update_world你會寫一個update_user方法。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/370467.html
