热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

如何在as3中实现撤消和重做功能[重复]-HowtoimplementUndoandRedofeatureinas3[duplicate]

PossibleDuplicate:HowtoimplementUndoandRedofeatureinas3可能重复:如何在as3中实现撤消和重做功能Iam

Possible Duplicate:
How to implement Undo and Redo feature in as3

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

I am going to create an application in that i have to implement an Undo and Redo feature. In the application there will be multiple objects located on stage and user can customize the position of the objects. But when user clicks on Undo the object go back to their default position and after clicking on redo object will move on the new position.

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

So my question is how can i apply these feature in my application? Is there any library or any third party classes?

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

Can some one help me?

有人能帮我吗?

Thanks in advance.

提前致谢。

3 个解决方案

#1


0  

This seemed like a fun exercise. The following tracks start and end coordinates of display objects, supports undo/redo and destroys redo actions when a new movement is made. It's probably a bit simple and restrictive for your needs, but could be easily extended by adding to the VO.

这似乎是一个有趣的练习。以下轨道显示对象的开始和结束坐标,支持撤消/重做并在进行新移动时销毁重做操作。它可能对您的需求有点简单和限制,但可以通过添加到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.;

        private var tempVO:HistoryVO;

        private var index:int;

        public function HistoryManager() 
        {
            //initialize the list
            historyList = new Vector.();
            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;
            }
        }
    }
}

Example document class:

示例文档类:

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.;

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

        public function Main() 
        {
            history = new HistoryManager();
            movies = new Vector.();
            (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


6  

Memento pattern is used for situations like this. A quick Google search yielded an article which explains how it is implemented.

Memento模式用于这种情况。谷歌的快速搜索产生了一篇文章,解释了它是如何实现的。

#3


0  

Unfortunately you didn't mention whether you use the flex framework. If it is so, this flex library may be helpful:

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

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

If the library is not suitable, you can provide your own implementation using the command pattern:

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

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


推荐阅读
  • Go Cobra命令行工具入门教程
    本文介绍了Go语言实现的命令行工具Cobra的基本概念、安装方法和入门实践。Cobra被广泛应用于各种项目中,如Kubernetes、Hugo和Github CLI等。通过使用Cobra,我们可以快速创建命令行工具,适用于写测试脚本和各种服务的Admin CLI。文章还通过一个简单的demo演示了Cobra的使用方法。 ... [详细]
  • Spring源码解密之默认标签的解析方式分析
    本文分析了Spring源码解密中默认标签的解析方式。通过对命名空间的判断,区分默认命名空间和自定义命名空间,并采用不同的解析方式。其中,bean标签的解析最为复杂和重要。 ... [详细]
  • 本文介绍了设计师伊振华受邀参与沈阳市智慧城市运行管理中心项目的整体设计,并以数字赋能和创新驱动高质量发展的理念,建设了集成、智慧、高效的一体化城市综合管理平台,促进了城市的数字化转型。该中心被称为当代城市的智能心脏,为沈阳市的智慧城市建设做出了重要贡献。 ... [详细]
  • 如何使用Java获取服务器硬件信息和磁盘负载率
    本文介绍了使用Java编程语言获取服务器硬件信息和磁盘负载率的方法。首先在远程服务器上搭建一个支持服务端语言的HTTP服务,并获取服务器的磁盘信息,并将结果输出。然后在本地使用JS编写一个AJAX脚本,远程请求服务端的程序,得到结果并展示给用户。其中还介绍了如何提取硬盘序列号的方法。 ... [详细]
  • 展开全部下面的代码是创建一个立方体Thisexamplescreatesanddisplaysasimplebox.#Thefirstlineloadstheinit_disp ... [详细]
  • 本文介绍了作者在开发过程中遇到的问题,即播放框架内容安全策略设置不起作用的错误。作者通过使用编译时依赖注入的方式解决了这个问题,并分享了解决方案。文章详细描述了问题的出现情况、错误输出内容以及解决方案的具体步骤。如果你也遇到了类似的问题,本文可能对你有一定的参考价值。 ... [详细]
  • 本文介绍了一个在线急等问题解决方法,即如何统计数据库中某个字段下的所有数据,并将结果显示在文本框里。作者提到了自己是一个菜鸟,希望能够得到帮助。作者使用的是ACCESS数据库,并且给出了一个例子,希望得到的结果是560。作者还提到自己已经尝试了使用"select sum(字段2) from 表名"的语句,得到的结果是650,但不知道如何得到560。希望能够得到解决方案。 ... [详细]
  • ALTERTABLE通过更改、添加、除去列和约束,或者通过启用或禁用约束和触发器来更改表的定义。语法ALTERTABLEtable{[ALTERCOLUMNcolu ... [详细]
  • Android开发实现的计时器功能示例
    本文分享了Android开发实现的计时器功能示例,包括效果图、布局和按钮的使用。通过使用Chronometer控件,可以实现计时器功能。该示例适用于Android平台,供开发者参考。 ... [详细]
  • 在Xamarin XAML语言中如何在页面级别构建ControlTemplate控件模板
    本文介绍了在Xamarin XAML语言中如何在页面级别构建ControlTemplate控件模板的方法和步骤,包括将ResourceDictionary添加到页面中以及在ResourceDictionary中实现模板的构建。通过本文的阅读,读者可以了解到在Xamarin XAML语言中构建控件模板的具体操作步骤和语法形式。 ... [详细]
  • 本文讨论了在openwrt-17.01版本中,mt7628设备上初始化启动时eth0的mac地址总是随机生成的问题。每次随机生成的eth0的mac地址都会写到/sys/class/net/eth0/address目录下,而openwrt-17.01原版的SDK会根据随机生成的eth0的mac地址再生成eth0.1、eth0.2等,生成后的mac地址会保存在/etc/config/network下。 ... [详细]
  • CEPH LIO iSCSI Gateway及其使用参考文档
    本文介绍了CEPH LIO iSCSI Gateway以及使用该网关的参考文档,包括Ceph Block Device、CEPH ISCSI GATEWAY、USING AN ISCSI GATEWAY等。同时提供了多个参考链接,详细介绍了CEPH LIO iSCSI Gateway的配置和使用方法。 ... [详细]
  • 本文介绍了在CentOS 6.4系统中更新源地址的方法,包括备份现有源文件、下载163源、修改文件名、更新列表和系统,并提供了相应的命令。 ... [详细]
  • Gitlab接入公司内部单点登录的安装和配置教程
    本文介绍了如何将公司内部的Gitlab系统接入单点登录服务,并提供了安装和配置的详细教程。通过使用oauth2协议,将原有的各子系统的独立登录统一迁移至单点登录。文章包括Gitlab的安装环境、版本号、编辑配置文件的步骤,并解决了在迁移过程中可能遇到的问题。 ... [详细]
  • Android系统移植与调试之如何修改Android设备状态条上音量加减键在横竖屏切换的时候的显示于隐藏
    本文介绍了如何修改Android设备状态条上音量加减键在横竖屏切换时的显示与隐藏。通过修改系统文件system_bar.xml实现了该功能,并分享了解决思路和经验。 ... [详细]
author-avatar
手机用户2502860335
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有