Using PHPObject to Save and Retrieve Simple Game Levels
[ May 27, 2004 ] by Tor de Vries
Using a simple video game level editor in Flash as a foundation, this whitepaper/tutorial explains how to use ActionScript, PHP, and the PHPObject "Flash remoting" libraries to save and retrieve data to/from a server in XML format.


How Leditor Works

The Logic of Leditor

Leditor relies on the ActionScript of "leditor.fla" (in the first frame) and the PHP in "Leditor.php". ActionScript hands off to PHP, which hands back, and on and on. Dissecting these files will reveal the symbiosis between them. You should look at the code as you read these notes.

However, before we get into the code, let's review the editor itself. There are seven possible tile shapes in this game editor:

Respectively, these are: a blank tile, representing open space; a blue rectangle tile, perhaps representing a diamond; a yellow circle tile, perhaps representing a coin; a dark purple star tile, perhaps representing an explosive mine or monster; a red brick wall and a yellow brick wall, representing walls that cannot be walked through; and finally a silver ball, representing the player.

The level editor provides a grid of tiles, 20 on each side, for a total of 400 tiles. After choosing a shape from the toolbox on the left, you can click on individual tiles to change them to that shape. All of the shapes are individually contained in frames 1 through 7 of the "tile" movie clip. Thus, to change a tile's shape, the ActionScript simply tells it to go to another frame; for example, to change a tile to a red brick wall, the tile's movie clip is told to go to frame 5. You could end up with a level like the one in sample_level.xml:

The level editor allows you to save levels. It does this by scanning through every tile movie clip in the grid, recording its current frame, and saving this information to a two-dimensional array. This array is then passed to the server via PHPObject, where PHP saves it as an XML file.

The level editor also allows you to open or delete previously-saved levels. PHP code on the server reads the list of available XML files and passes this information to Flash via an array. Flash then updates its file list. To open a file, Flash uses standard ActionScript XML loading functions; to delete a file, Flash uses PHPObject again.


Analyzing the PHP

The PHP file "Leditor.php" contains one main thing: a PHP class called "Leditor". This class name must match the file name, and both of these must match the ActionScript reference that creates the PHPObject (see below). Within this class are five functions.

The first two functions in Leditor.php are Leditor() and init(). The former simply contains a reference to the latter, and the latter contains any initialization functions. For this application, no PHP-related initialization is used. Other applications might verify database connections or security authorizations at this point. (These are required functions for every PHPObject, and the first function must match the name of the PHP class.)

The third PHP function is levelSave(), which takes two arguments: the string $filename and the two-dimensional array $gameArray, which contains the level's tile information. The function iterates through the array, building a long string of XML tags into the internal variable $saveVal. Then, it makes sure $filename has an ".xml" suffix, and saves the string into a file with that name (overwriting any existing data). Once completed, PHPObject notifies the Flash function myLeditor.levelSave_onResult(), which updates the interface accordingly.

The fourth PHP function is levelListing(), which takes no arguments. It simply opens the local directory, reads in each file name, and adds it to the Leditor array $this->localFiles if its file suffix is "xml". Then it closes the directory and sorts the array. Once completed, PHPObject notifies the Flash function myLeditor.levelListing_onResult(), which accesses this array via myLeditor.localFiles and fills the file list box with the array's contents.

The fifth PHP function is levelDelete(), which takes one argument: the string $filename. If the suffix of $filename is "xml", then the function deletes it. Once completed, PHPObject notifies the Flash function myLeditor.levelDelete_onResult(), which in turn calls the PHP function levelListing() to refresh the file list, as above.


Analyzing the ActionScript

The ActionScript code is marked off into different sections with lines of commented asterisks and appropriate labels. We'll follow that organization in this discussion.

Initialization and declarations

The first section of ActionScript begins with this command:

// ActionScript
#include "PHPObject.as"

This tells Flash to utilize the PHPObject libraries that you installed via the Extensions Manager. Without this, none of the PHPObject features will work. The rest of the commands in this section set up two new objects, level and tool, with various properties about the drawing grid and the drawing tool selections. The maximum number of level files is set in fileMaxQuantity (to 50). The final ActionScript sets an XML property in Flash, telling it to ignore white space (spaces and returns) in XML text files.

PHPObject Declarations

This section contains all of the variables and functions related to PHPObject. It begins by setting globals that tell PHPObject where to look for the "Gateway.php" file (which is necessary to communicate with PHP) and the password to use when communicating with the server (which must match the password in the "config.php" file on the server).

Next, it creates the myLeditor object:

// ActionScript
myLeditor = new PHPObject("Leditor");

This tells Flash to create a new object out of the PHPObject code, and tells PHPObject to link this object to the "Leditor.php" file on the server.

