Undo & Redo
[ October 07, 2003 ] by Roberto Valdunciel, alias Rober
Adding "Undo" and "Redo" buttons to increase playability in puzzle games.


In puzzle-like games where you perform movements in some order to resolve a level, you can add undo and redo buttons to increase playability.

You need 2 arrays: UndoArray and RedoArray. So everytime you perform an action, you store some information that TOTALLY describe this action in UndoArray. Add it to last position.

The content of an action to store in the arrays it's usually a set of variables: an array. For example the position x,y of a block and the direction dx,dy of the movement: [x,y,dx,dy]. But what is an action? You must decide what you want to be able to undo or redo. In a game where a character moves blocks, perphaps you want only to undo block movements, not character free movements...

When you press undo button you extract last position of UndoArray and use it to undo the action, while moving this action to RedoArray. For redo an action just reverse this process. Then, first action to be undone is last in UndoArray and first action to be redone is last in RedoArray. Note that when you perform a new action, if there's any content in RedoArray you must delete it.

To undo an action, we use same instructions that performing it but reversing things. Then, if clicking somewhere gives a point, we just store where we click [x,y], and when undoing the action we check if this position gives a point or not (we don't need to store that it gives a point). So if it gives a point, when undoing removes one. To redo an action we do things as performing it.

CODE

UndoButton.onRelease = Undo;
RedoButton.onRelease = Redo;
 
function Undo()
{
	//EXTRACT LAST UNDO ACTION wHILE MOVING IT TO REDO
	redoArray.push(action = undoArray.pop());
	//UNDO THE ACTION
	x = action[0];
	y = action[1];
	moves--;
	//more instructions in reverse way that move()...
}
 
function Redo()
{
	//EXTRACT LAST REDO ACTION wHILE MOVING IT TO UNDO
	undoArray.push(action = redoArray.pop());
	//REDO THE ACTION
	x = action[0];
	y = action[1];
	moves++;
	//more instructions like in move()...
}

//PRESSING IT'S AN ACTION, HERE
board.onPress = move;
 
function move()
{
	//ADD THE ACTION TO UNDOARRAY
	undoArray.push([x,y]);
	//EMPTY OUT REDOARRAY
	redoArray.length=0
	//performs the action
	moves++;
	//more instructions...
}

We can also use one array storing all performed actions, along a cursor that stores current position. To undo we use cursor position in the array, to redo cursor next position. On performing a new action, we delete all values after the cursor and add the action at the end of the array.

APPLICATIONS

When we resolve a level, UndoArray content it's the level solution. We can send this solution to a server script to save it in a db. Then, to play the level solution, we go through each value like when redoing. Knowing we can't send and array to the script, the first try would be:

solution = UndoArray.toString();
//if UndoArray = [[4,4,-1,0],[4,4,0,1],[3,4,0,-1],[3,3,0,-1],[4,3,1,0]]
//solution = "4,4,-1,0,4,4,0,1,3,4,0,-1,3,3,0,-1,4,3,1,0"

But it's difficult to play the solution from this string. We can store the string separating each UndoArray value with a semicolon:

for(i = 0; i < UndoArray.length; i++)
{
	solution += UndoArray[i] + ";";
}
solution = solution.substr(0,solution.length-1);
//solution = "4,4,-1,0;4,4,0,1;3,4,0,-1;3,3,0,-1;4,3,1,0"

To restore UndoArray from this string:

UndoArray = solution.split(";");
for(i in UndoArray) UndoArray[i] = UndoArray[i].split(",");

We can apply all this stuff to a word processor, paint application...



 
 
Name: Roberto Valdunciel, alias Rober
Location: Barcelona, Spain
Age: 26
Flash experience: 2-3 years
Job: University student
Website: http://www14.brinkster.com/boulderflash/
 
 
| Homepage | News | Games | Articles | Multiplayer Central | Reviews | Spotlight | Forums | Info | Links | Contact us | Advertise | Credits |

| www.smartfoxserver.com | www.gotoandplay.biz | www.openspace-engine.com |

gotoAndPlay() v 3.0.0 -- (c)2003-2008 gotoAndPlay() Team -- P.IVA 03121770048