HTML5 Canvas [110]
mouseY >= pieceY
The mouse pointer lies lower than or equal to the top of the piece.
mouseY <= pieceY+partHeight
The mouse pointer lies above or equal to the bottom of the piece.
mouseX >= pieceX
The mouse pointer lies to the right or equal to the left side of the piece.
mouseX <= pieceX+partWidth
The mouse pointer lies to the left or equal to the right side of the piece.
All of the above conditions must evaluate to true for a hit to be registered on any one piece on the board:
if ( (mouseY >= pieceY) && (mouseY <= pieceY+partHeight) && (mouseX >= pieceX) &&
(mouseX <= pieceX+partWidth) ) {
If all these conditions are true, we set the selected property of the piece object to true if it was already false, or we set it to false if it was already true. This allows the user to “deselect” the selected piece if he has decided not to move it:
if ( board[c][r].selected) {
board[c][r].selected = false;
} else {
board[c][r].selected = true;
}
}
At the end of the nested for:next loop, we make sure to test each piece to see whether its selected property is true. If so, we push it into the selectedList local array so we can perform the swap operation on the pieces:
if (board[c][r].selected) {
selectedList.push({col:c,row:r})
}
}
}
Swapping two elements in a two-dimensional array
Now we need to test to see whether two pieces have been marked as selected. If so, we swap the positions of those pieces. In this way, it appears that the player is clicking on puzzle pieces and changing their locations to try to solve the puzzle.
To achieve the swap, we use a classic three-way swap programming construct utilizing a temporary variable, tempPiece1, as a placeholder for the values we are going to swap. First, we need to create a couple variables to hold the selected pieces. We will use selected1 and selected2 for that purpose. Next, we move the reference to the piece represented by selected1 into the tempPiece1 variable:
if (selectedList.length == 2) {
var selected1 = selectedList[0];
var selected2 = selectedList[1];
var tempPiece1 = board[selected1.col][selected1.row];
board[selected1.col][selected1.row] =
Next, we move the piece referenced by selected2 to the location in the board array of the piece represented by selected1 (the first swap). Then we apply the piece referenced in selected1 to the position represented by selected2 (the second swap). Finally, now that they are swapped, we make sure to set the selected properties of both pieces to false:
board[selected2.col][selected2.row];
board[selected2.col][selected2.row] = tempPiece1;
board[selected1.col][selected1.row].selected = false;
board[selected2.col][selected2.row].selected = false;
}
}
NOTE
This part of the function works because we have limited the number of pieces that can be selected to 2. For a game such as poker, which requires the player to select five cards, you would use a slightly different algorithm that tests for 5 cards instead of 2, and then calculate the value of the hand.
Testing the game
Believe it or not, that is all the code we need to talk about—the rest you have seen many times before. Try running the game (CH6EX10.html). When it loads, you should see the video organized in a 16-piece grid. Each part of the video will be playing, just like one of those magic tricks where a woman appears to be separated into multiple boxes but her legs, arms, and head are still moving. In fact, this game is sort of like one of those magic tricks because, in reality, the video was never “cut” in any way. We simply display the parts of the video to make it appear to be cut into 16 independent, moving pieces that can be swapped to re-form the original video.
Example 6-10 shows the full code listing for the Video Puzzle application.
Example 6-10. Video puzzle