How to stop the timer and move to next scene when puzzle is solved - actionscript-3

I created a jigsaw in action script and kept it a separate class. In the project i linked the code and i added a timer to the scene so that the player have to solve the puzzle within the time specified. Now what i want is that if the player solved the puzzle correctly the timer will stop and go to next scene.
this is the puzzle.as
var xpos:Array=new Array();
var ypos:Array=new Array();
var numDone,i:int;
var numPieces:int=3;
var dif:int=25; //how close do they have to drag the piece
var sound:Sound=new Sound();
function playSound(file:String): void {
//var sound:Sound=new Sound();
var req:URLRequest=new URLRequest(file);
sound.load(req);
sound.play();
} //playSound
function scramble(): void {
for(i=0;i<numPieces;i++){
this["piece"+i].x=Math.random()*300;
this["piece"+i].y=Math.random()*500;
this["piece"+i].alpha=.8;
} //for each piece
numDone=0;
txtMessage.text="Drag the pieces to solve the puzzle";
sound.close();
} //scramble
function init(): void {
for(i=0;i<numPieces;i++){
xpos[i]=this["piece"+i].x;
ypos[i]=this["piece"+i].y;
this["piece"+i].addEventListener(MouseEvent.MOUSE_DOWN, beginMove);
this["piece"+i].addEventListener(MouseEvent.MOUSE_UP, endMove);
} //for each piece
txtMessage.text="Drag the pieces to solve the puzzle";
} //init
function beginMove(e:MouseEvent): void {
if(e.target.alpha<1)
e.target.startDrag();
} //beginMove
function endMove(e:MouseEvent): void {
if(e.target.alpha<1) {
e.target.stopDrag();
//figure out which piece it is
var piece:int=0;
while(e.target!=this["piece"+piece]){
piece++;
} //
var curX:int=this["piece"+piece].x;
var curY:int=this["piece"+piece].y;
if(curX<=xpos[piece]+dif && curX>=xpos[piece]-dif &&
curY<=ypos[piece]+dif && curY>=ypos[piece]-dif) { //close enough
this["piece"+piece].x=xpos[piece];
this["piece"+piece].y=ypos[piece];
this["piece"+piece].alpha=1;
numDone++;
if(numDone>=numPieces) gameOver();
else playSound("http://www.zebra0.com/langResource/ok.mp3");
} //in position
} //not already done
}//endMove
function gameOver(): void {
txtMessage.text="You did it!";
playSound("http://www.zebra0.com/langResource/win.mp3");
gotoAndStop(1,"Scene 2");
} //gameOver
function scrambleHandler(e:MouseEvent): void {
scramble();
} //clickHandler
btnScramble.addEventListener(MouseEvent.CLICK,scrambleHandler);
function solve(e:MouseEvent): void {
for(i=0;i<numPieces;i++) {
this["piece"+i].x=xpos[i];
this["piece"+i].y=ypos[i];
this["piece"+i].alpha=1;
} //for each piece
} //solve
the code for linking the puzzle.as to the project. i kept in a layer called 'ActionScript'
include "Puzzle.as"
numPieces=20;
init();
scramble();
stop();
timer code i kept in a layer called 'action'
var nCount:Number = 90;
var myTimer:Timer = new Timer(1000, nCount);
timer_txt.text = nCount.toString();
myTimer.start();
myTimer.addEventListener(TimerEvent.TIMER, countdown);
myTimer.addEventListener(TimerEvent.TIMER_COMPLETE, onComplete);
function countdown(e:TimerEvent):void
{
nCount--;
timer_txt.text = nCount.toString();
}
function onComplete(e: TimerEvent):void{
gotoAndStop(35);
}
if any one have an idea of how to achieve this.

Related

ActionScript3 remove child error

