Header
Pay just $29 for 70 fonts. Grab the Indie Font Bundle today & save over 97%
Advertisement

Create a Flickr-Based Pairs Game With Flash: The Basics

by

In this tutorial you’ll learn to build a card-matching game, in Flash, that uses Flickr as the source of its images. The first part of this two-part series will get you started, leaving you with a basic game structure that you can improve on later.

This game uses the Flickr API to get the images used for game play. In the SWF you will see the start page of the game. Pressing the PLAY button will allow you to begin a new game, the INSTRUCTIONS button will show the insructions for the game, and pressing the ABOUT button will give some information about the game. Try different keywords to retrieve different sets of photos: food is a good one!


Also available in this series:

  1. Create a Flickr-Based Pairs Game With Flash: The Basics
  2. Create a Flickr-Based Pairs Game With Flash: The Interface

Step 1: Getting a Flickr Account

To be able to use the Flickr Api you must be a registered user on flickr.com. On the homepage of Flickr choose the Sign Up link.



Step 2: Setting Up the App and Getting an API Key

Once logged in, you will need to visit the App Garden to get started.

You will want to bookmark this page if you are planning on doing alot of Flickr development, as it contains alot of useful information for developers.

Click on the "Create An App" Link once you arrive at the App Garden.


Under "Get your API Key" click the "Request an API Key" link.


Here you will need to choose whether you intend to use the app for commercial or non-commercial purposes. For this app I chose non-commercial.


Next you will be taken to the app details page. Enter the name of your app, a description of what your app does, accept the agreements, and click the submit button.


Next you will be presented with your key and your secret. We will not be using the secret key here as our app does not require authentication. Make a note of your API key as we will need it for the rest of this tutorial.



Step 3: Diving Into the Flickr API

Flickr has a Rest API for developers. We will be using two methods from the Rest API as listed below.

The flickr.photos.search method will allow us to search for photos, while the flickr.phots.getInfo method will allow us to get information for a single photo, such as the username(owner) of the Photo, the Title, and the URL to the photo on Flickr.

If you visit one of the links above, at the bottom of the page there is a link to the API Explorer where you can enter some data and get an example response.



The image above is for the flickr.photos.search method. Go ahead and click the link now.

There are a lot of options, and it may seem overwhelming, but all we are interested in for this tutorial is the "tags" option. I entered "dog" into the tags search box. Also make sure you choose JSON as the output method, as we will be using JSON in this tutorial. Finally press the "Call Method" Button. Once you press the "Call Method" button an example of the response will be returned.



Below is a portion of the JSON that is returned from choosing "dog" as a tag

We will be using the data from the response to construct our URLS to the images. The URLS take the form of: http://farm{farm-id}.static.flickr.com/{server-id}/{id}_{secret}_[mstzb].jpg

To make a usable URL we just replace what is inside the {} with the data we get from above, for example using the first response would yield the following:

http://farm6.static.flickr.com/5159/5892368188_05a32e3fea_s.jpg

And if we now use that link, we go to the photo http://farm6.static.flickr.com/5159/5892368188_05a32e3fea_s.jpg More info about the URLs can be found in the Flickr Documentation for Photo Source URLS.

Michael James Williams wrote a tutorial on Understanding JSON, be sure to check it out to learn about the intricacies of JSON.


Step 4: Setting Up the Project

Go to File > New and choose "ActionScript 3.0 Document".


Give the Flash document the following properties.

  • Stage Color: White
  • Size: 600x600px

Save this document as "PhotoMatch.fla".

Go to File > New and choose "ActionScript File". Save this as "Main.as" in the same folder that you saved the "PhotoMatch.fla" in.

Next we need to set the Document Class. Set the Document Class to "Main".



Step 5: Setting Up "Main.as"

Inside "Main.as" add the following code:

Here we opened the package, imported the classes we will need for the first part of this tutorial, delclared our Main class to extend Movie Clip, and set up our constructor function and closed out the package


Step 6: Using the Flickr API to Retrieve a List of Images

Now that we have our flash project set up we are ready to get a list of Image URLS from Flickr.

Unfortunately, Flash at this moment does not have any built in capability to parse JSON files. It has been anounced however, that the newest version of the Flash Player will support JSON files natively as mentioned by Joseph Labrecque in his Industry News: Week 20 2011 post on ActiveTuts+.

To get around this limitation, we will be using Abode's as3CoreLib hosted by Mike Chambers. So grab a copy on GitHub. Once you get a copy of the as3CoreLib, extract it to a convenient place on your hard drive. Inside the extracted folder, inside the "src" folder is a "com" folder. Copy this "com" folder into the same directory you saved the PhotoMatch.fla.

