2013-01-20 49 views
1

我正在嘗試使用Tkinter編寫一個Snake遊戲程序 我的蛇由下面定義的Circle列表組成。但是,當我調用移動方法時,最後一個不移動。問題是什麼?Tkinter - Canvas.move()不移動列表中的最後一項

class Circle: 

    def __init__(self,canv,x,y,index,direc): 
     self._x = x 
     self._y = y 
     self._index = index 
     self._direction = direc 
     self._canvas = canv 
     coordinat = (self._x)-5,(self._y)-5,(self._x)+5,(self._y)+5 

     if index==0: 
      color = "gold" 
     else: 
      color = "green" 

     self._circle = canv.create_oval(coordinat ,fill=color, tags=str(self._index)) 

    def _move(self): 
     if self._direction == "up": 
     delta = (0,-5) 
     elif self._direction == "down": 
     delta = (0,5) 
     elif self._direction == "left": 
     delta = (-5,0) 
     elif self._direction == "right": 
     delta = (5,0) 

     tag = str(self._index) 
     self._canvas.move(tag, delta[0],delta[1]) 

她是我如何稱呼它

self._canvas = Canvas(self._playArea,width=750,height=450,bg="#1C1C1C") 
    x = int(self._parent.winfo_width()/4.) 
    y = int(self._parent.winfo_height()/ 4.) 
    circle = Circle(self._canvas,x,y,0,"right") 
    self._circleList.append(circle) 
    self._addCircle() 
    self._addCircle() 
    self._addCircle() 
    self._addCircle() 
    self._addCircle() 

    self._canvas.place(x=0, y=0) 

    for i in range(0,500): 
     for x in self._circleList: 
      x._move() 
      root.update() 
      root.after(10) 

,這是addCircle方法

length = len(self._circleList) 
    if self._circleList[length-1]._direction == "right": 
     x = (self._circleList[length-1]._x)-10 
     y = self._circleList[length-1]._y 
     d = "right" 
    elif self._circleList[length-1]._direction == "left": 
     x = (self._circleList[length-1]._x) + 10 
     y = self._circleList[length-1]._y 
     d = "left" 
    elif self._circleList[length-1]._direction == "up": 
     x = self._circleList[length-1]._x 
     y = (self._circleList[length-1]._y)+10 
     d = "up" 
    elif self._circleList[length-1]._direction == "down": 
     x = self._circleList[length-1]._x 
     y = (self._circleList[length-1]._y)-10 
     d = "down" 

    newCircle = Circle(self._canvas,x,y,length,d) 
    self._circleList.append(newCircle) 
+0

千萬不要調用'update'。另外,如果您將您的代碼列表更改爲自包含,則有人可能會查看它。 – mmgp

回答

1

的問題是,您要創建的第一個項目,index=0,然後使用即index作爲識別該項目的標記。你不應該使用整數作爲標籤,這是爲項目的ID保留的,但是,畢竟你可以使用它。除了0被Tcl評估爲false之外,所以你沒有爲它定義任何標籤。事實證明,當您撥打canvas.move(0, ...)時,您不會移動任何創建的圈子。但是您創建的下一個項目會被分配一個標籤「1」,並且當您致電canvas.move(1, ...)時,實際上您正在移動之前創建的項目(具有「黃金」顏色的項目),因爲它由Tcl自動分配ID「1」。重複所有其他創建的圈子。

解決問題的快速方法是更改​​代碼以使用index + 1表示您傳遞的所有這些索引。但也有在你包含代碼的幾個問題,所以這裏是執行你所追求的修改之一:

import Tkinter 

UP, RIGHT, DOWN, LEFT = range(4) 

class Circle: 
    def __init__(self, canv, x, y, direc, color): 
     self.x, self.y = x, y 
     self.direction = direc 

     self._canvas = canv 
     coord = (self.x)-5, (self.y)-5, (self.x)+5, (self.y)+5 
     self._index = canv.create_oval(coord, fill=color) 

    def move(self): 
     y_sign = 1 if self.direction == DOWN else -1 
     x_sign = 1 if self.direction == RIGHT else -1 
     if self.direction in (UP, DOWN): 
      delta = (0, y_sign * 5) 
     else: 
      delta = (x_sign * 5, 0) 
     self._canvas.move(self._index, delta[0], delta[1]) 


def add_circle(canvas, l): 
    d = l[-1].direction 
    if d in (UP, DOWN): 
     x = l[-1].x 
     y = (1 if d == UP else -1) * 10 + l[-1].y 
    else: 
     x = (1 if d == LEFT else -1) * 10 + l[-1].x 
     y = l[-1].y 

    circle = Circle(canvas, x, y, d, "green") 
    l.append(circle) 


def move_circles(circle_l, root): 
    for c in circle_l: 
     c.move() 
    root.after(50, lambda: move_circles(circle_l, root)) 

root = Tkinter.Tk() 
width, height = 750, 450 

canvas = Tkinter.Canvas(width=width, height=height, bg="#1C1C1C") 
canvas.pack(fill=None, expand=False) 

circle_l = [] 
circle = Circle(canvas, width/4, height/4, RIGHT, "gold") 
circle_l.append(circle) 
for _ in range(5): 
    add_circle(canvas, circle_l) 

move_circles(circle_l, root) 

root.mainloop() 
+0

感謝您的幫助。當我用str(index + 1)替換str(index)時,問題就解決了。我在這裏發佈的代碼只是一個測試用例,不是最終的代碼。我正在努力學習Tkinter的工作原理。我會改變很多謝謝.. – uLtRaLoVeR

0

不是一個真正的答案,但你可以讓你的最後一段代碼短了很多/多高效:

length = len(self._circleList) 
    x = self._circleList[length-1]._x 
    y = self._circleList[length-1]._y 
    d = self._circleList[length-1]._direction 

    if d == "right": 
     x -= 10 
    elif d == "left": 
     x += 10 
    elif d == "up": 
     y += 10 
    elif d == "down": 
     y -= 10 

    newCircle = Circle(self._canvas,x,y,length,d) 
    self._circleList.append(newCircle) 

設置默認值,然後再只修改xy,如果他們必須如此。

相關問題