The remaining ActionScript defines the response functions for myLeditor, such as:

// ActionScript

// Handle results from levelListing() PHP function
myLeditor.levelListing_onResult = function() {
            // Fill the list box with array contents
     _root.files_available.dataProvider = this.localFiles;
}

This particular function is executed after the PHP function levelListing() has completed. This and the other response functions were discussed earlier in general. They are uncomplicated and well-commented, so read the code.

Grid Drawing Functions

This section contains all of the functions used to display the 20x20 tile grid. The first function is tileName(), which accepts two arguments: a reference to a column and a row. It returns a standardized name as a string. Thus, any place a tile move clip needs to be adjusted by name, that name can be derived from the tile's column and row by using this function.

The second function is drawGridFoundation(), which accepts no arguments, and simply initializes the blank 20x20 grid. It contains nested "for" loops to count through the rows and columns, tile by tile. For each tile, it determines a unique tile name (using tileName(), above), then takes a movie clip called "tile" from the library and attaches it to the empty movie clip instance called "origin" on the main timeline. (The tile's movie clip is called "grid tile" in the library list; however, if you select that item in the library and choose "Linkage" from the library menu, you'll see that its ActionScript name is "tile".) The function positions each "tile" movie clip horizontally and vertically on the screen, then attaches an "onMouseDown" function to the movie clip so it reacts to mouse clicks. Throughout it all, it tracks the movie clip stacking order (or "depth") to ensure that each "tile" clip depth is unique (as required by Flash).

The third function is drawGridXML(), which accepts one argument: an XML object called myXML. Like drawGridFoundation(), this function contains nested "for" loops to count through rows and columns, tile by tile. However, instead of creating a blank grid, this function uses XML node attributes from myXML to change the existing grid tiles.

The fourth function is updateTile(), which accepts one argument: a movie clip reference called who. This function was attached to every grid tile created by drawGridFoundation(), which told each tile to refer to updateTile() with itself ("this"). When you click on a grid tile, this function tests to make sure this tile was clicked (in case an errant click got through to it) and sets the tile to the current drawing tool shape. If the tile is already set to the current shape, then a click toggles it back to being empty. If the chosen drawing tool is the player shape, then the function prevents it from being placed more than once on the level (because you can't have more than one player!).

Input/Output Functions

This section contains all of the functions used to open, save and delete levels from the server.

The first function is openLevel(). It builds a file name from the previously-initialized global defaultGatewayDir with the name highlighted in the list of available files. Then it creates a Flash XML object and tells it what to do when it has finished loading the XML data. Finally, it loads it. (Note that this could have been handled by using PHPObject to read the file into an array, like the levelListing() function. That might actually be faster and use less bandwidth than having Flash parse the XML itself.)

The second function is saveLevel(). It begins by checking if there is room for another file on the server (by comparing the number of files to the maximum file limit set earlier). If there is room, it uses nested "for" loops to scan through all of the tiles on the grid. It saves information about the current frame of each tile movie clip into the two-dimensional array gameArray. It passes this to the PHP function levelSave() along with the file name typed into the text box, and then calls the PHP function levelListing() to update the file list box. However, if there is not room for another file, it displays an error message by changing the frame on a message movie clip.

The third function is deleteLevel(). This gets the name highlighted in the file list box and passes it to the PHP function levelDelete().

Define button functions

This section initializes the mouse click functions for the tool shapes and the save, open and delete buttons.

Final setup

This section calls the drawGridFoundation() function (explained above) to draw the first blank grid. And that's the end of the ActionScript.


Flowchart

The logic of the functions is illustrated in the flowchart below, from the beginning of the movie, to responses for each click. Functions are labeled according to whether they are in ActionScript (leditor.fla) or passed to PHP (Leditor.php) via PHPObject.

(Note: the "clicked on" boxes do not represent actual "if" statements in the code, but simply reflect the logic of how the clicks are responded to: "clicked on the delete button? do such-and-such.")


   
 
 
Name: Tor de Vries
Location: New York
Age: 30
Flash experience: I first began toying with it back when it was called "FutureSplash" and wasn't owned by Macromedia, if anyone else remembers that. Since then it has been a favorite tool alongside DHTML, JavaScript, PHP, Perl, XML and other buzzwords.
Job: Digital Designer
Website: http://www.tordevries.com/
 
 
| Homepage | News | Games | Articles | Multiplayer Central | Reviews | Spotlight | Forums | Info | Links | Contact us | Advertise | Credits |

| www.smartfoxserver.com | www.gotoandplay.biz | www.openspace-engine.com |

gotoAndPlay() v 3.0.0 -- (c)2003-2008 gotoAndPlay() Team -- P.IVA 03121770048