actionscriptでアンドゥ、リドゥの実装
自分で作っているプログラムにアンドゥ、リドゥ実装したくなったので、
簡単なサンプル作ってみた。
package { import flash.display.Sprite; import flash.events.MouseEvent; import flash.utils.Timer; import flash.events.TimerEvent; public class SandBox extends Sprite{ //描画、マウスハンドラ用 private var child:Sprite; //描画位置の配列 private var PointArray:Array; //タイマー関数 private var timer:Timer; //アンドゥ用データ private var UndoData:Array; public function SandBox() { PointArray = new Array(); UndoData = new Array(); child = new Sprite(); child.focusRect = false; //背景クリア child.graphics.beginFill(0xffffff); child.graphics.drawRect(0,0,1024,768); child.graphics.endFill(); addChild(child); //イベント追加 child.addEventListener(MouseEvent.MOUSE_DOWN,mouseDownHandler); timer=new Timer(40,0); timer.addEventListener(TimerEvent.TIMER,onTick); timer.start(); } //時間毎に行う処理 private function onTick(evt:TimerEvent):void { //背景クリア child.graphics.beginFill(0xffffff); child.graphics.drawRect(0,0,1024,768); child.graphics.endFill(); child.graphics.beginFill(0x000000); child.graphics.drawRect(500,100,100,100); child.graphics.endFill(); child.graphics.beginFill(0x0000ff); child.graphics.drawRect(600,100,100,100); child.graphics.endFill(); var i:int; for(i=0;i<PointArray.length;++i){ child.graphics.beginFill(0xff0000); child.graphics.drawCircle(PointArray[i].Getx(),PointArray[i].Gety(),20); child.graphics.endFill(); } } private function mouseDownHandler(evt:MouseEvent):void { if(500 < mouseX && mouseX < 600){ if(100 < mouseY && mouseY < 200){ Undo(); return; } } if(600 < mouseX && mouseX < 700){ if(100 < mouseY && mouseY < 200){ Redo(); return; } } PointArray.push(new Point(mouseX,mouseY)); } private function Undo():void { if(PointArray.length > 0){ UndoData.push(PointArray.pop()); } } private function Redo():void { if(UndoData.length > 0){ PointArray.push(UndoData.pop()); } } } }
以下がコンパイル結果。
適当な所をクリックすると赤い丸がおけて、黒い四角クリックでアンドゥ、
青い四角でリドゥです。
アンドゥ、リドゥ
現在はデータに対してアンドゥ、リドゥしているけど、
Commandパターンを用いて処理自体をアンドゥ、リドゥをする方法もある。
ペイントソフトのように、様々な描画処理を一般化してアンドゥ、リドゥできますね。
Undo,Redoの実装って何十回もやってる気がする - あしあと日記
http://www.sun-inet.or.jp/~yaneurao/intensive/ggg/