I was going through my portfolio recently and realized that I have an entry for my Press Your Luck game but I’ve only described how it works, never taken a deep dive into the code.
The current version (if you can call something no longer in use “current”) runs entirely on the client side. There is one HTML file (with inline jQuery), one CSS file, an XML file with configuration values, and a handful of images and sounds.
Some parts of these files have been modified for display purposes. None of the changes impact functionality.
We’ll start with the config file…
We’re defining a set of images, the tiles that make up the game board. Each has a thumbnail (the image displayed on the standard game board) and a full-size image (the one displayed in the center when that tile is selected by the player) and we define their URLs here. We also define whether this is a prize image or a whammy, which determines what sound plays when that tile is selected.
Fairly simple. Now we move on to the CSS…
More pretty simple stuff. The page has a background. There’s a div that contains all the game elements. Those are positioned as needed. The tiles have a background image for their active and inactive states. The sound controls are hidden.
Now we get to the fun, the HTML and jQuery. Here’s the full page, we’ll break down the important parts afterwards…
Get the basic stuff out of the way… We import our CSS. We import jQuery UI. We lay out the game board and we set up some audio elements for the game sounds (which I pulled from some site that had all sorts of game show sounds archived, I can’t remember where it was).
The first thing we do is initialize some stuff. Define our board images, build our possible game boards, throw a board onto the screen. Now let’s see how we do that.
We’re loading that config file, then looping through each “image” element to find the “thumb”, “large”, and “type” definitions we discussed earlier. Then we’re dropping those into an array.
When I wrote this I was shocked that there wasn’t an easier way to do this using XML. If it were similarly-structured JSON, it’d just parse automatically. Instead I have to do it manually. Considering what the X in AJAX stands for, I expected more out-of-the-box support for XML. Maybe I’m just missing something.
With our available images defined, we cache a set of fifty possible game boards. We do this by shuffling the array of images (using a function I just grabbed from somewhere else) and adding them in order to a new set until there are 18 in that set. If we run out before we get to 18, we shuffle again and keep going. This means we can have as many or as few (as long as there’s at least one) images configured.
Finally we load the game board. We make sure no tiles are active, we set the middle image back to our placeholder, we get a randomly-selected one of our cached tile sets and display it on the board. Then we define some key events that allow the game to be controlled from the keyboard or from a presentation mouse, so that any event will trigger the start of the game. We bind the same action on touchend so that the person who commissioned this can play on her phone.
Our function for getting a random set is simple enough. Get a random number from 0 to the size of the set (should always be 50). If we don’t want to allow the same set to be picked twice in a row, compare that number to the current one and do it again until we get something different. Return the set of images with that number as the key.
To print out the board, we loop through each image on the board that isn’t the one in the middle. We use the index of the image and pull from the array we set in get_random_set() to reset said image’s attributes.
Ahh, yes, now we start the actual gameplay. We wipe out all of the events we set earlier and set new ones on the same triggers, this time for stopping the game. We start playing our in-game music. Then we set an interval to reload the game board every 850 milliseconds (allowing for the same board to be played twice in a row this time) and for the active tile to shift every half-second. I got those numbers from watching way too much Press Your Luck.
How do we switch the active tile? Well we know there are 18 tiles so we randomly select a number 0 to 17 until that number is not the same as the one we’ve already got. Then we remove the active class from whatever tile is active and add it to the one that corresponds to our randomly-selected number.
Our last step is to stop the game and it’s made up of a bunch of little things.
First we clear our intervals so the game won’t continue, then we wipe out our event bindings and set up new ones for the same triggers. These new ones will reset the game board and get us in a position to start a new game.
We get the winning tile and stop the in-game music. Based on what type of image that winning tile is, we play either the “buzz-in” sound or the “whammy” sound.
This is how we make the lights around the winning tile flash and it’s ugly. We add and remove the “active” class from that tile in 100 millisecond intervals. Partway through that, we change the center image on the game board to match that of the winning tile. Again, those times were selected from watching way too much Press Your Luck.
And that’s really all there is to it. There may be a better way by now (I hope there is for that flashing bit) but this is what I knew at the time. It was a lot of fun to write and it was a lot of fun to see people play.