如何在as3中实现撤消和重做功能

时间:2011-11-16 05:17:07

标签: flash actionscript-3 flex

  

可能重复:
  How to implement Undo and Redo feature in as3

我将创建一个应用程序,因为我必须实现撤消和重做功能。 在应用程序中,将有多个对象位于舞台上,用户可以自定义 物体的位置。但是,当用户点击“撤消”时,对象将恢复为默认值 位置和点击重做对象后将移动到新位置。

所以我的问题是如何在我的应用程序中应用这些功能? 有没有图书馆或任何第三方课程?

有人可以帮助我吗?

提前致谢。

3 个答案:

答案 0 :(得分:6)

Memento pattern用于此类情况。 Google快速搜索产生an article,解释了如何实施。

答案 1 :(得分:0)

这看起来很有趣。以下轨迹显示对象的开始和结束坐标,支持撤消/重做并在进行新移动时销毁重做操作。它可能对您的需求有点简单和限制,但可以通过添加到VO轻松扩展。

HistoryVO:

package  {

    import flash.display.DisplayObject;

    public class HistoryVO {

        public var mc:DisplayObject;
        public var oldX:Number;
        public var oldY:Number;
        public var newX:Number;
        public var newY:Number;

        public function HistoryVO($mc:DisplayObject,$oldX:Number,$oldY:Number)
        {
            mc = $mc;
            oldX = $oldX;
            oldY = $oldY;
        }
    }
}

HistoryManager注册:

package  {

    import flash.display.DisplayObject;

    public class HistoryManager {

        private var historyList:Vector.<HistoryVO>;

        private var tempVO:HistoryVO;

        private var index:int;

        public function HistoryManager() 
        {
            //initialize the list
            historyList = new Vector.<HistoryVO>();
            index = -1;
        }

        public function createEntry($mc:DisplayObject,$oldX:Number,$oldY:Number):void
        {
            //create a tempory VO to store the old position and the object
            tempVO = new HistoryVO($mc,$oldX,$oldY);
        }

        public function finishEntry($mc:DisplayObject,$newX:Number,$newY:Number):void
        {
            //make sure this is the same object
            if($mc == tempVO.mc) {
                tempVO.newX = $newX;
                tempVO.newY = $newY;
                if(historyList.length > index+1) {
                    //delete any future history
                    historyList = historyList.splice(0,index+1);
                }
                historyList.push(tempVO);
                index++;
            } else {
                throw new Error("Target DisplayObject does not match the stored value");
            }
        }

        //redo
        public function nextStep():void
        {
            if(historyList.length > index+1) {
                var step:HistoryVO = historyList[++index];
                step.mc.x = step.newX;
                step.mc.y = step.newY;
            }
        }

        //undo
        public function previousStep():void
        {
            if(index > -1) {
                var step:HistoryVO = historyList[index--];
                step.mc.x = step.oldX;
                step.mc.y = step.oldY;
            }
        }
    }
}

示例文档类:

package  {

    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.display.Sprite;
    import flash.display.MovieClip;

    public class Main extends MovieClip {

        private var history:HistoryManager;

        private var movies:Vector.<Sprite>;

        private var backBut:Sprite;
        private var nextBut:Sprite;

        public function Main() 
        {
            history = new HistoryManager();
            movies = new Vector.<Sprite>();
            (stage) ? init() : addEventListener(Event.ADDED_TO_STAGE,init);
        }

        private function init(evt:Event = null):void
        {
            //create some sprites to play with
            for(var i:int = 0; i < 5; i++) {
                movies[i] = addChild(new Sprite()) as Sprite;
                movies[i].x = Math.round(Math.random() * 500);
                movies[i].y = Math.round(Math.random() * 350);
                movies[i].graphics.beginFill(Math.round(Math.random()*0xFFFFFF));
                movies[i].graphics.drawRect(0,0,50,50);
                movies[i].graphics.endFill();
                movies[i].addEventListener(MouseEvent.MOUSE_DOWN,onDown);
                movies[i].addEventListener(MouseEvent.MOUSE_UP,onUp);
            }
            //create the buttons
            backBut = addChild(new Sprite()) as Sprite;
            backBut.graphics.beginFill(0x000000);
            backBut.graphics.drawRect(0,0,100,30);
            backBut.addEventListener(MouseEvent.CLICK,previousStep);
            nextBut = addChild(new Sprite()) as Sprite;
            nextBut.x = 110;
            nextBut.graphics.beginFill(0x000000);
            nextBut.graphics.drawRect(0,0,100,30);
            nextBut.addEventListener(MouseEvent.CLICK,nextStep);
        }

        private function onDown(evt:MouseEvent):void
        {
            history.createEntry(Sprite(evt.target),evt.target.x,evt.target.y);
            evt.target.startDrag();
        }

        private function onUp(evt:MouseEvent):void
        {
            evt.target.stopDrag();
            history.finishEntry(Sprite(evt.target),evt.target.x,evt.target.y);
        }

        private function previousStep(evt:MouseEvent):void
        {
            history.previousStep();
        }

        private function nextStep(evt:MouseEvent):void
        {
            history.nextStep();
        }
    }
}

答案 2 :(得分:0)

不幸的是你没有提到你是否使用了flex框架。如果是这样,这个 flex库可能会有所帮助:

http://code.google.com/p/flexundoredo/

如果库不合适,您可以使用命令模式提供自己的实现:

http://en.wikipedia.org/wiki/Command_pattern