Showcase and discover digital art at yex

Follow Design Stacks

Subscribe to our free newsletter to get all our latest tutorials and articles delivered directly to your inbox!

Making the puzzle click-and-drop accessible

Making the puzzle click-and-drop accessible

Now you are ready to add some code. You want to program the pieces in such a way that they can be placed not only by using the mouse but also by the keyboard. You want users to be able to click a piece to make it “stick” to the mouse until they click again to release it. You also want to be able to tab to a piece, press Enter to pick it up, then tab to the proper hit area, and press Enter again to release the piece in place.

Start by writing all this down in pseudocode. Describe how you are going to tackle this combination between tabbing to a puzzle piece and using the mouse:

On pressing a puzzle piece:
If the piece was not picked up yet: pick up piece
Else stop dragging the piece and place the piece
If the piece is over the right hit area, then place piece
Else make piece spring back to its original location
On pressing a hit area:
If the user is tabbing only
If there was no piece selected,
play warning "select a piece first"
If selected piece corresponds to that hit area,
then place piece
Else make piece spring back to its original location
On moving the mouse:
Alert the game that the user is no longer tabbing
When a piece is selected, turn on dragging
On pressing the Tab key
Alert the game that the user is tabbing

Clicking a puzzle piece with the mouse is equal either to picking it up or trying to place it because the piece is under the mouse when it is dragged. Of course, when someone is not using the mouse, the piece stays in its place and the user has to press Enter in the hit area to place the piece.

You also have to keep in mind that someone might switch from tabbing to using the mouse. Therefore, keep checking for an onMouseMove event.

To detect whether or not the user is tabbing, add this code on the main Timeline to detect a Tab keypress:

// global variables
var tabbingON = false;

// track to see if user is tabbing
function down( ) {
if (x = Key.isDown(Key.TAB)) {
tabbingON = true;
}
delete this.onKeyDown; this.onKeyUp = up;
}
function up( ) {
this.onKeyUp = undefined;
this.onKeyDown = down;
}
var keyListener:Object = new Object( );
keyListener.onKeyDown = down;
Key.addListener(keyListener);

Tip: Check the above keyListener code by adding a trace statement. Also you can tab through your Flash content in preview mode after first selecting Control > Disable Keyboard Shortcuts to turn off keyboard shortcuts.

Fill in the pseudocode on the puzzle pieces and enter functions where you might be reusing code somewhere else:

// puzzle pieces
pp1.onPress =
pp2.onPress =
pp3.onPress =
pp4.onPress =
pp5.onPress =
function() {
stopDrag(); if (tabbingON || !draggingON) {
pickupPiece(this._name);
}
// if puzzle piece is in right spot, then place
else if (eval(_root[this._name]._droptarget)
== _root["hitarea" + selectedPiece]) {
placePiece(this._name);
// if puzzle piece is not in right spot, then return it
} else {
returnPiece(this._name);
}
}

Also fill in the pseudocode for the hit areas:

// hitareas
hitarea1.onPress =
hitarea2.onPress =
hitarea3.onPress =
hitarea4.onPress =
hitarea5.onPress =
function() {
n1 = Number(subString(this._name,8,9));
if (tabbingON) {
// when no piece is picked up
if (selectedPiece == 0) {
playSound("nopiece");
// when it is in the right place, place it
} else if (_root.selectedPiece == n1) {
placePiece("pp" + selectedPiece);
// when it is in the wrong place, play message
} else {
returnPiece("pp" + selectedPiece);
}
}
}

Next, add an onMouseMove event that checks when the user starts to move the mouse. You want to start the dragging not on clicking a puzzle piece, but when the mouse starts moving:

// check to see if the mouse is moved
onMouseMove = function () {
tabbingON = false;
if (selectedPiece > 0) {
_root["pp" + selectedPiece].startDrag(true);
}
}

When players pick up a piece, you want several things to happen. You want to elevate the piece so that, while being dragged, it will not move behind any of the other puzzle pieces. You can do this by swapping its depth and putting the selected puzzle piece always onto level 10:

_root[ppName].swapDepths(10); 

You want to alert the game that players are now dragging a piece, even though the piece is left in place when tabbing. Do this by creating a global variable called draggingON:

draggingON = true; 

Keep track of the current selected piece by creating another global variable and getting the piece number from the puzzle piece’s instance name:

selectedPiece = Number(subString(ppName,3,4)); 

Play a sound to alert the visually impaired user that the puzzle piece was indeed picked up. Later on, you will write the playSound function because you will use it a lot.

The final function looks like this:

function pickupPiece(ppName) { 
_root[ppName].swapDepths(10);
draggingON = true;
selectedPiece = Number(subString(ppName,3,4));
if (tabbingON) {
playSound("yourturn03");
}
}

When placing a piece, you want players to match the pieces with the x and y coordinates of the hit areas:

_root[ppName]._x = _root["hitarea" + selectedPiece]._x;
_root[ppName]._y = _root["hitarea" + selectedPiece]._y;

Set the dragging variable to false and change the selectedPiece variable to 0, because no piece is now selected. Also keep a running tally of how many pieces have been placed just in case you want to add feedback to the user—such as “Great Job!”—at the end of the puzzle. Increase the global variable total by 1:

draggingON = false;
total += 1;
selectedPiece = 0;

The final function would look like this:

function placePiece(ppName) {
if (tabbingON) {
playSound("right");
}
_root[ppName]._x = _root["hitarea" + selectedPiece]._x;
_root[ppName]._y = _root["hitarea" + selectedPiece]._y;
draggingON = false;
total += 1;
selectedPiece = 0;
}

When a player places a piece incorrectly, you want the piece to spring back to its original spot. In order to do this, capture the original x and y coordinates of each puzzle piece into an array before game start. If you do this dynamically, you can always move the pieces around later as well, or have them be shuffled by some ActionScript:

// global variables
var origPos:Array = new Array();

function initGame() {
// initialize array with original x
// and y positions of the puzzle pieces
for (i = 1; i <= totalPieces; i++) {
origPos[i] = new Array(2);
origPos[i][0] = _root["pp" + (i)]._x;
origPos[i][1] = _root["pp" + (i)]._y;
}
}

Use this array when you write the function for returning a piece.

To play a sound indicating the piece cannot be placed, set draggingON back to false, and selectedPiece back to 0:

function returnPiece(ppName)  {
if (tabbingON) {
playSound("wrong");
}
_root[ppName]._x = origPos[selectedPiece][0];
_root[ppName]._y = origPos[selectedPiece][1];
draggingON = false;
selectedPiece = 0;
}

Comments