Mission Accomplished
We used a wide range of jQuery and plain-vanilla JavaScript over the course of this project to create this simple game. We also looked at using jQuery UI's draggable component as well as the localStorage API.
We covered a lot of code so let's briefly look back at what we did.
We first declared most of the variables that we used throughout the project right at the start of our document.ready
function. It's useful to do this so that variables can be used throughout our code without making them global in scope. For performance reasons, it's also best to cache jQuery objects so that they can be manipulated frequently without having to keep selecting them from the page.
We then saw how we can easily split an image of a known aspect-ratio into a number of equally-sized pieces laid out in a grid using nothing but some nested for
loops and some simple mathematics. We also saw that using an array of substrings to create a string instead of using string concatenation is a very easy optimization that can help speed up our applications when long strings need to be constructed.
We then saw how to shuffle the individual pieces into a random order using an accepted algorithm for randomizing – the Fisher-Yates shuffle. We didn't actually use jQuery at all to do this, but don't forget that the code to produce the shuffle was executed inside an event handler added using jQuery's on()
method.
Next we looked at how to make the pieces of the puzzle draggable using jQuery UI. We looked at some of the configurable options exposed by the component, as well as how to react to different events generated when the pieces were dragged. Specifically, we used the start
, drag
, and stop
callbacks to enforce the rules of the game concerning which pieces could be moved, and how they could be moved during game play.
After this we looked at using a standard JavaScript timer to keep track of how long it took to solve the puzzle, and how to keep the visible timer on the page updated so that the player could see the time that has elapsed since they started.
Detecting when the puzzle was solved was also a crucial ability of the code. Our main obstacle here was the fact that the pieces weren't selected from the page in the visible order we could see on the screen, but this was easily overcome by selecting the pieces using their numbered id
attributes and then manually checking their CSS position.
Lastly we looked at how to keep a record of the player's best time in solving the puzzle. localStorage is the obvious choice here, and it was a small step to check whether a score was already stored, and then compare the current time with the stored time to see if the record had been beaten.