Embedding XML in AS3
I thought I'd write a bit of a technical post for a change, explaining how to embed XML files in a SWF from FlashDevelop. Coincidentally, I used XML to store the layout of MoneySeize's stages, so the example will specifically be geared toward XML representing platformer stages.
Now then, here's an example of an XML stage file from MoneySeize. It's actually just a snippet of a stage file, not a full one:
The XML is pretty self-explanatory. As you can see, the stage contains an objects tag, which contains a list of every game object on the stage. Objects include blocks, coins, "tutorials", "jumpthrus" (one-way blocks), etc. Each object tag includes its x and y positions (divided by 16, because the game is grid-based) and any other applicable attributes (for example the CHEST tag contains a COINS attribute to indicate the amount of coins in the chest).
Of course, designing levels by typing raw XML into a text file isn't very intuitive, so it's nice to have an editor.
So now that we have the XML, our goal is to embed it in our SWF. Then, at some point as the game is running, we will load and parse it to build the level it represents. Here's the code I used to embed the XML:
The "application/octet-stream" MIME type allows us to embed any asset as a byte stream. The last step is to load the XML into memory and parse it:
Here we load the level as a ByteArray, then convert it to a string. This string is the raw XML of the file in string format, which we can use to create an XML object. Now we use the interface of the XML object to parse the level data:
For MoneySeize, it is known that each level file only has one OBJECTS tag, so we can simply access xml.OBJECTS[0] to find all the game objects. xml.OBJECT[0].BLOCK is another XML object: it contains every BLOCK tag within the OBJECTS tag. We simply traverse every tag in the object, adding a block object to the level for every BLOCK tag.
Note that the @ symbol is used to access the attributes within a tag.
Now then, here's an example of an XML stage file from MoneySeize. It's actually just a snippet of a stage file, not a full one:
< STAGE>
< OBJECTS>
< BLOCK X="2" Y="23" WIDTH="36" HEIGHT="4" />
< SPAWN X="6" Y="22" />
< BLOCK X="12" Y="21" WIDTH="4" HEIGHT="2" />
< TUTORIAL X="18" Y="16" TEXT="..." />
< TUTORIAL X="28" Y="22" TEXT="..." />
< BLOCK X="36" Y="2" WIDTH="2" HEIGHT="16" />
< JUMPTHRU X="32" Y="9" WIDTH="4" />
< BLOCK X="27" Y="9" WIDTH="5" HEIGHT="2" />
< COIN X="28" Y="7" />
< COIN X="30" Y="7" />
< COIN X="32" Y="7" />
< COIN X="34" Y="7" />
< BLOCK X="17" Y="8" WIDTH="5" HEIGHT="2" />
< BLOCK X="2" Y="9" WIDTH="10" HEIGHT="2" />
< CHEST X="19" Y="7" COINS="5" />
< DOOR X="5" Y="8" />
< BLOCK X="37" Y="20" WIDTH="2" HEIGHT="3" />
< BLOCK X="1" Y="5" WIDTH="3" HEIGHT="4" />
< BIRD_GOLD X="2" Y="4" COINS="3" TIME="5" />
</ OBJECTS>
</ STAGE>
The XML is pretty self-explanatory. As you can see, the stage contains an objects tag, which contains a list of every game object on the stage. Objects include blocks, coins, "tutorials", "jumpthrus" (one-way blocks), etc. Each object tag includes its x and y positions (divided by 16, because the game is grid-based) and any other applicable attributes (for example the CHEST tag contains a COINS attribute to indicate the amount of coins in the chest).
Of course, designing levels by typing raw XML into a text file isn't very intuitive, so it's nice to have an editor.
So now that we have the XML, our goal is to embed it in our SWF. Then, at some point as the game is running, we will load and parse it to build the level it represents. Here's the code I used to embed the XML:
public class Levels
{
[Embed(source='../../../assets/levels/Level1.xml',
mimeType="application/octet-stream")]
public static const Level1:Class;
}
The "application/octet-stream" MIME type allows us to embed any asset as a byte stream. The last step is to load the XML into memory and parse it:
var file:ByteArray = new Levels.Level1;
var str:String = file.readUTFBytes( file.length );
var xml:XML = new XML( str );
Here we load the level as a ByteArray, then convert it to a string. This string is the raw XML of the file in string format, which we can use to create an XML object. Now we use the interface of the XML object to parse the level data:
var o:XML;
for each (o in xml.OBJECTS[0].BLOCK)
{
addChild( new Block( o.@X, o.@Y, o.@WIDTH, o.@HEIGHT ) );
}
For MoneySeize, it is known that each level file only has one OBJECTS tag, so we can simply access xml.OBJECTS[0] to find all the game objects. xml.OBJECT[0].BLOCK is another XML object: it contains every BLOCK tag within the OBJECTS tag. We simply traverse every tag in the object, adding a block object to the level for every BLOCK tag.
Note that the @ symbol is used to access the attributes within a tag.
Labels: devlog, MoneySeize




