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.

Using Objects in Flash

If you are familiar with Flash's ActionScript language, you already understand some things about objects (in the programming sense of the word). For example, you may have created a movie clip and given it the instance name "myTitleSequence". To tell it to go to frame 54, you might write this:

// ActionScript

In this case, "myTitleSequence" is being treated as an object, and "gotoAndPlay" is a function or method of that object. To move the movie clip to a different location on the screen, you might write this:

// ActionScript
myTitleSequence._x = 200;
myTitleSequence._y = myTitleSequence._x + 100;

In this case, "_x" and "_y" are properties of the object. Flash uses these properties to position this movie – in this case, moving its origin point to coordinate (200,300).

Just about everything in Flash is treated as an object, from movie clips to text boxes. You can create also create your own generic objects and give them their own properties and functions, like this:

// ActionScript

// Create object
var myIceCream = new Object;
// Add some properties
myIceCream.chocolate = "none";
myIceCream.strawberry = "full";
myIceCream.vanilla = "half";

// Add a function
myIceCream.checkStatus = function() {
   if (this.chocolate == "none") trace("Buy more chocolate!");
   if (this.strawberry == "none") trace("Buy more strawberry!");
   if (this.vanilla == "none") trace("Buy more vanilla!");

Elsewhere in your ActionScript, you could refer to "myIceCream.checkStatus()" to determine which kind of ice cream you need to buy. Because this function is part of the "myIceCream" object, it can use the special variable "this" to refer to its own properties.

Using the PHPObject

PHPObject relies on a kind of "shared object" between ActionScript and PHP. This is a special object that exists in Flash and in PHP, with identical or complementary properties and functions. For the "leditor" game editor, the ActionScript for this object resembles this:

// ActionScript

// Create object
myLeditor = new PHPObject("Leditor");
// Add a property
myLeditor.localFiles = new Array();

// Add some functions
myLeditor.onInit = function() { }
myLeditor.onAbort = function() { }
myLeditor.onResult = function() { }	
myLeditor.levelSave_onResult = function() { }
myLeditor.levelListing_onResult = function() { }
myLeditor.levelDelete_onResult = function() { }
(The ActionScript inside these functions has been removed for brevity.)

In this code, there is only one property, "localFiles". Shortly, it will become an array of file names to be displayed in the file listing box.

When the object is created, the PHPObject refers to "Leditor". This tells the PHPObject that there is a PHP file on the server by the same name, "Leditor.php", with a PHP class inside it called "Leditor". That PHP file contains code like this:

// PHP

class Leditor {
   function Leditor() { }
   function init() { } 
   function levelSave ($filename, $gameArray) { }
   function levelListing() { }
   function levelDelete($filename) { }

(The PHP inside these functions has been removed for brevity.)

With PHPObject, these properties and functions are fully accessible through the myLeditor object from both ActionScript and PHP. Thus, calling the PHP function "levelSave" from ActionScript is as simple as this:

// ActionScript

The PHP code for the "levelDelete" function will then execute on the server, using the ActionScript variable "levelName" passed to the PHP variable "$filename". PHP can also operate directly on the Flash object properties, and vice versa. Earlier, we gave the myLeditor object this array in ActionScript:

// ActionScript
myLeditor.localFiles = new Array();

The PHP function "levelListing" can manipulate this array directly, like this:

// PHP
$this->localFiles[0] = $filename;

The thing called "localFiles" is the same array of information, shared between the Flash object and the PHP object. Where Flash uses "this.localFiles" inside a myLeditor function, PHP uses "$this->localFiles" to handle the very same array.

Reacting to PHP Execution

When a PHP function finishes executing, it notifies one of the Flash functions associated with the PHPObject. This way, Flash knows when data has been updated, and can modify the display as needed. For Leditor, the connections are as follows:

When this PHP function finishes... notifies this Flash function.
function init() { } myLeditor.onInit = function() { }
(when the PHP is interrupted) myLeditor.onAbort = function() { }
(for all PHP functions) myLeditor.onResult = function() { }
function levelSave () { } myLeditor.levelSave_onResult = function() { }
function levelListing() { } myLeditor.levelListing_onResult = function() { }
function levelDelete() { } myLeditor.levelDelete_onResult = function() { }

The "onInit" and "onAbort" functions are required parts of PHPObject, responding to the initialization and interruption of PHPObject objects.

Look at the four "onResult" functions. The last three specifically have the same names as the PHP functions that notify them; e.g. "levelSave()" notifies "levelSave_onResult". The first "onResult" function is generic, and is only notified after any PHP function that does not have a specifically-named result function. This allows you to handle some functions generically, and handle other functions very specifically. Our Leditor object does not actually use the generic onResult function, opting to have entirely customized functions instead.

Doing Things In Order

When referring to PHP functions from Flash, you must wait for one function to finish before beginning the next function, or the second one will not work. PHPObject functions operate serially. For example, this code will not work:

// ActionScript


The second function will never execute. It will be sent to the object before the first one has finished, which is impossible for PHP to handle properly.

There are two solutions for this. If you know that a specific function is always followed by another specific function, you can "chain" the two together through the "onResult" functions in Flash. For example:

// ActionScript

myLeditor.levelSave_onResult = function() {
            myLeditor.levelListing_onResult = function() {
    // some other code 

With this code, Flash calls the "levelSave" function, which then notifies Flash to execute the "levelSave_onResult" function, which then calls the "levelListing" function, which then notifies Flash to execute the "levelListing_onResult" function. Thus, through the prescribed chain of PHPObject events, you can execute a series of functions.

However, this solution only works when the second function always follows the first. This is frequently not true; you may only want the second function to execute in certain circumstances. PHPObject offers a way of storing up a series of commands so that they execute sequentially. By adding the "delayExecute()" and "execute()" functions, the above code can be made to work as follows:

// ActionScript


The "delayExecute()" command tells PHPObject to queue all the commands that follow, not executing them until it gets an "execute()" command. By encapsulating the PHPObject functions this way, you have a large amount of control over the sequence of functions.

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
| Homepage | News | Games | Articles | Multiplayer Central | Reviews | Spotlight | Forums | Info | Links | Contact us | Advertise | Credits |

| | | |

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