Как реализовать функцию отмены и возврата в as3 - PullRequest
0 голосов
/ 06 октября 2011

Я собираюсь создать приложение, в котором мне нужно реализовать функцию Отменить и повторить .В приложении будет несколько объектов, расположенных на сцене, и пользователь может настроить положение объектов.Но когда пользователь нажимает кнопку «Отменить», объект возвращается в положение по умолчанию, а после нажатия на кнопку «Повторить» объект перемещается в новую позицию.

Итак, мой вопрос: как я могу применить эту функцию в своем приложении?Есть ли какая-нибудь библиотека или какие-либо сторонние классы?

Может ли кто-нибудь мне помочь?

Заранее спасибо.

Ответы [ 4 ]

5 голосов
/ 06 октября 2011

Посмотрите на шаблон команды . Он хорошо подходит для устранения ошибок типа

0 голосов
/ 16 ноября 2011
 package com
 {
    import flashx.undo.IOperation;

    public class UndoOperation implements IOperation
    {

    private var _previousX:Number = 0;
    private var _previousY:Number = 0;
    private var _previousObj:Object = new Object();
    private var _currentX:Number = 0;
    private var _currentY:Number = 0;
    private var _currentObj:Object = new Object();
    private var _shape:Object = new Object();


    public function TransformOperation(currentObj:Object,previousObj:Object,previousX:Number, previousY:Number, currentX:Number, currentY:Number)
    {
        _previousX = previousX;
        _previousY = previousY;
        _previousObj = previousObj;

        _currentX = currentX;
        _currentY = currentY;
        _currentObj = currentObj;
        _shape = _currentObj;

        trace('Transform _previousX:  '+  _previousX  +' _previousY:  ' +_previousY+' _currentObj '+_currentObj+' _shape '+_shape);
        trace( 'trans _currentX    '+ _currentX +'  '+'_currentY     '+ _currentY );

    }

    public function performUndo():void
    {
        _shape = _currentObj;
        //trace('_shape.x '+_shape.x+" _shape.y "+_shape.y);
        _shape.x = _previousX;
        _shape.y = _previousY;
        //trace(_previousX +'  '+ _previousY +'  '+ _previousWidth +'  '+ _previousHeight +'  '+  _previousScaleX +'  '+  _previousScaleY +'  '+ _previousRotation);
        //trace('_shape.x '+_shape.x+" _shape.y "+_shape.y);
        //trace('_currentX    '+ _currentX +'  '+'_currentY     '+ _currentY);
    }

    public function performRedo():void
    {
        _shape.x = _currentX;
        _shape.y = _currentY;
        trace(_currentX+'  '+ _currentY);
    }
  }
}

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

Для использования этого класса импортируйте только класс

                 import flashx.undo.UndoManager;

и после этого

            public static var _undo:UndoManager=new UndoManager();
            public static var _redo:UndoManager=new UndoManager();     
            public static var PrevX:Number=0;
            public static var PrevY:Number=0;
            var operation:TransformOperation = new TransformOperation(this,this,PrevX,PrevY,this.x,this.y);
           _undo.pushUndo(operation);

После этого создать событие клика для отмены и повтора:

    public static function Undo(e:MouseEvent):void
    {
        _redo.pushRedo(_undo.peekUndo());
        _undo.undo();
        if(_undo.peekUndo()==null)
        {
            PlayerPosition.getClass.getChildByName("toolbar_mc").getChildByName("undo_mc").removeEventListener(MouseEvent.CLICK,Undo);
        }
        PlayerPosition.getClass.getChildByName("toolbar_mc").getChildByName("redo_mc").addEventListener(MouseEvent.CLICK,Redo);
    }

    public static function Redo(e:MouseEvent):void
    {
        _undo.pushUndo(_redo.peekRedo());
        _redo.redo();
        if(_redo.peekRedo()==null)
        {                          PlayerPosition.getClass.getChildByName("toolbar_mc").getChildByName("redo_mc").removeEventListener(MouseEvent.CLICK,Redo);
        }
        PlayerPosition.getClass.getChildByName("toolbar_mc").getChildByName("undo_mc").addEventListener(MouseEvent.CLICK,Undo);
    }

Для меня это работает нормально ... Надеюсь, это поможет и другим ...:)

0 голосов
/ 06 октября 2011

Самый простой способ, который я могу придумать, - это создание объекта действия, в котором у вас есть старое состояние, новое состояние и объект, который изменился.

каждый раз, когда запускается действие, которое получило бы функцию отмены, заполните эти данные в объекте действия

когда вы нажмете «Отменить», вернитесь в предыдущее состояние объекта и поместите действие в стек повторного выполнения.

Это должно быть в состоянии обрабатывать наиболее распространенные изменения. Такие вещи, как удаление / восстановление, требуют небольшой дополнительной настройки. Я просто вставил бы все свойства во время удаления и использовал бы функцию create при обработке отмены.

Я бы предложил использовать строку для комбинаций параметров и значений для состояний «до» и «после», чтобы вы могли обрабатывать дополнительные функции без изменения функций отмены / возврата.

Это более быстрый и грязный способ, вы также можете сделать это, используя шаблоны проектирования и надлежащие ООП-способы решения этой проблемы, как уже упоминали другие.

0 голосов
/ 06 октября 2011

Если вам нужны только два разных состояния (по умолчанию и «изменено»), это должно быть довольно просто реализовать. Сохраните новые значения и обновленные значения для каждого объекта в массивах и установите позиции из соответствующего массива при нажатии «отменить» или «повторить».

Если вам нужно что-то более сложное, вы можете хранить все, что вы делаете, как «действие», которое невозможно отменить. Например, есть класс (например, «Action») с несколькими дочерними классами («Move», «ChangeColor» и т. Д.). Они содержат изменения, которые они выполняют (сколько пикселей мы должны переместить) и методы для выполнения действия (перемещение объекта X пикселей) и отмены действия (перемещение объекта -X пикселей).

...