Wil*_*ong 4 python tk-toolkit tkinter python-2.7
我正在为大学做一个python跳棋游戏.我使用tk绘制了电路板,但我似乎无法为这些部件实现移动功能.如果有人在我的代码中看到任何错误,或者可以提供帮助,我将不胜感激.这是完整的来源.提前致谢.
我知道这会吸引棋子.我不知道如何重新绘制碎片,而不删除其他碎片.我已经在线查看了移动功能,并尝试了简单的测试,但我无法在我的代码中使用它.
lst2 = []
#counter variable
i=0
#board variable is what stores the X/O/- values.
# It's a 2D list. We iterate over it, looking to see
# if there is a value that is X or O. If so, we draw
# text to the screen in the appropriate spot (based on
# i and j.
while i < len(board):
  j=0
  while j < len(board[i]):
    if board[i][j] == 2:
      lst2.append(canvas.create_oval((i+1)*width + width/2 + 15,
        (j+1)*height + height/2 +15,(i+1)*width + width/2 - 15,
        (j+1)*width + width/2 - 15, fill="Red",outline='Black'))
    elif board[i][j] == 4:
      lst2.append(canvas.create_oval((i+1)*width + width/2 + 15,
        (j+1)*height + height/2 +15,(i+1)*width + width/2 - 15,
        (j+1)*width + width/2 - 15, fill="Red",outline='Black'))
    elif board[i][j] == 1:
      lst2.append(canvas.create_oval((i+1)*width + width/2 + 15,
        (j+1)*height + height/2 +15,(i+1)*width + width/2 - 15,
        (j+1)*width + width/2 - 15, fill="Black",outline='Black'))
    elif board[i][j] == 3:
      lst2.append(canvas.create_oval((i+1)*width + width/2 + 15,
        (j+1)*height + height/2 +15,(i+1)*width + width/2 - 15,
        (j+1)*width + width/2 - 15, fill="Black",outline='Black'))
    j+=1
  i+=1
Bry*_*ley 29
您可以使用坐标和/或移动方法在画布上移动项目,以将坐标从它们更改为您想要的坐标.
这是一个简单的示例,展示如何在画布上创建和移动项目:
import tkinter as tk     # python 3
# import Tkinter as tk   # python 2
class Example(tk.Frame):
    '''Illustrate how to drag items on a Tkinter canvas'''
    def __init__(self, parent):
        tk.Frame.__init__(self, parent)
        # create a canvas
        self.canvas = tk.Canvas(width=400, height=400)
        self.canvas.pack(fill="both", expand=True)
        # this data is used to keep track of an 
        # item being dragged
        self._drag_data = {"x": 0, "y": 0, "item": None}
        # create a couple of movable objects
        self._create_token((100, 100), "white")
        self._create_token((200, 100), "black")
        # add bindings for clicking, dragging and releasing over
        # any object with the "token" tag
        self.canvas.tag_bind("token", "<ButtonPress-1>", self.on_token_press)
        self.canvas.tag_bind("token", "<ButtonRelease-1>", self.on_token_release)
        self.canvas.tag_bind("token", "<B1-Motion>", self.on_token_motion)
    def _create_token(self, coord, color):
        '''Create a token at the given coordinate in the given color'''
        (x,y) = coord
        self.canvas.create_oval(x-25, y-25, x+25, y+25, 
                                outline=color, fill=color, tags="token")
    def on_token_press(self, event):
        '''Begining drag of an object'''
        # record the item and its location
        self._drag_data["item"] = self.canvas.find_closest(event.x, event.y)[0]
        self._drag_data["x"] = event.x
        self._drag_data["y"] = event.y
    def on_token_release(self, event):
        '''End drag of an object'''
        # reset the drag information
        self._drag_data["item"] = None
        self._drag_data["x"] = 0
        self._drag_data["y"] = 0
    def on_token_motion(self, event):
        '''Handle dragging of an object'''
        # compute how much the mouse has moved
        delta_x = event.x - self._drag_data["x"]
        delta_y = event.y - self._drag_data["y"]
        # move the object the appropriate amount
        self.canvas.move(self._drag_data["item"], delta_x, delta_y)
        # record the new position
        self._drag_data["x"] = event.x
        self._drag_data["y"] = event.y