Now we are ready to parse some JSON files.

Underneath the line public class Main extends MovieClip add the following.

Be sure to replace "YOUR API KEY" with the API KEY you recieved from Flickr in the steps above.

Underneath the Main() constructor in "Main.as" add the following code.

Here we set up our searchURL to point to the flickr.photos.search method of the flickr api. This is how you will send any requests to flickr, after the "?" you put whatever method you are interested in, here we are searching for photos.

Next we append the arguments onto the searchURL. Below are the options with an explanation of each

  • api_key: "This is the API Key Flickr issued to you for your app".
  • tags: "This is the tags you want to search for, you can specify multiple tags by seperating them with a comma".
  • per_page: "This is how many photos you want returned at once, we are getting 10 for now".
  • format: "This is the format you want the results returned in "Can be JSON or XML".
  • license: "This is the types of licenses you wish the photos to have. Because the photos have different licenses you need to make sure you app complys with the licenses of the photos. More info is below".
  • nojsoncallback: "The Flickr API will return a callback function for javascript users. Since we are not using javascript we set it to 1 (which means no callback is provided)".

Again for reference here is the documentation to the flickr.photos.search method so you can cross reference the arguments we have used

As mentioned the photos have a certain license attached to them, below are the licenses along with a link for futher explanation.

For the purpose of this tutorial we are allowing images with license IDs of 5 and 7. It's important only to use images that we are allowed to.

Next we set up a URLRequest , a URLLoader, add an EventListener to the URLLoader, and finally load the request.


Step 7: Coding the completeHandler

Here we code the completeHandler() method that we added to the URLLoader in the step above. Add the following to "Main.as" just below the doRequest() function you created above.

Here we set up a URLLoader, put the data from the Loader into the rawString variable, and use the "JSON" class we imported to decode the JSON into an Object.

Next we use a for each loop to loop through the object.

On each iteration of the loop we set up an imageURL variable, push the imageURL into the imageURLArray, and also push the photo.id from the current photo. We will need a pointer to the photo.id later in the tutorial when we get information for a single photo.

Add the following within the Main() constructor function:

You can now test the Movie and you should see the 10 imageURLs traced to the output panel.

Be sure to check the download files for the code for this step.


Step 8: Creating the shuffleCards() function

To make this game useful we will need to be able to shuffle our cards. For now we are just going to shuffle the URLs, when we get to loading the actual images/cards we will update this function to shuffle cards instead.

Add the following to "Main.as" underneath the completeHandler function

Here we setup our shuffle function to take an Array as a parameter. Next we choose a random element from the Array, and set the temp variable equal to the Arrays current index.

Then we swap out the current index of the Array with the random Array index we chose, and swap the random Array index with our temp Array index Remove the trace(imageURL) line from within the completeHandler() function. Then in the same function underneath the for each loop add the following.

If you test the movie now you should see the imageURLs before we shuffle them, and after they have been shuffled.

Be sure to check the download files for the complete code for this step.


Step 9: Putting the Images on the Stage

Now that we have a shuffle function, lets get the images onto the stage.

Add the following to the variables section above public function Main().

We also need to add a new import because we are using a Loader, so add the following to your imports.

The reason we have a separate array (cardImages) from imageURLArray is because the imageURLArray will hold all of the images we load for the game (up to 300) at one time. Since our game only uses 10 images at a time we need a seperate array for just those 10 images.

The cardArray is used to hold our cards. For now it just holds UILoaders but once we make an actual card class we will change this to hold "Cards".

The numCardsLoaded is used to keep track of how many Cards have been loaded.

The xPos and yPos variables are used to position our cards on the stage. These are used in our postion cards function which is coming up shortly.

Add the following after the shuffleCards function

The loadCards() function first resets the cardImages Array and cardArray Vector, then we splice the first 10 elements of imageURLArray into the cardImages Array. Remember the game will only use 10 images at any time, but imageURLArray will eventually hold up to 300 elements.

Next we loop through the cardImages Array and setup a URLLoader,tell the URLLoader to load the URL, and add an Event.COMPLETE listener to the URLLoader.

We then run a for loop, which runs twice for each element in the cardImages Array. We create card as an UILoader, set it's source, and finally push it into the card Array. Essentially this just makes 2 copies of a "Card".

The positionCards() function is where we will positions our cards on stage, this function is next.

Add the following below the loadCards function.

Here we increment the numCardsLoaded, and if it equals 10 we shuffle the cards within the cardArray, loop through the cardArray creating a "Card", set the position of the Card, and finally add the Card to the Stage. We subtract 37.5 from the UILoaders .x and .y because we want the "registration" point in the center of the UILoader. When we build our "Card" class we will set up the UILoaders this way.

Before we can test this we need to update the shuffle function to take an Vector, since the cardArray is a Vector and not an Array.

Change the shuffleCards() to the following.

Remove the following from within the completeHandler function

Finally we can test our Movie and see the URLLoaders randomly arranged on the stage. This is starting to look like a game now:

Be sure to check the download files for the complete code up to this step.


Step 10: Checking for Card Matches

Now that we have our "Cards" shuffled and arranged on stage, we will check to see if they "Match" when clicked on. Add the following to the bottom of your variable declarations.

The chosenCards Vector will hold the cards the user clicks on. Since we only want two cards chosen at any one time we give the Vector a length of 2.

Add the following below the positionCards() function.

This function will soon be used to flip our Cards. But for now we just use it to handle our chosenCards Vector.

The first thing we do is check if the chosenCards.length is equal to two, and if it is we reset the chosenCards to a new Vector. Next we check if chosenCards does not already contain the "Card"; if it does not then we push the Card into chosenCards and remove the EventListener for the card. Last we check if chosenCards length is equal to 2 and if it is we call removeListeners() which removes the EventListeners from all the cards, finally we call the checkForMatch() method which is coming up shortly.

Add the following inside the positionCards(). The difference is highlighted.

What we do here is add an EventListener that will call the checkForMatch() function when the user clicks on one of the cards. This function is below.

Add the following to "Main.as" underneath the positionCards function.

The first thing we do is check if chosenCards length is equal to 2; if it is we check if the first "Card" in the chosenCards is the same as the second "Card", if it is we remove the EventListeners from them, splice them out of the cardArray, remove them from the stage and add the EventListeners back to the remaining cards.

We then check if cardArray.length is equal to 0 and if it is we simply trace "GAME OVER!!", finally we add the EventListeners back to all the cards whether there was a match or not.

Below are the methods removeListeners and addListeners. In these two methods we simply add or remove the EventListeners to the "Cards" within the cardArray.

Add these two methods underneath the checkForMatch() method.

Be sure to check the download files for the complete source code up to this step.


Step 11: Doing a Custom Search

Now that we have our cards laid out on the stage, and we are able to check for matches, let's set the game up to do a custom search.

Select the text tool and drag out a TextField onto the stage.You will want to position it toward the top of the stage so it does not interfere with the images.


Give the TextField the instance name "searchText" and make sure the the type is set to "Classic Text" and "Input Text" respectively. Also make sure you select "Show border around text" so you can actually see the TextField. This is a temporary TextField just so we can test a custom search. We will be building a "SearchPanel" class shortly that contains a TextField and a Button.



We need to be able to press the "Enter" key to do the search, so replace the doRequest(null) with the following code inside the Main() constructor function

Here we added an ADDED_TO_STAGE Event Listener. This get called when the movie is fully loaded and the "Stage" is ready.

Next up we need to code the addedToStage method. Add the following code directly under the Main() constructor function.

Here we add an KeyboardEvent.KEY_DOWN listener. The keyDownHandler function is where we will handle the pressing of the "Enter" key. This function is up next.

Add the following code directly underneath the addedToStage method.

Here we test if the player pressed Enter; if they did then we call the doRequest() function.

Since we are using the "KeyBoard" Class we will need to import that class.

Add the following to the bottom of your import statements:

Now we need to change the doRequest function to handle the text from our searchText TextField so change the following in the doRequest() function

You can now test the Movie and enter your own search text such as "Flower". Give it a try!You will have to wait a brief second before the images pop up, so be patient.

Be sure to check the download files for the complete source code up to this step


Step 12: Creating the Game Button

Now that we can do a custom search, we will create the "GameButton" class that is used throughout the game. Then we will create a search panel that holds the search TextField and the "Search" button.

Go to Insert > New Symbol or alternatively press Ctrl+F8. Give it the name "Game Button" and check "Export for Actionscript" and make sure Class is set to "GameButton".


Select the rectangle tool and under "Fill And Stroke" make sure the stroke is not set and give the fill the color "#F26AF2". Next under "Rectangle Options" set the corner radius to 15.

Now drag a rectangle out inside the new MovieClip. Once dragged out, click on it to select it and set the following properties under "Position And Size"

  • X: 0.00
  • Y: 0.00
  • W: 150.00
  • H: 32.00



Next select the text tool and drag out a TextField on top of the Rounded Rectangle you just created. Make sure to give the TextField the color White.

