Reading+Files

This is an optional lesson - for those of you writing games which have a lot of things in them. While it is possible to hard-code in the location of every item in your code, this can be a bit of a pain in the neck, and it's not very flexible. You might consider creating a file that has information about the starting locations of things in your game which can then be read by the game itself. This way, you can keep the data separate from the code, and you can edit the data freely.

In this example, I am going to show you how you might set up a platformer's platforms and ladders using an external file. Imagine that you have a flash file that has a main movie class and two movie clips, bricks and ladders - each brick and ladder movie clip is 20x20 pixels. It is conceivable that you could write code in your constructor that says: code format="actionscript3" var brick1:Brick = new Brick; brick1.x = 100; brick1.y = 100; myTileArray.push(brick1); addChild(brick1); var brick2:Brick = new Brick; brick2.x = 120; brick2.y = 100; etc.... code But this is a bit of a pain. (And imagine if you had a second level that looked different!) One solution is to use an XML file. This used to be a big pain in the neck in ActionScript 2, but is much, much easier now!

**Making an XML file** What I would like to suggest is that you create an external file in  format that will contain the information about what sorts of tiles (brick or ladder) you want and where they will go. Then, you can create a routine (or two) in Actionscript to load that file and put all those tiles at the appropriate locations on the screen and into myTileArray. Here is what the file might look like. See whether you can understand what it is saying. (For those of you who have taken HTML, I think this will make a lot of sense!) code format="xml"  brick 100 100 brick 120 100 ladder 120 80 ladder 120 60</y> brick 100</x> 60</y> brick 140</x> 60</y> </tileList> code As you can see, this is just like HTML, but we get to choose what we name the tags, so that there is meaning to them. I hope that you can see that this will create 4 brick tiles and 2 ladder tiles on the screen.

In a moment, we will write the code in Actionscript to read this file (which we might call (tileDemo.xml"). But first, a few notes on the XML...

The tags MUST be balanced correctly. Every opening tag (e.g. " ") must have a corresponding closing tag (e.g. " "). The indentation of lines does not matter to the computer, but is a very good idea for the human. The tags are case-sensitive. I recommend that you use all lower case. Again, you can use whatever tag names you like, but no spaces or numbers. Yes, you could nest the tags even deeper if you wish. Before you write one of these for yourself, make sure you read the rest of this page. You might also wish to talk with Mr. Howe about the setup of an XML file before you put a ton of data in.

**How the computer uses XML data** In the XML file above, you will note that there is exactly one pair of <tileList>...</tileList> tags, which contain all the other code. You must have one outer set of tags for the file to work. Contained within these <tileList> tags are a series of ... tags (all the other stuff is contained within them). We say that the tags are the **children** of the tags. In turn the, , and  tags are the children of the tags. (Which means that they are the 3rd cousins of the <tileList> tags.)

In Actionscript, we can use a type of variable called an "XML" to store the information contained in the XML document. code format="actionscript3" var tileList:XML; code We will save the process of getting that information into this "tileList" variable for later. For now, we will skip these details and just presume that the information gets stored in the "tileList" variable...somehow. (If you can't wait, skip down to the next horizontal separator.)

When we load up the XML file, we might access the type of the first tile as the following: code format="actionscript3" trace(tileList.tile[0].type); code This would start with the tileList, find the first (item #0) tile tag, and look inside of that for the "type" data. Likewise to find the coordinates of the second tile, we could say something like: code format="actionscript3" secondTileMC.x = parseInt(tileList.tile[1].x); secondTileMC.y = parseInt(tileList.tile[1].y); code (Note we are using the parseInt function to convert the strings in the XML file into numbers.) If we wish to use the array of tags, we can do so with the following syntax: code format="actionscript3" var aTileTag:XML; for each (aTileTag in tileList.child("*")) {   // do something with aTileTag - it will be each one of the tiles, one at a time. } code The .child("*") suffix lets us treat the tileList as an array of smaller XML variables. Naturally, you can use whatever tag names you like -- and this process is very adaptable.

**Reading an XML file into Flash** So, how do we get flash to read in this information? First we have to tell the computer to ask for the file, and then we set up an event so that when the information arrives, we can open up the XML variable and get the stuff from it.

Here's the first part: code format="actionscript3" import flash.display.*; import flash.events.*; import flash.net.URLLoader; import flash.net.URLRequest;

public class tileDemoLoader extends MovieClip {       private var myTiles:Array;

public function tileDemoLoader {           myTiles = new Array; importTileData; }

public function importTileData {           var xmlLoader:URLLoader = new URLLoader(new URLRequest("tileDemo.xml")); xmlLoader.addEventListener(Event.COMPLETE, manageXMLimport);

} code Note that we have a few new things to import. The constructor is calling the function importTileData. This creates a new thing called a URLLoader - which is the thing to load in the file - in this case, "tileDemo.xml." In the next line, we tell the loader that when the data is all read in, it should call the "manageXMLimport" function. (That is what we will do next.) As far as I am concerned, you can just copy and paste this stuff and modify it to open your file.

Next we write the manageXMLImport function, which will receive the "event" about the data. Unlike many of the other events we have received, though, we will definitely make use of the "evt" variable that is being passed along - it holds the content of the file! code format="actionscript3" public function manageXMLimport(evt:Event) {           var tileList:XML = XML(evt.target.data); trace(tileList); // you will see that it loaded in....

for each (var tileData:XML in tileList.child("*")) {               var nextTile:MovieClip; if (tileData.type == "brick") {                   nextTile = new Brick; }               else if (tileData.type == "ladder") {                   nextTile = new Ladder; }               else {                   //trace("bad tile: "+xData.tile[i]); trace("bad tile: "+tileData); continue; }               nextTile.x = parseInt(tileData.x); nextTile.y = parseInt(tileData.y); stage.addChild(nextTile); myTiles.push(nextTile); }       } code In the first line, we are transferring the data from the "evt" parameter into the "tileList" XML variable. We then are (optionally) printing it out so we can check that we read the file correctly.

We then do a loop through each of the items in the tileList. Each time through the list, "tileData" gets filled with the sub-XML values associated with the next tag, as if it was a little XML files of its own.

We create a new variable called nextTile. Depending on the of the, we either fill this in with a Brick or a Ladder movieclip. (Or nothing, if there was an error. - The "continue" statement skips over the rest of the commands in the loop and goes to the next item on the list, if there is one.)

Then we place the tile at the  and  locations, add the item to the stage, and then push them onto an Array of tiles. It does this for each ... found in the <tileList>...</tileList> tag.

**But why do all of this?** At first blush, this might look like a lot more work than just hard-coding the instructions for loading in the graphics in your game. And, in fact, it might be if you don't have much data. However, once you start to have a lot of things to keep track of, it is much easier to use, and it keeps your data very organized.

Consider: If you are making a multilevel game, you could put a ... tag between the pair and the pair, that way you could have a set of tags for each. This would require a small modification of the reading code we described.

Keeping the data in a separate file means that your .as file will be shorter, so it will be easier to find things in it.

If you have a text editor, you can edit the xml file even if you don't have Flash handy.