簡體   English   中英

Tkinter Python:使用 OOP 一次移動多個小部件對象?

[英]Tkinter Python: Moving Multiple widget objects at once with OOP?

我是一名 python 初學者,致力於使用 Tkinter 創建 2048 游戲。 到目前為止,我一直致力於讓多個圖塊具有相同的運動,遵循相同的一般行為。 為了做到這一點,我定義了一個 class,Tile,它定義了每個 tile 如何移動。 我的想法是我可以添加幾個瓷磚對象,它們會一致移動,就像在 2048 中一樣。但是,問題是 Tkinter Canvas 上的每個瓷磚在我按箭頭鍵時隨機移動。 如果我使用“”箭頭鍵三次,它將單獨移動三個瓷磚,隨機選擇下一個要移動的瓷磚。

我該如何解決這個問題,只需按一下箭頭鍵即可移動 canvas 上的所有圖塊?

這是我定義的 canvas:

from tkinter import * 
from tkinter.ttk import *

root = Tk()

w = 300
h = 300
my_canvas = Canvas(root, width=w, height=h, bg="white")

在這段代碼下面,我定義了我的 class,即在 canvas 中添加一個矩形並定義四個方向的運動

class Tile:
    def __init__(self, starting_x, starting_y):
        self.root = root
        self.x = 0
        self.y = 0
        self.starting_y = starting_y
        self.starting_x = starting_x
    self.tile = my_canvas.create_rectangle(starting_x, starting_y, starting_x + 25, starting_y + 25,fill="black")
    my_canvas.pack()



    self.movement()

def movement(self):
    root.bind("<Left>", self.left)
    root.bind("<Right>", self.right)
    root.bind("<Up>", self.up)
    root.bind("<Down>", self.down)

    my_canvas.move(self.tile, self.x, self.y)
    

    self.coordinates = []
    self.coordinates = my_canvas.coords(self.tile)
    if self.coordinates[0] == 0: self.x = 0
    if self.coordinates[2] == w: self.x = 0
    if self.coordinates[1] == 0: self.y = 0
    if self.coordinates[3] == h: self.y = 0
    my_canvas.after(1, self.movement)

def left(self, e):
    self.x = -1
    self.y = 0
    if self.coordinates[0] == 0:
        self.x = 0
        self.y = 0
def right(self, e):
    self.x = 1
    self.y = 0
    if self.coordinates[2] == w:
        self.x = 0
        self.y = 0
def up(self, e):
    self.x = 0
    self.y = -1
    if self.coordinates[1] == 0:
        self.x = 0
        self.y = 0
def down(self, e):
    self.x = 0
    self.y = 1
    if self.coordinates[3] == h:
        self.x = 0
        self.y = 0

最后,這里是我創建三個 Tile 對象的時候,然后是 root.mainloop():

if __name__ == "__main__":
    tile1 = Tile(0,0)
    tile2 = Tile(50,50)
    tile3 = Tile(100,100)

root.mainloop()

如您所見,所有三個圖塊都輸出了,但它們並沒有一致移動

看截圖

在此先感謝您的幫助!

問題是,移動中的命令my_canvas.move(self.tile, self.x, self.y)不知道要移動哪個圖塊。 為了使該程序正常工作,您必須保留一組可從 move movement() function 訪問的圖塊。

具體來說,我建議創建一個能夠自行移動並且確切知道它們所在的 canvas 的磁貼的全球列表:

class Tile:
    def __init__(self, canv, starting_x, starting_y):
        self.root = root
        self.canvas = canv
        self.x = 0
        self.y = 0
        self.starting_y = starting_y
        self.starting_x = starting_x
        self.idx = canv.create_rectangle(starting_x, starting_y, starting_x + 25, starting_y + 25,fill="black")
        canv.update()

    def moveleft(self): ## Add more methods for other movements
        if self.starting_x>25:
            self.starting_x -= 25
            self.canvas.move(self.idx,self.starting_x,self.starting_y)    

然后,您可以創建小部件和可以在 canvas 上移動的 Tile 對象列表。 在開頭而不是在 function 中指定綁定。

root = Tk()
w = 300
h = 300
my_canvas = Canvas(root, width=w, height=h, bg="white")
root.bind("<Left>", left)
root.bind("<Right>", right)
root.bind("<Up>", up)
root.bind("<Down>", down)


global tilelist
tilelist = []
tilelist.append(Tile(my_canvas,0,0))
tilelist.append(Tile(my_canvas,50,50))
tilelist.append(Tile(my_canvas,100,100))

您現在在全局列表中有一個可移動圖塊列表。 每個圖塊都可以在所有四個方向上移動(如果您完成了課程)。 現在你只需要一個移動 function 來移動它們:

def left():
    global tilelist
    for t in tilelist:
        t.moveleft()

這將移動你所有的瓷磚。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM