Dana Vrajitoru
B583/C490 Game Programming and Design

Lab 1

Date: Thursday, September 1, 2011. To be turned in by Thursday, September 8, for 10 points of the homework. Here is an example of the intended result.

In this lab we'll get used to the Flash environment and write a small program using it. Boot your computer on MacOS and open Flash CS5. You'll see a dialog that allows you to create a new project. Choose ActionScript 3.0. Then in the drop-down menu on the right side of the screen, left of the search box, switch your environment style to Classic.

Ex. 1. In this lab we will implement a simple version of the game of Hangman. Save your project under this name.

a. Stage Setup. The big white rectangular area under the title of your project is called the Stage. This represents the graphical area on which the app will run.

Start by setting the background color of the stage. On the right, under Properties, you'll see the label Stage next to a small white rectangle. Click on it and choose a color that you want.

The tools in the bar to the left of the window can be used to vector draw in the stage. Start by drawing the gallows somewhere to the left of the stage. Using the selection tool at the top of the toolbar, select all the objects that compose the gallows. From the Modify menu, choose Group. Now they should act like one entity. Move it around the stage a little to see that it works as a group. Then from the Modify menu select Convert to Symbol. In the dialog that opens give it the name gallows and choose the type Graphic. This is a type of symbol that we don't intend to interact with in the app.

Using the drawing tools, create a stick figure head. Note that you can find an oval in a drop-down menu attached to the rectangle. Group the objects composing the head and the convert it to a symbol. Give it the name HeadClass (we'll use a simpler name for the instance name). Choose the type Movie Clip for this one because we'll need to manipulate it during the execution of the program. Note that in the Properties area there is a box now where you can enter an Instance Name. Call this object head. Basically the symbol name defines a class and the instance name defines a variable name that contains a reference to the object.

Repeat the procedure to create the body, each arm, and each leg (separately because we want to give the player more chances to guess letters). Name the symbols classes whatever you want and the instances for these objects body, leftArm, rightArm, leftLeg, rightLeg. Note that for the arms and legs you can create one of them, convert to a symbol, then make copies after that and give them different instance names. If you create the left arm, for example, convert to a symbol, then make a copy, you can apply the transformation Flip Horizontal found in the Modify menu, to convert it into a right arm, and then you can re-position it. Each of these must have their own instance name, but they can be instances of the same class.

Interface Objects. We still need a few interface objects before we go and start writing code.

First, we'll need a text box where the word to be guessed will be written. From the toolbar on the left, click on the Text Tool (it looks like a T). On the right side, under properties, in the first drop-down menu choose Classic Text, and in the second one choose Dynamic Text. This way we can edit its content in the code. Place a box under the gallows and stick figure and for now fill it with "_ _ _ _". Select the entire text (Command-A), and choose an appropriate font, color, size for the text. Then click on the Select Tool at the top of the toolbar and select this text that you have entered (as an object). Now in the Properties area you should be able to give it an instance name. Let's call this guessTxt.

Repeat the procedure to create another text are somewhere in the top-right area that will display the letters that the user has already entered. Let's call this text area historyTxt. Then create another text box in the right-center area and write "Your guess:" in it. Choose the type for this one to be Classic Text - Static Text. This box does not need an instance name because we will not need to modify it.

The last piece that we need to add is a text box that will receive as input the key guessed by the player. Create another text box under the label Your Guess and choose the style for it to be Classic Text - Input Text. Make the box of a reasonable size to store one letter. Below the Anti-Alias properties in the Character section of the Properties you'll see 3 little boxes. The one to the right should allow you to show a border around the text. Click on it to enable it. Give this object the instance name inputTxt. Make sure that all your dynamic text boxes are long enough to contain the text they may need to hold.

Before we proceed to the code, there is one more operation that we need to do in order for the movie to work properly. Select one of your text boxes. In the Properties area, under Character, you will see a button that says "Embed...". Click on it. In the dialog that opens, check the boxes for uppercase and lowercase alphabet letters. If the font is not given a name at the top, enter a name yourself, then click OK.

Code. Now that we have prepared everything we need, it's time to start writing some code. Let's test first what the movie will look like with Cmd-Enter. For now you should just see the content of your stage the way you've set it up.

Make sure that none of your objects is currently selected. Let's open the Actions panel from the Window menu. First, we want to start by hiding some of the objects in the stage. To hide the head of the stick figure, add the following line of code:

head.visible = false;

Do the same for all the other parts of its body. Test that the figure is not visible anymore with Cmd-Enter.

Next, we need to set up the content of the historyTxt object. For this, add the line:

historyTxt.text = "";

We can now add some code to start with a list of words from which we'll choose one at random, and then set up the guessedTxt object with the appropriate content. Let's declare this variable first:

var words:Array = new Array("", "", "");

Fill this array up with 10 words of your choosing, each delimited by quotes and separated by commas. Then declare three variables called word, guess, and history and initialize all of them with an empty string. Now let's write a function that chooses a random word out of the 10, stores it in the variable word, and then initializes the the variable guess with a string containing "_ " (underscore and one space) for each letter in the word. First, go to the top of the code and add the line

import Math;

The Math module contains a function called random returning a random number between 0 and 1 (non inclusive). If we multiply the result by 10 and then take the floor of it, we should obtain a random integer between 0 and 9. The last thing you need to know, a string object has a property called length that give you the number of characters in the string. Now add the following function at the end of the code::

function chooseWord() {
	var i = Math.floor(Math.random()*10);
	word = words[i];
	guess = "";
	for (i=0; i<=word.length; i++) {
		guess += "_ ";
	}
	guessTxt.text = guess;
}

Add a call to this function after the declaration of the two variables from the previous step. Test the application a couple of times to see if you get a different result.

The next function will handle the history. It receives as input the letter entered by the user and checks if it already stored in the history. If it is, then it returns false and we'll assume that the letter will be ignored. If it isn't, then it is added to the history variable and to historyTxt, and then the function returns true:

function checkAddHistory(letter:String) {
	var i = history.indexOf(letter);
	if (i>=0) {
		return false;
	} else {
		history += letter;
		trace(history);
		historyTxt.appendText(letter);
		trace(historyTxt.text);
		return true;
	}
}

Test this function to make sure it works.

Now you should be ready to write some code on your. First, we'll need an array to keep track of which characters in the word have been guessed so that we can display those on the stage instead of the underscore. We'll also need a variable that keeps track of how many characters are left to read. Add a variable called leftToGuess and the following array (both before the two functions are defined and before any function call):

var guessVisible:Array;

The in the function chooseWord, add the following:

guessVisible = new Array(word.length);

Inside the for loop in this function, initialize all the values of guessVisible as false.

Next, write a function called checkAddGuess taking as parameter a letter. This function should go through the string in the variable word and check if the character at position i (word.charAt(i)) is equal to the first letter in the string letter. If they are, then change the values of guessVisible[i] to true. Use a Boolean local variable in this function initialized as false to store the fact that we found a match or not. If we do find a match, then return true, otherwise return false (you can return the variable itself). Note that in case of a match you should not simply return true because you need to mark all the places that have been matched. In addition, for every match you find, decrease the value of the variable leftToGuess. Test this function.

We can now piece it together. We'll need another variable, called missed, initialized as 0. This will let us know how many characters the player has missed so that we know which body parts to make visible. Write another function that takes a letter as input, let's call it playLetter. This function should first check if the number of misses is greater than 7 or if the number of leftToGuess is equal to 0 (the or operator is the same as in C++), and if that's the case, simply return because the game is over. Otherwise, it should call the function checkAddHistory first. If this function returns false, then the function play should also return. Otherwise it should call the function checkAddGuess with the letter.

If the answer is true, it means that this is a good guess. In this case you should check if the number left to guess is now equal to 0, which means that the player has won the game. If that's true, then you have to let them know somehow, for example, by changing the history text box to "You won". Either way, you need to update the content of the variable guess in a way similar to what we have done in the function chooseWord. This time you need to check guessVisible[i] and if it is true, then you need to add the character at position i in the word and a space to the string guess, otherwise simply an underscore and a space like before. After the loop you need to update the text of guessTxt.

If the answer is false, then this is a bad guess and you have to increment the number of misses. Then based on the number of misses, you need to make visible one more body part by assigning the value true to its visible property. Make this a separate function that you can call here. Then if the number of misses is equal to 7, change the text of the guessTxt to the value of the word (so we show the player what they were supposed to guess), and then change the text of historyTxt to something like "You lost".

Test the function by calling it with a letter that might be in some of your words. Make sure you get the expected result when the letter is in the word and when it's not.

Keyboard Event. To be able to run the game we now need to attach a keyboard event to the inputTxt text box and make it call the function play with the result of the input. First, let's import a couple of modules at the top:

import flash.ui.Keyboard;
import flash.events.KeyboardEvent;

Then add the following function at the end of the code connecting the event with the function playLetter:

function captureInput(event:KeyboardEvent):void {
    if (event.keyCode == Keyboard.ENTER) {
        var letter:String = inputTxt.text;
        inputTxt.text="";
        if (letter.length > 1) {
            letter = letter.substr(0, 1);
        }
        playLetter(letter);
    }
}

Then last, we need to connect the input text box itself with the event:

inputTxt.addEventListener(KeyboardEvent.KEY_UP, captureInput);

Now if everything went well, your program should be fully functional.

Turn in: the source file .fla and the compiled version .swf. You can wait until you have finished the homework part to turn these in, since the homework continues this program.