I recently have been converting an as2 fla to as3 (new to AS3) and have the entire thing working on export, but I am getting an error when I try to remove previously loaded swf's before a new swf is loaded
ArgumentError: Error #2025: The supplied DisplayObject
must be a child of the caller.
at flash.display::DisplayObjectContainer/removeChild()
at MethodInfo-11()
I know the error relates to my removeChild code here:
`stage.addEventListener(MouseEvent.CLICK, removeSWF);
function removeSWF (e:MouseEvent):void
{
if(vBox.numChildren !=0){
// swfLoader.unloadAndStop();
vBox.removeChild(swfLoader);// empty the movieClip memory
}
}`
However, I cannot seem to find a suitable rewrite for this code that will work and not have an error. This code IS working, so I'm not sure if it would be worth my time to fix this error, or just leave it. I've already messed with it for a couple days, so at this point it's just frustrating me that I cannot fix it.
The stage mouse click listener is useful in this case because I have a back button not shown in this code that clears the loaded swf's before moving to another scene.
Does anyone see a simple solution for this, or do you think it is unnecessary to pursue since the code does what I require?
ENTIRE CODE:
function launchSWF(vBox, vFile):void {
var swfLoader:Loader = new Loader();
var swfURL:URLRequest = new URLRequest(vFile);
swfLoader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, onProgressHandler);
swfLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, loadProdComplete);
swfLoader.load(swfURL);
function loadProdComplete(e:Event):void {
trace("swf file loaded");
vBox.removeChild(preLoader);
vBox.addChild(swfLoader);
currentSWF = MovieClip(swfLoader.content);
currentSWF.gotoAndPlay(1);
currentSWF.addEventListener(Event.ENTER_FRAME , checkLastFrame);
swfLoader.x = 165;
swfLoader.y = 15;
function checkLastFrame(e:Event):void {
if (currentSWF.currentFrame == currentSWF.totalFrames) {
currentSWF.stop();
// trace("DONE");
}
}
}
var preLoader:loader = new loader();
preLoader.x = 450;
preLoader.y = 280;
vBox.addChild(preLoader);
function onProgressHandler(event:ProgressEvent){
var dataAmountLoaded:Number=event.bytesLoaded/event.bytesTotal*100;
//preLoader.bar.scaleX = dataAmountLoaded/100;
preLoader.lpc.text= int(dataAmountLoaded)+"%";
//trace(preLoader.bar.scaleX );
}
//NEW ERRORS BUT WORKING
stage.addEventListener(MouseEvent.CLICK, removeSWF);
function removeSWF (e:MouseEvent):void
{
if(vBox.numChildren !=0){
// swfLoader.unloadAndStop();
vBox.removeChild(swfLoader);// empty the movieClip memory
}
}
}
var container:MovieClip = new MovieClip();
var currentSWF:MovieClip = new MovieClip();
fall_b.addEventListener(MouseEvent.CLICK, fall_bClick);
function fall_bClick(e:MouseEvent):void {
var swfFile:String = 'load/fall.swf';
launchSWF(container, swfFile);
addChild(container);
}
face_b.addEventListener(MouseEvent.CLICK, face_bClick);
function face_bClick(e:MouseEvent):void {
var swfFile:String = 'load/face.swf';
launchSWF(container, swfFile);
addChild(container);
}
rott_b.addEventListener(MouseEvent.CLICK, rott_bClick);
function rott_bClick(e:MouseEvent):void {
var swfFile:String = 'load/rottgut.swf';
launchSWF(container, swfFile);
addChild(container);
}
//MORE SWFS...
Any advice anyone has is appreciated
First of all function launchSWF(vBox, vFile):void { isn't closed. You've also got function inside functions which is easy enough for you to solve if you click the lines the curly brackets start and end on to track them.
I can't see anything wrong with the code you said has an error but I'm guessing this isn't all the code. If you using Flash Professisonal you can use permit debugging to show the line the error is on.
EDIT: Please note this hasn't been tested as I'm on my mobile writing out code. That being said this should now work:
var container:MovieClip;
var currentSWF:MovieClip;
var swfFile:String;
var swfLoader:Loader;
var preLoader:Loader;
var swfURL:URLRequest;
init();
function init():void {
preLoader = new Loader();
preLoader.x = 450;
preLoader.y = 280;
vBox.addChild(preLoader);
container = new MovieClip();
currentSWF = new MovieClip();
fall_b.addEventListener(MouseEvent.CLICK, fall_bClick);
face_b.addEventListener(MouseEvent.CLICK, face_bClick);
rott_b.addEventListener(MouseEvent.CLICK, rott_bClick);
stage.addEventListener(MouseEvent.CLICK, removeSWF);
}
function launchSWF(vBox, vFile):void {
swfLoader = new Loader();
swfURL = new URLRequest(vFile);
swfLoader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, onProgressHandler);
swfLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, loadProdComplete);
swfLoader.load(swfURL);
}
function loadProdComplete(e:Event):void {
trace("swf file loaded");
vBox.removeChild(preLoader);
vBox.addChild(swfLoader);
currentSWF = MovieClip(swfLoader.content);
currentSWF.gotoAndPlay(1);
currentSWF.addEventListener(Event.ENTER_FRAME , checkLastFrame);
swfLoader.x = 165;
swfLoader.y = 15;
}
function checkLastFrame(e:Event):void {
if (currentSWF.currentFrame == currentSWF.totalFrames) {
currentSWF.stop();
// trace("DONE");
}
}
function onProgressHandler(event:ProgressEvent) {
var dataAmountLoaded:Number = (event.bytesLoaded / event.bytesTotal * 100);
//preLoader.bar.scaleX = dataAmountLoaded/100;
preLoader.lpc.text = int(dataAmountLoaded)+"%";
//trace(preLoader.bar.scaleX );
}
function removeSWF (e:MouseEvent):void {
if(vBox.numChildren !=0){
//swfLoader.unloadAndStop();
vBox.removeChild(swfLoader);// empty the movieClip memory
}
}
function fall_bClick(e:MouseEvent):void {
swfFile = 'load/fall.swf';
launchSWF(container, swfFile);
addChild(container);
}
function face_bClick(e:MouseEvent):void {
swfFile = 'load/face.swf';
launchSWF(container, swfFile);
addChild(container);
}
function rott_bClick(e:MouseEvent):void {
swfFile = 'load/rottgut.swf';
launchSWF(container, swfFile);
addChild(container);
}
I have this rewritten. I could not get the vBox errors cleared in the original code, and I was getting many other errors with what was posted. The vBox code was seen on a tutorial. I think it was supposed to reference the loader for the preloader and the swf, and vFile was for the actual .swf. The following code preloads multiple swfs and clears them with no errors. I appreciate your help AntBirch. I'm beginning to understand loaders in as3 a little more now.
//LOAD FIRST PIECE ON OPEN (required to removeChild later)
var swfLoader:Loader = new Loader();
var defaultSWF:URLRequest = new URLRequest("load/fall.swf");
swfLoader.load(defaultSWF);
swfLoader.x = 165;
swfLoader.y = 15;
addChild(swfLoader);
//PRELOADER
var preLoader:loader = new loader();
preLoader.x = 450;
preLoader.y = 280;
function loadProdComplete(e:Event):void {
trace("swf file loaded");
removeChild(preLoader);
addChild(swfLoader);
}
function onProgressHandler(event:ProgressEvent){
var dataAmountLoaded:Number=event.bytesLoaded/event.bytesTotal*100;
preLoader.lpc.text= int(dataAmountLoaded)+"%";
}
//BUTTONS
function btnClick(event:MouseEvent):void {
swfLoader.unloadAndStop();
removeChild(swfLoader);
swfLoader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, onProgressHandler);
swfLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, loadProdComplete);
addChild(preLoader);
var newSWFRequest:URLRequest = new URLRequest("load/" + event.target.name + ".swf");
swfLoader.load(newSWFRequest);
swfLoader.x = 165;
swfLoader.y = 15;;
addChild(swfLoader);
}
// BUTTON LISTENERS
fall.addEventListener(MouseEvent.CLICK, btnClick);
face.addEventListener(MouseEvent.CLICK, btnClick);
rott.addEventListener(MouseEvent.CLICK, btnClick);
angel.addEventListener(MouseEvent.CLICK, btnClick);
ratts.addEventListener(MouseEvent.CLICK, btnClick);
metal.addEventListener(MouseEvent.CLICK, btnClick);
//etc...
//BACK BUTTON
BB3.addEventListener(MouseEvent.CLICK, BB3Click);
function BB3Click(e:MouseEvent):void {
swfLoader.unloadAndStop();
removeChild(swfLoader);
this.gotoAndPlay(1 ,"Scene 2")
}

