7

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

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

我现在变得更加雄心勃勃,并想开始构建一个带有棋子的 GUI,它将玩家的动作提供给国际象棋引擎,并在棋盘上代表引擎的动作。我的目标是可拖动的部分,而不是点击方块。

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

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

有什么想法吗?这不是家庭作业或任何东西,只是我在业余时间闲逛的东西作为练习。

4

1 回答 1

3

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

这是我的做法。

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

    MouseLeftButtonDown="Image_MouseLeftButtonDown" MouseMove="Image_MouseMove" MouseLeftButtonUp="Image_MouseLeftButtonUp"

这 3 个事件背后的想法是,当我单击图像 (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 个像素,而棋盘方格仅比我移动 2 个棋盘方格的 50 像素。

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;

}

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

于 2010-09-02T20:55:33.723 回答