Make sure the TextField is selected and give it the instance name "button_txt" and make sure the pulldowns are set to "Classic Text" and "Dynamic Text" respectively.


Next set the following properties under "Position And Size".

  • X: 14.00
  • Y: 4.00
  • W: 128.00
  • H: 23.00

You can now exit this MovieClip.

Next we need to create the class for this MovieClip. Go to File > New and choose "ActionScript File"


Save this file as "GameButton.as". Now add the following code to this file.

Here we set up our "GameButton" class to extend MovieClip. Inside our constructor function we set buttonMode to true, and set mouseChildren to false.

Setting buttonMode to true makes the hand pointer show when the MovieClip is moused over. And by setting mouseChildren to false we cause any nested MovieClips within this class to not recieve Mouse Events. While I was testing the TextField was selectable (even though I had chosen not selectable in the "CHARACTER" panel); by setting mouseChildren to false I was able to make the TextField non-selectable.

Next we create a setText(theText:String) method.

This function takes a String as its argument, then simply sets the button_txt TextField's text to the String we passed in.


Step 13: Creating the Search Panel

Now that we have our GameButton ready we can create the SearchPanel and respective class.

Go to Insert > New Symbol or alternatively press Ctrl+F8. Give it the name "SearchPanel" and check "Export for Actionscript" and make sure Class is set to "SearchPanel".

Select the Text Tool and drag out a TextField into this MovieClip. Give it the instance name "searchTxt". Under the "CHARACTER" panel give the TextField the color "#F26AF2".


Next set the following properties on the TextField

  • X: -130.00
  • Y: -12.00
  • W: 261.00
  • H: 23.00

Now go to the library and drag an instance of the GameButton into this MovieClip, give it the instance name "searchBtn" and set the following properties on it.

  • X: 147.00
  • Y: -16.00
  • W: 150.00(Default Size)
  • H: 32.00(Default Size)

You can now exit this MovieClip

Now we are ready to write the class for the SearchPanel. Go to File > New and choose "ActionScript File"


Save this file as "SearchPanel.as" and enter the following code

Here we set up our SearchPanel to extend MovieClip and set up three methods within the class. The clearText() function simply clears the TextField by setting it to an empty String.

The setButtonText(theText:String) takes a String as an argument and sets the searchButtons text to the String that was passed in.

The getText() returns whatever was entered into the TextField.


Step 14: Testing the Search Panel

Now that we have a functional Search Panel we can add it to our game and give it a quick test.

If you have not done so, delete the previous TextField we were using from the Stage.

Add the following variable at the bottom of the current variables.

This is simply a variable for our searchPanel that the game will use. Now we need a way to add the searchPanel to the stage, this function is next.

Add the following to the "Main.as" underneath the keyDownHandler() function.

Here we set the searchPanel's .x and .y properties and add it to the Stage. Then we set the button's text and add an EventListener that will call our doRequest method.

Now we need to clean up the code from the previous Step where we were using a single TextField to do the search.

We are first going to make sure the Search Panel TextField is not empty. Then we change where we were just grabbing the ".text" property of the TextField to use the getText() method of the SearchPanel class.

The updated code for the doRequest method is below

Before we can test the Movie we need to add the Search Panel to the stage. Add the following function above the keyDownHandler() you created in the steps above

This method will be used to set up our game elements. For now we are using it to add the Search Panel.

Finally within the addedToStage() function add the setupGameElements() method.

You can now test the Movie and enter a search into the Search Panel.


Step 15: Creating the Card Class

Next up we will create the "Card" Class. We will use a UILoader within this class to hold the images we get from Flickr. Our card class is going to be utilizing TweenLite, so if you don't have a copy go grab one from GreenSock.com. You will want to put the greensock folder into the same "com" folder that you created in Step 7.

Now we are ready to write the class for the SearchPanel. Go to File > New and choose "ActionScript File".


Save this file as "Card.as" and enter the following code.

Here we open our package, import the classes we will need for this class, set up some variables we will need and code our constructor function

Now add the following inside the constructor function.

Here we create a new UILoader and set its .x, .y, width, and height properties. Then we add it to the stage. Now add the following code below the Card() constructor function.

The setURL(theURL:*) function is set up to take any data type as denoted by the *.Then we set the source of the loader to what was passed in. The reason I used a * here is because we will set the source of the UILoader to a MovieClip when we show the Flickr Logo Image (the card Front),and it will be set to a String when we show the actual images.

Add the following code below the setURL() method.