use of button to increase and decrease the timer in action script3.0

I have written a code to add two buttons. It shows them correctly, but the action is not performed correctly.
public class butt extends Sprite {
public function butt() {
var delayGlobal:Number = 2000;
var min1:Number =1000;
var myTimer:Timer = new Timer(delayGlobal);
myTimer.addEventListener(TimerEvent.TIMER,runMany);
myTimer.start();
// Button Event
myButton1.addEventListener(MouseEvent.CLICK, myButton1Click);
function myButton1Click(ev:MouseEvent):void {
delayGlobal = delayGlobal- 1000;
trace(delayGlobal);
}
myButton2.addEventListener(MouseEvent.CLICK, myButton2Click);
function myButton2Click(ev:MouseEvent):void {
delayGlobal = delayGlobal + 1000;
trace(delayGlobal);
}
function runMany(e:TimerEvent):void {
var loader:Loader=new Loader();
var url:String= "http://google.com.example2";
loader.load(new URLRequest(url));
addChild(loader);
}
}
}
The timer is shown but doesn't work
Your issue is that you are updating a variable, but not actually updating the timer at all.
You need to explicitly tell the timer to change the delay. myTimer.delay = delayGlobal
Here is a re-working of your code:
public class butt extends Sprite {
private var min1:Number =1000; //assuming this is your minimum allowed delay?
private var myTimer:Timer;
public function butt() {
myTimer = new Timer(2000);
myTimer.addEventListener(TimerEvent.TIMER,runMany);
myTimer.start();
// Button Event
myButton1.addEventListener(MouseEvent.CLICK, myButton1Click);
myButton2.addEventListener(MouseEvent.CLICK, myButton2Click);
}
private function myButton1Click(ev:MouseEvent):void {
myTimer.delay = Math.max(min1, myTimer.delay - 1000); //This will assign whatever is bigger, min1 or the timer delay less 1000 - ensuring that the timer doesn't drop below the value of min1
trace(myTimer.delay);
}
private function myButton2Click(ev:MouseEvent):void {
myTimer.delay = myTimer.delay + 1000;
trace(myTimer.delay);
}
private function runMany(e:TimerEvent):void {
var loader:Loader=new Loader();
var url:String= "http://google.com.example2";
loader.load(new URLRequest(url));
addChild(loader);
}
}

