我正在为大学做一个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
答案 0 :(得分:26)
您可以使用coords和/或move方法在画布上移动项目,以将坐标从它们更改为您想要的坐标。
这是一个简单的示例,展示如何在画布上创建和移动项目:
import Tkinter as tk
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()
答案 1 :(得分:2)
第5编辑:好的,谢谢你删除了代码。
解释完全您的电路板绘图代码有什么问题? '已移动的部分未从旧位置删除'? '所有棋子都是用错误的坐标或颜色绘制的'? ...?的 仅保留转储代码并说“此代码不起作用”是不可接受的。
“我不知道如何重新绘制碎片,而不删除其他碎片。” 我认为这就是你的问题。如果您声明并调用
redrawBoard()
,它应该重绘所有部分(!),而不仅仅是移动的部分。同意?即你必须遍历所有的board [] []并在每一块上调用drawPiece()。但是你的代码似乎已经这样做了吗?
让我建议您如何清理现有的电路板绘图代码,在这个过程中,您几乎肯定会发现您的错误。
显然,每当有移动(或促销)时你需要清除并重绘屏幕,你真的这样做了吗?为此声明fn redrawBoard()
。如果你不清楚,那么在移动后,这件作品将显示在旧的和新的位置,这显然是错的?
(关于帧率的评论是每秒更新画布的频率。让我想知道你什么时候重绘,你不需要每秒重绘10次,除非你还有一个时钟或其他改变但是,嘿,这也有效。)
首先,强烈建议你在[] []
中使用use an enum to self-document the valuesclass Checkers():
EMPTY=0
RED_PIECE=1
RED_KING=2
BLACK_PIECE=3
BLACK_KING=4
接下来,您可以大大清理电路板绘图代码。 由于所有4个绘图案例都称为常见案例,因此请将其设为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)假设你得到了枚举权:
顺便说一句,永远不要使用一个更易读的for-loop可以做的while循环:
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几乎应该向你跳出来。
(顺便说一句,你现在正在绘制与棋子完全相同的国王,但我想你以后会解决这个问题。)
原始回复: 什么机器向往说,这不是一个问题 - 还没有:告诉我们你目前正在尝试什么,以及为什么它不起作用。另外,删除所有不相关的代码。
看起来你在功能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