Создание шахматного интерфейса в WPF - PullRequest
7 голосов
/ 24 августа 2010

Во-первых: извинения, если это повторяющийся пост.Вещи стали немного запутанными, так как я пытаюсь одновременно публиковать / регистрировать.

Я начал исследовать работу шахматных движков UCI из простого окна WPF, понял, что шахматный движок работает в другом потокек интерфейсу, и создали разумно работоспособный текстовый интерфейс.

Сейчас я становлюсь немного более амбициозным и хотел бы начать создавать графический интерфейс с шахматными фигурами на нем, который будет кормить игрока.ходы к шахматному движку, и также отображают ходы двигателя на доске.Я стремлюсь к перетаскиваемым фигурам, а не щелкаю квадратами.

В настоящее время мои попытки включают использование перетаскиваемых пользовательских элементов управления для фигур на элементе .Мне было бы действительно интересно услышать, как другие, более опытные программисты WPF / .NET подошли бы к этому, поскольку я не совсем уверен, что я на правильном пути.

Например: было бы лучшеиспользовать равномерную сетку и перетаскивать данные между дочерними элементами?Должен ли я создать абстрактный класс «фигуры», из которого могут происходить фигуры, такие как пешки?Такого рода вещи.

Есть мысли?Это не домашнее задание или что-то в этом роде, просто то, чем я занимаюсь в свободное время в качестве упражнения.

1 Ответ

3 голосов
/ 03 сентября 2010

Я реализовал шахматную доску для своей системы Silverlight Online Chess .

Вот как я это сделал.

  1. Я создал отдельный пользовательский элемент управлениядля шахматной доски
  2. Я добавил сетку 8x8 на элемент управления
  3. Затем я добавил 64 границы, заштриховывая каждую из них разным цветом (темные квадраты и светлые квадраты). Обязательно назовите каждую из них.Каждая из границ была размещена на сетке с использованием свойств Grid.Row и Grid.Col.
  4. В каждой границе я добавил изображение, которое будет содержать изображение шахматной фигуры.
  5. У вас будетзакодировать некоторые методы установки изображения на правильную шахматную фигуру в зависимости от вашего текущего игрового состояния.
  6. Каждое из изображений получило одно и то же событие (это важно), все 64 вызывают один и тот же кусокcode:

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

Идея этих 3 событий заключается в том, что мы записываем, когда мы записываем, когда мы записываем, когда мы записываем, когда мы записываем эти 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 пикселей, а квадрат шахматной доски составляет всего 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;

}

Если у вас есть какие-либо вопросы, не стесняйтесь обращаться ко мне.

...