How do I display a button at a certain time, then have it disappear again in Actionscript 3?

I am trying to make a game that involves hitting keys/clicking buttons at the right time. I want to have the button/indicator hidden until the right time but am having a bit of trouble getting it to display. This is the code I have for it so far.
var count:Number = 5;
var myTimer:Timer = new Timer(1000, count);
myTimer.addEventListener(TimerEvent.TIMER, countdown);
myTimer.start();
function countdown(event:TimerEvent): void {
timer_txt.text = String((count)-myTimer.currentCount);
}
btnthing.addEventListener(MouseEvent.CLICK, btnclick);
btnthing.visible=false;
while (((count)-myTimer.currentCount)==1) {
btnthing.visible=true;
}
function btnclick(e:MouseEvent): void {
if (((count)-myTimer.currentCount) == 1) {
myTimer.stop();
btnthing.visible=false;
time_txt.text = "Yay!";
} else {
myTimer.stop();
gotoAndStop(3);
}
}
So far my code starts the timer and displays a countdown. If I remove the part that hides/shows the button, everything works fine.
var count:Number = 5;
var myTimer:Timer = new Timer(1000, count);
myTimer.addEventListener(TimerEvent.TIMER, countdown);
myTimer.start();
function countdown(event:TimerEvent): void {
timer_txt.text = String((count)-myTimer.currentCount);
}
btnthing.addEventListener(MouseEvent.CLICK, btnclick);
function btnclick(e:MouseEvent): void {
if (((count)-myTimer.currentCount) == 1) {
myTimer.stop();
btnthing.visible=false;
timer_txt.text = "Yay!";
} else {
myTimer.stop();
gotoAndStop(3);
}
}
If anyone could help me get this right that would be awesome. Thanks!
You're not using the 'while' loop correctly. Change it to a 'if' statement and put it inside the countdown function like this:
function countdown(event:TimerEvent): void
{
timer_txt.text = String((count)-myTimer.currentCount);
if (((count)-myTimer.currentCount)==1) {
btnthing.visible=true;
}
}
so that your code tests for the currentCount on each tick of the timer and finally does something about it.
Read up on 'while' loops - they don't do exactly what you think they do and it's easy to get 'em into infinite repitions if you don't increment the thing that you're changing within the loop.

AS3: Issues with multiple save/load slots

