HomeFlash Page 7 - Building Data-Driven Flash Movies
Splitting Up - Flash
Contrary to what you might think, Flash isn't just all tweensand motion blurs. The application comes with powerful data-retrievalcapabilities, which allow you to hook your Flash movie clips up to adatabase (or any other external data source) and dynamically build movieclips that are easy to update and modify. Find out more, in this roughguide to the data-driven Flash universe.
At this point, your Library should contain three symbols - "text" (the label), "circle" (the button) and "item" (the container for both).
Drag and drop an instance of the "item" symbol onto the Stage.
Use the Modify -> Instance command to give this instance a name - I called mine "itemInstance". This name will be used to reference the instance when creating copies of it via the duplicateMovieClip() function.
Right-click the first frame (this should be a keyframe), and add some ActionScript to it.
This will first make the instance invisible, and then load
the variables found at the URL "menu.php". Let's look at that script next:
// menu.php
// open connection to database
$connection = mysql_connect("localhost", "root", "secret") or die
("Unable to connect!");
mysql_select_db("menu") or die ("Unable to select database!");
// formulate and execute query
$query = "SELECT link, label FROM menu";
$result = mysql_query($query) or die("Error in query: " .
mysql_error());
if (mysql_num_rows($result) > 0)
{
// iterate through rows
while($row = mysql_fetch_object($result))
{
// build label string
$labelStr .= $row->label . "|";
// build link string
$linkStr .= $row->link . "|";
}
// print output as form-encoded data
echo "items=" . urlencode($labelStr) . "&urls=" .
urlencode($linkStr);
}
// close connection
mysql_close($connection);
?>
This script does the hard work of connecting to the database,
extracting the menu items and their corresponding links, and creating a URL-encoded string that Flash can use.
It's important to note, at this point, the format in which the data is output. All the menu labels are compressed into a single string, separated by a pipe, and assigned to the variable "items", while all the corresponding URLs are similarly concatenated and assigned to the variable "urls".
Here's an example of what the output of this script might look like:
All that's remaining is to write the ActionScript code that
reads these variables, parses them and uses them to create multiple instances of the "item" symbol. Right-click the "item" variable, pop open the Actions panel, and add the following code to it:
onClipEvent(data)
{
// split variables into array
items = items.split("|");
urls = urls.split("|");
// get position of template movie clip
yPos = getProperty("itemInstance", _y);
// iterate over array elements
for (i=0; i<(items.length-1); i++)
{
// clone movie clip and name it
duplicateMovieClip ("itemInstance", "itemInstance"+i, i);
// set position
setProperty ("itemInstance"+i, _y, yPos+i*50);
// set variables
set ("itemInstance"+i+".label", items[i]);
set ("itemInstance"+i+".url", urls[i]);
}
}
The onClipEvent(data) event handler is triggered whenever the
Flash movie completes loading the variables imported via loadVariables(). This is necessary because Flash loads variables asynchronously, which means that it doesn't wait for the variables to be fully loaded before proceeding to the next statement of the script.
By wrapping the code in an onClipEvent() handler, I'm ensuring that the it's executed only after the variables have finished loading. This doesn't always work as advertised, though - keep reading for a couple of caveats to this technique.
Once the variables have been loaded, the split() function is used to break the concatenated label and link strings into their constituent parts,
items = items.split("|");
urls = urls.split("|");
and a "for" loop is used to iterate over the resulting
arrays.
This "for" loop does a number of important things. First, it creates a duplicate of the "itemInstance" movie clip, and gives it a unique name by suffixing the array index to the name.
Next, it sets the vertical position of the newly-created
movie clip, via the instance's "_y" property. This position is calculated via a simple algorithm, which allows each additional instance to be placed below the previous one.
setProperty ("itemInstance"+i, _y, yPos+i*50);
Finally, the movie clip's "label" and "url" values are set
using the set() function; these values are used within the "text" and "circle" symbols respectively (you remember I mentioned these on the previous page).
set ("itemInstance"+i+".label", items[i]);
set ("itemInstance"+i+".url", urls[i]);
These two lines of code set the newly-created menu item's
label and target URL respectively.
All that's left is to test the movie. If all has gone well, this is what you should see:
It should be noted at this point that I sometimes encountered problems while using the onClipEvent(data) event. In case you find that your Flash movie isn't loading the variables correctly, you might want to consider removing the
onClipEvent(data)
{
// code
}
handler from the movie clip instance, and instead add a new
keyframe (maybe around frame 3?) containing the following code:
// split variables into array
items = items.split("|");
urls = urls.split("|");
// get position of template movie clip
yPos = getProperty("itemInstance", _y);
// iterate over array elements
for (i=0; i<(items.length-1); i++)
{
// clone movie clip and name it
duplicateMovieClip ("itemInstance", "itemInstance"+i, i);
// set position
setProperty ("itemInstance"+i, _y, yPos+i*50);
// set variables
set ("itemInstance"+i+".label", items[i]);
set ("itemInstance"+i+".url", urls[i]);
}
This forces Flash to run the
split-into-array-and-create-duplicate-instances code whenever the movie plays, instead of waiting for the event handler to be triggered. It's a somewhat brute-force solution to the problem - the first option is far safer, not to mention also being the one Macromedia recommends - which is why you should only use it if you find yourself in dire straits.