This is the code we use to flip our cards. If the cardFace is equal to "front" we flip the images to the left by changing the rotationY property from 0 to 180. We also call an onUpdate function that runs continuously while the image is being animated, and an onComplete function that runs when the animation is complete.

We similarly use TweenLite again to rotate our images rotationY from 180 to 0 if it is not on the "front" of the Card and call the onUpdate and onComplete functions.

Now add the following code below the flip() function.

This function is called continuously while the image is animating. We first check to see whether the images rotationY is >=90. If it is, we check to see if imageSetInTween is equal to false. If it is we use the setURL function to set the UILoader's source equal to imageURL, (which will be a URL to an image on Flickr), set the Cards scaleX to -1 ,and finally set the imageSetInTween to true.

The reason we set the scaleX to -1, is because when we flip the images they appeared mirrored. (Text would read from right to left).

The imageSetInTween needs some explanation. When I was creating the Card Class I was getting a "blank" image in the UILoader meaning the image would not show. After awhile of debugging I realized that it was repeatedly setting the image and it would appear that there was no image showing. I think this has to do with the UILoader repeatedly "unloading" and "reloading" the image creating a blank effect. So I set up this variable so it would only load it one time.

Next we check whether the rotationY of the card is <= 90. If it is we reset the imageSetInTween to false, set the scaleX back to 1, and set the image back to the cardFront.

Add the following code beneath the setImage() method.

These two functions are called when the animation completes. We simply set cardFace to "front" or "back".

We use dispatchEvent() in the setCardFaceBack() function to dispatch a new Event called "finished".We will use this event in our Main Class to alert us when the card is finished animating.

Add the following code beneath the two functions above.

The remove() function will be used to tween the Cards height to zero, while also decreasing it's alpha. We call this function in our Main Class when we want to remove a card from the stage. When the tween is complete we call removeFromStage() which removes the Card from the stage. We call parent.removeChild() which would be the main movie/stage.

Next add the following code below the removeFromStage() function.

These are some simple getter and setter functions that get and set our variables because we made them private.

The imageURL will be a URL to the image on flickr. The userName will be the owner of the photo on flickr.

The photoURL will be the URL to the actual user and photoPage on Flickr; this is different from the imageURL which is just the photo itself.

This completes our "Card" class. Next up we will change our game to use cards instead of individual image loaders.


Step 16: Using the Card Class

Now that we've got our Card Class Ready we need to update our code to use our Cards instead of individual UILoaders. Back in "Main.as" change the cardArray Vector to hold Cards now instead of UILoaders.

Next we need to update our chosenCards Vector to hold Cards as well.

Next up is changing our shuffle() function to take Cards instead of Vectors. This is a small change all we need to change is the parameter type from UILoader to Card and change the temp variable to be typed as an Card instead of an UILoader. Go ahead and make those changes.

Next up in the list of changes is the loadCards().Within the loadCards change the cardArray to equal a new Vector of Cards instead of UILoaders.

Instead of creating a new Card as an UILoader we will create it as a card and use the setURL and setImageURL. methods of our Card class. Change the following within the loadCards() function.

In the library I have provided a Movie Clip to be used as the front of the Card. Since we want our Cards starting out with the Flickr logo showing, we use setURL to set the cards "front". Then we use setImageURL so we have a reference to the image for this particular card.

Thats is all the changes we need to make in the loadCards() function for now. Next up is changing the positionCards function.

The only change we need to make is where we create the tempCard instead of typing it as an UILoader we need to type it as as a Card make that change now.

Next up in our changes is the doFlip() function. The first thing we need to do is tell the card to flip by using the cards flip() method. Next we need to change where we create a new chosenCards Vector. Currently we are using UILoader for the type. We need to change it to Card.

We will also need to change where we are pushing our Cards into the chosenCards Vector. Change it to from UILoader to Card as well.

Last, where we are checking if chosenCards length is equal to 2 we remove checkForMatch(null) and replace it with our custom EventListener we made in the card class.

The EventListener "finished" gets called when the card finishes the animation. Since we only want to call checkForMatch after the second card finished its animation we add the EventListener to the second card.

Last up in our changes is the checkForMatch() function. The first thing we do is remove the "finished" EventListener we just added to the Card in the Step NaNabove. Next, the code where we check if chosenCards[0].source == chosenCards[1].source can now be changed to use our getImageURL() function. We also use our remove() method instead of calling removeChild() directly. Last if the cards do not match, we want to flip them back over, so we tell them both to flip again.

You can now test the movie. You should have a playable game with the cards doing flipping animations.

That's it for this part of the tutorial! In the next part, we'll add multiple levels and vastly improve the interface. Hope you've enjoyed it so far!

Advertisement