Анимация проблемы Башни Ханоя в C#

Следующий метод AnimateMovement перемещает диск по прямой линии из текущего местоположения в новый.

// Переместите движущийся диск в это место.
private void AnimateMovement(int end_x, int end_y)
{
    int start_x = MovingDiskRect.X;
    int start_y = MovingDiskRect.Y;

    const int pixels_per_second = 400;
    float dx = end_x - MovingDiskRect.X;
    float dy = end_y - MovingDiskRect.Y;
    float dist = (float)Math.Sqrt(dx * dx + dy * dy);

    // Вычисление расстояния в секунду.
    dx = pixels_per_second * dx / dist;
    dy = pixels_per_second * dy / dist;

    // Посмотрим, сколько времени займет общий ход.
    float seconds = dist / pixels_per_second;
    DateTime start_time = DateTime.Now;

    // Начнем движение.
    for (; ; )
    {
        // Перерисовать.
        this.Refresh();

        // Подождите немного.
        System.Threading.Thread.Sleep(10);

        // Посмотрим, сколько времени прошло.
        TimeSpan elapsed = DateTime.Now - start_time;
        if (elapsed.TotalSeconds > seconds) break;

        // Обновляем позицию прямоугольника.
        MovingDiskRect.X =
            (int)(start_x + elapsed.TotalSeconds * dx);
        MovingDiskRect.Y =
            (int)(start_y + elapsed.TotalSeconds * dy);
    }

    MovingDiskRect.X = end_x;
    MovingDiskRect.Y = end_y;
}

Код вычисляет количество пикселей в секунду, которое он должен добавить в координаты X и Y на диске. Затем он входит в цикл, где он добавляет необходимое количество пикселей, в зависимости от того, сколько времени прошло. Он останавливает 10 миллисекунд за каждый проход через цикл.

Следующий метод использует AnimateMovement для перемещения диска с одного привязки и на другой.

// Анимация перемещения диска из привязки from_peg в peg to_peg.
private void AnimateDiskMove(int from_peg, int to_peg)
{
    // Удалите диск, чтобы Paint не рисовала его.
    int disk_width = PegStack[from_peg].Pop();

    // Переместите диск выше from_peg.
    int y = PegLocation[from_peg].Bottom -
        (PegStack[from_peg].Count + 1) * (DiskThickness + 2);
    int x = PegLocation[from_peg].X + DiskThickness / 2 -
        disk_width / 2;
    MovingDiskRect = new Rectangle(
        x, y, disk_width, DiskThickness);

    // Переместите диск выше привязки.
    int to_y = 10;
    AnimateMovement(x, to_y);

    // Переместите диск поверх нового привязки.
    int to_x = PegLocation[to_peg].X + DiskThickness / 2 -
        disk_width / 2;
    AnimateMovement(to_x, to_y);

    // Переместите диск вниз на привязку.
    to_y = PegLocation[to_peg].Bottom -
        (PegStack[to_peg].Count + 1) * (DiskThickness + 2);
    AnimateMovement(to_x, to_y);

    // Перерисовать.
    this.Refresh();

    // Добавить диск в новый привязку.
    MovingDiskRect.X = -1;
    PegStack[to_peg].Push(disk_width);
}

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

Далее код использует AnimateMovement для перемещения диска по привязке адресата. Он заканчивается с помощью AnimateMovement снова, чтобы переместить диск вниз на привязку адресата.

Источник: http://csharphelper.com/blog/2015/08/animate-the-tower-of-hanoi-problem-in-c/

1 Звезда2 Звезды3 Звезды4 Звезды5 Звезд (Пока оценок нет)
Adblock
detector