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.")
|