AJAX Tutorial: Hangman Game (no database required)
Last year I made an PHP tutorial of an OOP Hangman game (no database required) for a Siminar I spoke at. This year as a part of my new Game Tutorial Series I’m adding a new tutorial to my collection. This tutorial will teach you how to modify the PHP hangman game we created and add some AJAX to it using jQuery so we don’t have to refresh the page every time we guess a new letter or start a new game. If you haven’t followed along with the original PHP tutorial I would strongly suggest you do as I won’t touch on anything introduced in the last one.
Download the Working Source Code
.zip archive
Getting jQuery
First thing is first we’ll need to get the jQuery library before we start updating any code. For those of you that don’t know, jQuery is code library that makes doing JavaScript quick and pretty painless. You can download or link to a copy offered on a Content Delivery Network (CDN) like Google Code. Personally I recommend downloading a copy if you’re going to post this game on a high traffic/visibility website. Sometimes if you link to a copy of jQuery on a CDN your site can experience lag and/or delays if the CDN is slow and your game won’t work at all if the CDN is down. On the other hand if you have a small website or limited space to store your files then there’s no need to download a copy of jQuery, linking to it is a better option. In this tutorial I’ve downloaded and included the jQuery file in the js folder of the .zip archive.
Setting Up For AJAX
Because we want our game to display using AJAX we need to create a new JavaScript file called hangman.js. This is what we’ll use to make all of our AJAX calls and respond to the player’s input.
Now that we have two JavaScript files we have to update our index.php file so it knows both of those JavaScript files are necessary to run the game. In the <head> tag, under the link to our stylesheet, we add two lines of code that tell our browser to load our JavaScript files:
<head> <title>Hangman</title> <link rel="stylesheet" type="text/css" href="inc/style.css" /> <script language="Javascript" src="js/jquery-1.7.1.min.js"></script> <script language="Javascript" src="js/hangman.js"></script> </head>
We also need to remove our $_SESSION[‘game’][‘hangman’] check from the top of our index file. Our AJAX calls will be running the game so it’s no longer necessary here. However we leave the session_start() at the top of the page so that if the player accidentally refreshes the page they don’t loose the game they had in progress.
Next we remove the code inside of our <div id=”content”> and set that aside for later because we’ll need to use parts of it in our AJAX. In it’s place we’re going to enter a loading message. This is what the page will display before the AJAX calls have finished processing.
<body> <div id="content"> <center>Loading Hangman.... please wait.</center> </div> </body>
Writing the Hangman.js File
Now it’s time to jump into jQuery and AJAX.
$(document).ready(function() { //start the game when the page loads playGame(); });
jQuery uses a special function to check when the page has finished loading. Anything you put inside of this function will run as soon as the page is loaded, or in response to something someone has done on the page, like mouse clicks or using the keyboard. For this tutorial all we need it to do is call our AJAX function that will load and display the game to the content div on our index.php file.
/*** * Purpose: play hangman * Preconditions: none * Postconditions: new game has started or existing game is in play ***/ function playGame() { $.ajax({ url: 'ajax/index.php', data: {type: 'playGame'}, success: function( data ) { $("#content").html(data); } }); }
Inside of our playGame() function we use AJAX to tell the browser to load our ajax file and send it some data (the type of action we’re doing, whether or not to start a new game, the letter the player guessed). Then we use a success callback function to load the results of our ajax call onto the page. A callback function is a function that runs as a result of being called by another process. In this case our callback function, success, is loading the data we’ve retrieved through AJAX and putting it into the content div’s HTML property.
/*** * Purpose: guess a letter * Preconditions: none * Postconditions: game status updated ***/ function guessLetter() { //make sure they've entered something into the box if (!$("#letter").val()) { alert("You must enter a letter."); return; } //check to make sure they've entered a letter if (!isLetter($("#letter").val())) { alert("This is not a letter. Please enter a letter."); //clear out the value in the input box $("#letter").val(""); return; } //if it was a letter then submit the guess $.ajax({ url: 'ajax/index.php', data: {type: 'playGame', letter: $("#letter").val()}, success: function( data ) { $("#content").html(data); } }); } /*** * Purpose: check to see if a value is a letter * Preconditions: value to check * Postconditions: returns true if this is a letter ***/ function isLetter(value) { var lettersOnly = /^[a-zA-Z]+$/; //check to make sure there are no numbers and the value isn't more than 1 characters if(value.match(lettersOnly) && value.length == 1) return true; //otherwise this isn't a letter return false; }
If we want to respond to someone trying to guess a letter we use a fairly similar process. Our guessLetter function checks to make sure the player has entered a value into our letter input box, then checks to make sure the value inside of it is really a letter, and finally uses an AJAX call to update the game by passing it the letter entered.
/*** * Purpose: start a brand new game * Preconditions: none * Postconditions: new game has started ***/ function newGame() { $.ajax({ url: 'ajax/index.php', data: {type: 'playGame', newgame: true}, success: function( data ) { $("#content").html(data); } }); }
The last piece of our ajax file is the newGame function. When the game is over we want to make sure we use AJAX to update the game state and then refresh the page to a new game.
Writing the AJAX File
Now that our JavaScript file will send AJAX requests we need to write the file on the other end of the request — the file that responds to the data we’re sending it. Create a new folder and name is ajax. Inside of it make an index.php file. Inside of the file put the following:
<?php //include the required OOP files require_once('../oop/class.game.php'); require_once('../oop/class.hangman.php'); //this will keep the game data as they make a new ajax request session_start(); //respond to AJAX requests echo doAction($_GET); function doAction($_GET) { switch ($_GET['type']) { case "playGame": return playGame($_GET); default: return "Invalid option selected."; } } /*** * Purpose: Display and play the game * Preconditions: a game exists * Postconditions: the current game is displayed to the screen ***/ function playGame($_GET) { //if they haven't started a game yet let's load one if (!$_SESSION['game']['hangman']) $_SESSION['game']['hangman'] = new hangman(); echo "<h2>Let's Play Hangman!</h2>"; $_SESSION['game']['hangman']->playGame($_GET); }
In this file we have two functions, doAction and playGame. Both functions take the $_GET data sent by our AJAX calls and do various things depending on the data sent to them. doAction is run every time this ajax file loads. It decides which function it needs to call, depending on the type we’ve sent it, and then returns the result to the screen.
Now pull up that code I had you set aside earlier. We’re going to move that into our playGame function with a few adjustments. We no longer need the <form> tags around our game data. In addition instead of sending $_POST data to our hangman object we’re now sending $_GET data. The $_GET data contains the information we were previously posting from the <form> tags. Since AJAX is refreshing what appears inside of our content div there’s no reason to use our <form> and $_POST variables anymore.
Last But Not Least
We’re almost done! Before we can view our handy work we need to open our hangman OOP file. Anywhere we had a $_POST statement we need to change that to a $_GET since we’re no longer using the $_POST variable.
Finally, we need to update our new game and guess buttons so they run the newGame and playGame javascript functions we wrote earlier:
<input type="text" name="letter" value="" size="2" maxlength="1" id="letter" /> <input type="submit" name="submit" value="Guess" onClick="guessLetter()" /> <div id="start_game"><input type="submit" name="newgame" value="New Game" onClick="newGame()" /></div>"
Conclusion
Well, that wasn’t so hard now was it? Try the working version to see what it’s like! In this tutorial we took our existing PHP Hangman game and modified it to use AJAX. If you play the game you’ll see the page no longer has to refresh each time you click the guess letter button or the new game button. To accomplish this we first downloaded jQuery, created a JavaScript file to make AJAX requests, wrote a file to return a response to our AJAX requests, and then updated our hangman class to use $_GET and our new JavaScript functions.
Do you have the native files for this project? I followed the tutorial and I can not get it to work.
Yes you can download them here: http://design1online.com/downloads/hangman_ajax.zip
Thank you! Great tutorial by the way.
You’re welcome, I’m glad you enjoyed it! I have other versions of it coming (flash, angular) just haven’t had time to post them yet 🙂