dog*_*_uk 7 wpf user-interface chess
首先:如果这是重复的帖子,请道歉.当我试图同时发布/注册时,事情变得有点混乱.
我开始研究从一个简单的WPF窗口运行UCI国际象棋引擎,让国际象棋引擎在与该界面不同的线程上运行,并创建了一个合理可维护的基于文本的前端.
我现在变得更加雄心勃勃了,并希望开始构建一个带有国际象棋棋子的GUI,它将为玩家提供棋子引擎的动作,并代表引擎在棋盘上的动作.我的目标是可拖动的碎片,而不是点击方块.
我目前的尝试涉及在<canvas>元素上使用可拖动的用户控件.我真的很想知道其他更有经验的WPF/.NET程序员会如何处理这个问题,因为我并不完全相信我是在正确的轨道上.
例如:使用统一网格并在子元素之间拖动数据会更好吗?我应该创建一个抽象的"片段"类,如棋子可以衍生出来吗?那种事.
有什么想法吗?这不是一个家庭作业或任何事情,只是我在业余时间作为练习在我身边徘徊.
我已经为我的 Silverlight Online Chess系统实现了一个棋盘。
我是这样做的。
每个图像都收到相同的事件(这很重要),所有 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);
}
}
Run Code Online (Sandbox Code Playgroud)
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);
}
}
Run Code Online (Sandbox Code Playgroud)
在上面的 CalulareSquareSelected 中,将移动到我认为棋子在 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;
}
Run Code Online (Sandbox Code Playgroud)
如果您有任何疑问,请随时与我联系。