I'm trying to take this very simple "game" and give it three save/load slots. Following a separate tutorial I can make it work with a single save slot but once I try adding more, it gives me the following error message.
1046:Type was not found or was not compile-time constant: save2.
1046:Type was not found or was not compile-time constant: save3.
I am new to actionscript 3 so I'm sure I'm being very newbish but I have tried to figure this out for quite some time now but just can't seem to. The whole thing is controlled by buttons already placed on the scene. I appreciate any help I can get.
The code:
import flash.net.SharedObject;
var saveDataObject:SharedObject;
var currentScore:Number = 0
init();
function init():void{
btnAdd.addEventListener(MouseEvent.CLICK, addScore);
btnSave1.addEventListener(MouseEvent.CLICK, save1);
btnSave1.addEventListener(MouseEvent.CLICK, saveData);
btnSave2.addEventListener(MouseEvent.CLICK, save2);
btnSave2.addEventListener(MouseEvent.CLICK, saveData);
btnSave3.addEventListener(MouseEvent.CLICK, save3);
btnSave3.addEventListener(MouseEvent.CLICK, saveData);
btnLoad1.addEventListener(MouseEvent.CLICK, save1);
btnLoad1.addEventListener(MouseEvent.CLICK, loadData);
btnLoad2.addEventListener(MouseEvent.CLICK, save2);
btnLoad2.addEventListener(MouseEvent.CLICK, loadData);
btnLoad3.addEventListener(MouseEvent.CLICK, save3);
btnLoad3.addEventListener(MouseEvent.CLICK, loadData);
}
function save1(e:MouseEvent):void{
saveDataObject = SharedObject.getLocal("savefile1");
}
function save2(e:MouseEvent):void{
saveDataObject = SharedObject.getLocal("savefile2");
}
function save3(e:MouseEvent):void{
saveDataObject = SharedObject.getLocal("savefile3");
}
function addScore(e:MouseEvent):void{
currentScore += 1;
updateScoreText();
}
function saveData(e:MouseEvent):void{
saveDataObject.data.savedScore = currentScore;
trace("Data Saved!");
saveDataObject.flush();
trace(saveDataObject.size);
}
function loadData(e:MouseEvent):void{
currentScore = saveDataObject.data.savedScore;
updateScoreText();
trace("Data Loaded!");
}
function updateScoreText():void
{
txtScore.text = ("Score: " + currentScore);
trace("Score text updated");
}
I tried your code and it works like a charm...
Anyways, I've made a simpler version that doesn't use so many functions and Events.
Here is a pure AS3 version of it (just save it as Test.as3 and use as Document Class in Flash), but you can copy the content of the Test() method and paste in a action frame.
package
{
import flash.display.Sprite;
import flash.events.MouseEvent;
import flash.net.SharedObject;
import flash.text.TextField;
public class Test extends Sprite
{
public function Test()
{
/***** START: Faking buttons and field *****/
var txtScore:TextField = new TextField();
addChild(txtScore);
var btnAdd:Sprite = new Sprite();
var btnSave1:Sprite = new Sprite();
var btnSave2:Sprite = new Sprite();
var btnSave3:Sprite = new Sprite();
var btnLoad1:Sprite = new Sprite();
var btnLoad2:Sprite = new Sprite();
var btnLoad3:Sprite = new Sprite();
var items:Array = [btnAdd, null, btnSave1, btnSave2, btnSave3, null, btnLoad1, btnLoad2, btnLoad3];
for (var i:int = 0; i < items.length; ++i)
{
var item:Sprite = items[i];
if (item)
{
item.graphics.beginFill(Math.random() * 0xFFFFFF);
item.graphics.drawRect(0, 0, 100, 25);
item.graphics.endFill();
item.x = 25;
item.y = i * 30 + 25;
addChild(item);
}
}
/***** END: Faking buttons and field *****/
var saveDataObject:SharedObject;
var currentScore:Number = 0
btnAdd.addEventListener(MouseEvent.CLICK, addScore);
btnSave1.addEventListener(MouseEvent.CLICK, save);
btnSave2.addEventListener(MouseEvent.CLICK, save);
btnSave3.addEventListener(MouseEvent.CLICK, save);
btnLoad1.addEventListener(MouseEvent.CLICK, load);
btnLoad2.addEventListener(MouseEvent.CLICK, load);
btnLoad3.addEventListener(MouseEvent.CLICK, load);
function getLocal(target:Object):String
{
if (target == btnSave1 || target == btnLoad1)
{
return "savefile1";
}
else if (target == btnSave3 || target == btnLoad2)
{
return "savefile2";
}
else if (target == btnSave2 || target == btnLoad3)
{
return "savefile3";
}
}
function save(e:MouseEvent):void
{
var local:String = getLocal(e.target);
saveDataObject = SharedObject.getLocal(local);
saveDataObject.data.savedScore = currentScore;
trace("Data Saved!");
saveDataObject.flush();
trace(saveDataObject.size);
}
function load(e:MouseEvent):void
{
var local:String = getLocal(e.target);
saveDataObject = SharedObject.getLocal(local);
currentScore = saveDataObject.data.savedScore;
updateScoreText();
trace("Data Loaded!");
}
function addScore(e:MouseEvent):void
{
currentScore += 1;
updateScoreText();
}
function updateScoreText():void
{
txtScore.text = ("Score: " + currentScore);
trace("Score text updated");
}
}
}
}