if __name__ == "__main__":
    root = tk.Tk()
    Example(root).pack(fill="both", expand=True)
    root.mainloop()
第六次编辑:这里有两个解决方案供您使用:
第五次编辑:好的,谢谢您删除代码。
准确解释一下您的绘图代码有什么问题?“移动的片段没有从旧位置删除”?“所有的作品都绘制在错误的坐标或颜色上”?...? 仅仅不断地转储代码并说“此代码不起作用”是不可接受的。
“我不知道如何在不删除其他部分的情况下重新绘制这些部分。” 我认为这就是你的问题所在。如果你声明并调用
redrawBoard(),它应该重画所有的棋子(!),而不仅仅是移动的棋子。同意?即您必须迭代所有 board[][] 并在每块上调用 drawPiece() 。但你的代码似乎已经做到了这一点?
让我建议您如何清理现有的绘图代码,在这个过程中您几乎肯定会发现错误。显然,每次有移动(或升级)时,您都需要清除并重绘屏幕,您真的这样做了吗?redrawBoard()为此声明一个 fn 。如果不进行清除,则移动后该棋子将显示在其旧位置和新位置,这显然是错误的?(关于帧速率的评论是画布每秒更新的频率。让我想知道当您重绘时,您不需要每秒重绘 10 次,除非您还有时钟或其他变化的数据。但是,嘿,那个也有效。)
首先,强烈建议您使用枚举来自行记录board[][] 中使用的值
class Checkers():
    EMPTY=0
    RED_PIECE=1
    RED_KING=2
    BLACK_PIECE=3
    BLACK_KING=4
接下来,您可以极大地清理画板代码。由于所有 4 个绘图用例都调用一个公共用例,因此将其设为 fn,并使该 fn 整洁:
def drawPiece(i,j,fillColor,outlineColor):
    """Draw single piece on screen."""
    x = (i+1)*width + width/2
    y = (j+1)*height + height/2
    lst2.append(canvas.create_oval(x+15,y+15,x-15,y-15,fill=fillColor,outline=outlineColor))
现在,严格调用这些的板绘图代码实际上只有两种情况:(2,4) 或 (1,3) 假设您获得了正确的枚举:
顺便说一下,永远不要使用 while 循环,而更清晰的 for 循环可以做到这一点:
for i in range(len(board)):
    for j in range(len(board[i])):
        if board[i][j] in (RED_PIECE,RED_KING):
            drawPiece(i,j,'Red','Black')
        elif board[i][j] in (BLACK_PIECE,BLACK_KING):
            drawPiece(i,j,'Black','Black')
这种分解不是更容易阅读和调试吗?它是自我记录的。现在你的 bug 应该会突然出现在你面前了。
(顺便说一句,您目前绘制的国王与棋子完全相同,但我想您稍后会解决这个问题。)
第四次编辑:你让我们看到了错误的 fns,grr...你说你的错误实际上是在板绘图代码中。请您更正标题,仍然写着“实现移动功能”吗?
原始回复:机器向往所说的,这不是一个问题 - 还不是:告诉我们您目前正在尝试什么,以及为什么它不起作用。另外,删除所有不相关的代码。
看起来您在功能上遇到了困难moveTo(i,j)- 但到底是什么?(全局变量 SecondPass、SecondPosition 表明你可能遇到了麻烦......你知道递归吗?如果不知道,不用担心。)
另外,作为一种风格,为了让你的生活变得轻松,这个实现不是面向对象的,全局变量尖叫着糟糕的分解。尝试重写为类Checkers,使董事会等成为成员,编写init()方法。我会将函数重命名grid(x,y)为initialize(nrows,ncols).
(咳咳!有迹象表明你是从别人那里改编的……)
#Frame rate is how often canvas will be updated
# each second. For Tic Tac Toe, 10 should be plenty.
FRAME_RATE = 10
| 归档时间: | 
 | 
| 查看次数: | 11020 次 | 
| 最近记录: |