绘制棋盘代码来移动椭圆

2025-03-12 08:50:00
admin
原创
56
摘要:问题描述:我正在为大学开发一款 Python 跳棋游戏。我已经使用 tk 绘制了棋盘,但似乎无法实现棋子的移动功能。如果有人发现我的代码中存在任何错误,或者可以提供帮助,我将不胜感激。这是完整的源代码。提前致谢。我知道这会绘制棋子。我不知道如何在不删除其他棋子的情况下重新绘制棋子。我在网上查看了移动函数,并尝...

问题描述:

我正在为大学开发一款 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

解决方案 1:

您可以使用坐标和/或移动方法移动画布上的项目,以将坐标从原来的坐标更改为您想要的坐标。

这是一个简单的例子,展示如何在画布上创建和移动一个项目:

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, background="bisque")
        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.drag_start)
        self.canvas.tag_bind("token", "<ButtonRelease-1>", self.drag_stop)
        self.canvas.tag_bind("token", "<B1-Motion>", self.drag)

    def create_token(self, x, y, color):
        """Create a token at the given coordinate in the given color"""
        self.canvas.create_oval(
            x - 25,
            y - 25,
            x + 25,
            y + 25,
            outline=color,
            fill=color,
            tags=("token",),
        )

    def drag_start(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 drag_stop(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 drag(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()

解决方案 2:

第六次编辑:这里有两个解决方案供您使用:

  1. (正如 Bryan 建议的那样)要么记住移动棋子的旧位置,在那里取消绘制(=> 用背景颜色绘制),要么在新位置重新绘制它

  2. 更简单:清除并重新绘制整个棋盘

第五次编辑:好的,谢谢您删去代码。

请准确解释一下您的棋盘绘制代码存在什么问题?“移动的棋子未从原位置删除”?“所有棋子都绘制在错误的坐标或颜色上”?……?
只是不断地转储代码并说“此代码不起作用”是不可接受的。

“我不知道如何在不删除其他棋子的情况下重新绘制棋子。”
我认为这就是你的问题所在。如果你声明并调用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')

这种分解不是更容易阅读和调试吗?它是自文档化的。现在你的错误应该会立即显现出来。

(顺便说一句,你现在画的王和棋子一模一样,但我想你稍后会解决这个问题。)


第四次编辑:你让我们看错了 fns,哎呀……你说你的错误实际上是在画板代码中。你能更正一下标题吗?标题仍然是“实现移动功能”


原始回复:machine yearning 说过,这不是一个问题 - 还不是:告诉我们您目前尝试了什么,以及为什么它不起作用。另外,删除所有不相关的代码。

看起来您在功能上遇到了困难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
相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   2500  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1541  
  PLM(产品生命周期管理)项目对于企业优化产品研发流程、提升产品质量以及增强市场竞争力具有至关重要的意义。然而,在项目推进过程中,范围蔓延是一个常见且棘手的问题,它可能导致项目进度延迟、成本超支以及质量下降等一系列不良后果。因此,有效避免PLM项目范围蔓延成为项目成功的关键因素之一。以下将详细阐述三大管控策略,助力企业...
plm系统   16  
  PLM(产品生命周期管理)项目管理在企业产品研发与管理过程中扮演着至关重要的角色。随着市场竞争的加剧和产品复杂度的提升,PLM项目面临着诸多风险。准确量化风险优先级并采取有效措施应对,是确保项目成功的关键。五维评估矩阵作为一种有效的风险评估工具,能帮助项目管理者全面、系统地评估风险,为决策提供有力支持。五维评估矩阵概述...
免费plm软件   23  
  引言PLM(产品生命周期管理)开发流程对于企业产品的全生命周期管控至关重要。它涵盖了从产品概念设计到退役的各个阶段,直接影响着产品质量、开发周期以及企业的市场竞争力。在当今快速发展的科技环境下,客户对产品质量的要求日益提高,市场竞争也愈发激烈,这就使得优化PLM开发流程成为企业的必然选择。缺陷管理工具和六西格玛方法作为...
plm产品全生命周期管理   26  
热门文章
项目管理软件有哪些?
曾咪二维码

扫码咨询,免费领取项目管理大礼包!

云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用