Action script 3 drawing app undo and redo function

Can anyone show me how can I make undo and redo function? so this is my current action script. I cant figure how to do it and i see some example in some web site, the action script is to long to under stand. Pls show a simple way that i can make this work..
sorry for bad grammar...
import flash.display.MovieClip;
import flash.events.MouseEvent;
var pen_mc:MovieClip;
var drawing:Boolean = false;
var penSize:uint = 1;
var penColor:Number = 0x000000;
var shapes:Vector.<Shape>=new Vector.<Shape>();
var position:int=0;
const MAX_UNDO:int=10;
function init():void{
pen_mc = new MovieClip();
stage.addEventListener(MouseEvent.MOUSE_DOWN, startDrawing);
stage.addEventListener(MouseEvent.MOUSE_MOVE, isDrawing);
stage.addEventListener(MouseEvent.MOUSE_UP, finishedDrawing);
addChild(pen_mc);
}
init();
function startDrawing(e:MouseEvent):void{
trace("Pen Has started drawing");
drawing = true;
pen_mc.graphics.lineStyle(penSize, penColor);
pen_mc.graphics.moveTo(mouseX, mouseY);
}
function isDrawing(e:MouseEvent):void{
if(drawing){
pen_mc.graphics.lineTo(mouseX, mouseY);
}
}
function finishedDrawing(e:MouseEvent):void{
trace("finished drawing");
drawing = false;
var sh:Shape=new Shape();
sh.graphics.copyFrom(pen_mc.graphics); // put current state into the vector
shapes.push(sh);
if (shapes.length>MAX_UNDO) shapes.unshift(); // drop oldest state
position=shapes.indexOf(sh);
}
function undo():void {
if (position>0) {
position--;
pen_mc.graphics.copyFrom(shapes[position].graphics);
} // else can't undo
}
function redo():void {
if (position+1<shapes.length) {
position++;
pen_mc.graphics.copyFrom(shapes[position].graphics);
} // else can't redo
}
function btn_undo(e:MouseEvent):void
{
undo();
}
function btn_redo(e:MouseEvent):void
{
redo();
}
undo_btn.addEventListener(MouseEvent.CLICK, btn_undo);
redo_btn.addEventListener(MouseEvent.CLICK, btn_redo);
You can use copyFrom() in Shape.graphics to store current condition, and the same to "redo", as your canvas is a Shape.
var shapes:Vector.<Shape>=new Vector.<Shape>();
var position:int=0;
const MAX_UNDO:int=10;
...
function finishedDrawing(e:MouseEvent):void{
trace("finished drawing");
drawing = false;
var sh:Shape=new Shape();
sh.graphics.copyFrom(penMC.graphics); // put current state into the vector
shapes.push(sh);
if (shapes.length>MAX_UNDO) shapes.unshift(); // drop oldest state
position=shapes.indexOf(sh);
}
function undo():void {
if (position>0) {
position--;
penMC.graphics.copyFrom(shapes[position].graphics);
} // else can't undo
}
function redo():void {
if (position+1<shapes.length) {
position++;
penMC.graphics.copyFrom(shapes[position].graphics);
} // else can't redo
}
This approach lacks some features, as to drop part of undo/redo stack if first undone to a certain point, then drawn. You can try adding this function yourself.