在WPF中创建国际象棋GUI

时间:2010-08-24 09:07:48

标签: wpf user-interface chess

首先:如果这是一个重复的帖子,请道歉。当我试图同时发布/注册时,事情变得有点混乱。

我开始研究从一个简单的WPF窗口运行UCI国际象棋引擎,让国际象棋引擎在与该界面不同的线程上运行,并创建了一个合理可维护的基于文本的前端。

我现在变得更加雄心勃勃了,并希望开始构建一个带有国际象棋棋子的GUI,它将播放玩家移动到国际象棋引擎,并代表引擎在棋盘上的移动。我的目标是可拖动的碎片,而不是点击方块。

我目前的尝试涉及在< canvas>上使用可拖动的用户控件。元件。我真的很想知道其他更有经验的WPF / .NET程序员如何处理这个问题,因为我并不完全相信我已走上正轨。

例如:使用统一网格并在子元素之间拖动数据会更好吗?我应该创建一个抽象的“片段”类,如棋子可以衍生出来吗?那种事。

有什么想法?这不是一个家庭作业或任何事情,只是我在业余时间作为一种锻炼而徘徊的东西。

1 个答案:

答案 0 :(得分:3)

我已经为我的Silverlight Online Chess系统实现了棋盘。

我是这样做的。

  1. 我为棋盘制作了一个单独的用户控件
  2. 我在控件
  3. 上添加了一个网格8x8
  4. 然后我添加了64个边框,每个边框用不同的颜色(黑色方块和浅色方块)着色。确保为每个边框命名。使用Grid.Row和Grid.Col属性将每个边框放置在网格上。
  5. 在每个边框内,我添加了一个可以保存国际象棋图像的图像。
  6. 根据您当前的游戏状态,您必须编写一些方法,将图像设置为正确的棋子。
  7. 每个图像都收到相同的事件(这很重要),所有64个调用同一段代码:

    的MouseLeftButtonDown = “Image_MouseLeftButtonDown” 的MouseMove = “Image_MouseMove” 的MouseLeftButtonUp = “Image_MouseLeftButtonUp”

  8. 这三个事件背后的想法是,当我点击图像(MouseLeftButtonDown)时,我会记录下点击的原点,然后我在鼠标移动时调用事件,这样我就可以将屏幕更新为这件作品正在移动,当我放开鼠标按钮(MouseLeftButtonUp)时,我记录的最后一个事件,这允许我获取目的地并将移动发送到我的国际象棋引擎。一旦国际象棋引擎记录了这一动作,我就会重新绘制国际象棋棋盘。

    private void Image_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        Image image = (Image)sender;
        Border border = (Border)image.Parent;
    
        image.CaptureMouse();
        isMouseCapture = true;
        mouseXOffset = e.GetPosition(border).X;
        mouseYOffset = e.GetPosition(border).Y;
    
        var chessPiece = (Image) sender;
        var chessSquare = (Border) chessPiece.Parent;
    
        var row = (byte) (Grid.GetRow(chessSquare));
        var column = (byte) (Grid.GetColumn(chessSquare) - 1);
    
        if (engine.HumanPlayer == ChessPieceColor.White)
        {
            SelectionChanged(row, column, false);
        }
        else
        {
            SelectionChanged((byte)(7 - row), (byte)(7 - column), false);
        }
    }
    

    SelectionChanged是我自己的方法,用于记录用户选择的源方块。 isMouseCapture也是我自己的变量,用于在用户开始绘制文章时进行录制。

    private void Image_MouseMove(object sender, MouseEventArgs e)
    {
    
        Image image = (Image)sender;
        Border border = (Border)image.Parent;
    
    
        if (!currentSource.Selected)
        {
            image.ReleaseMouseCapture();
            isMouseCapture = false;
    
            translateTransform = new TranslateTransform();
    
            translateTransform.X = 0;
            translateTransform.Y = 0;
    
            mouseXOffset = 0;
            mouseYOffset = 0;
        }
    
    
    
        if (isMouseCapture)
        {
            translateTransform = new TranslateTransform();
    
            translateTransform.X = e.GetPosition(border).X - mouseXOffset;
            translateTransform.Y = e.GetPosition(border).Y - mouseYOffset;
    
            image.RenderTransform = translateTransform;
    
            CalculateSquareSelected((int)translateTransform.X, (int)translateTransform.Y, false);
    
    
        }
    }
    

    在上面的CalculareSquareSelected中,将移动的像素转换为我认为该棋子在8x8棋盘中移动的位置。例如,我说我移动了100个像素,棋盘方块只有50个像素,而不是我移动了2个棋盘方块。

    private void Image_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
    {
        if (translateTransform == null)
        {
            return;
        }
    
        Image image = (Image)sender;
    
        image.ReleaseMouseCapture();
        isMouseCapture = false;
    
        if (translateTransform.X > 10 || translateTransform.Y > 10 || translateTransform.X < -10 || translateTransform.Y < -10)
        {
            CalculateSquareSelected((int)translateTransform.X, (int)translateTransform.Y, true);
        }
        translateTransform = new TranslateTransform();
    
        translateTransform.X = 0;
        translateTransform.Y = 0;
    
        mouseXOffset = 0;
        mouseYOffset = 0;
    
        image.RenderTransform = translateTransform;
    
    }
    

    如果您有任何问题,请随时与我联系。