Watcher support

From Whirled Club Wiki
Jump to navigation Jump to search
Icon-Programming.png
Icon-Flex.png

Party games and games that permit players to watch a game in progress require some extra support, to make sure incoming players have all of the information that they need to watch or join the game. All code examples herein come from the game Piggy.

The easiest way to keep track of essential items for new players is to use properties. These can be accessed from the NetSubControl class inside the GameControl.

First, a little setup...

<actionscript> import com.whirled.game.GameControl; import com.whirled.game.PropertyChangedEvent; import com.whirled.game.ElementChangedEvent; </actionscript>

All of these types are essential to games using properties. Simply importing com.whirled.game may cause the compiler to fail.

The game should also register the following event listeners to be able to hear and respond to changes from the controller.

<actionscript> _control.net.addEventListener(PropertyChangedEvent.PROPERTY_CHANGED, propertyChanged); _control.net.addEventListener(ElementChangedEvent.ELEM_CHANGED, elemChanged); </actionscript>

(You may also want to register the MessageReceivedEvent, if your game will be using sendMessage from the NetSubControl, but it is not related to these examples) Also note that there are no examples provided for these events, as they are simply for active clients.

If the game keeps a score table as an array (recommended), the initialization code that runs upon game startup should set the property. Note that it is recommended only the controlling player should do this. This can be checked and executed as follows:

<actionscript> // Only proceed if this client is the controlling player. if (_control.game.amInControl()) { // Set up the array property initially so we can do individual element updates later on. _control.net.set("Scores", _scores); } </actionscript>

Note: The above example assumes your GameControl is named _control. This is the default with new Whirled projects. If all clients initialize the scoring array on their own, it is not necessary to listen for this particular property change, as it will not convey anything new to the clients. Any non-array variables should also be updated in this manner (in which case, it is necessary to listen for these). The following is such an example:

<actionscript> if (_control.game.amInControl()) { _control.net.set("Turn Total", "0"); } </actionscript>

Note: Any values obtained using BagSubControl methods will automatically be distributed as properties, so it is not necessary to manually set these.

After an array property has been set, updating it should be done using the setAt() method, which will just distribute the new element, rather than the entire array. The clients can update their local copies of the array themselves.

<actionscript> if (_control.game.amInControl()) { // Obtain the position of the player who's turn just ended so we get the right spot. var currentPosition :int = _control.game.seating.getPlayerPosition(_control.game.getTurnHolderId()); var newScore :int= _scores[currentPosition] + int(_turnTotal.text); // Send the score data to all players. _control.net.setAt("Scores", currentPosition, newScore); } </actionscript>

The ElementChangedEvent will trigger upon the completion of this.

Now that we have the property management in place, how do we get all this data to incoming watchers? Simple. The NetSubControl has the get() method for retrieving properties, so we'll use that.

<actionscript> //This occurs if the player is a watcher. if (_control.game.seating.getMyPosition() == -1) { _scores = _control.net.get("Scores") as Array; _control.local.setPlayerScores(_scores); _turnTotal.text = String(_control.net.get("Turn Total")); } </actionscript>

The above will pull in the scoring array (the "as Array" is required, or else the compiler will issue errors), and the property we were fiddling with earlier, and update them on the client-side. Note that in this example the game is applying the Turn Total property to the text property of a TextField, so it must be converted to a string first, or else the compiler will throw an error. After the watcher has these elements, it will receive property and element changed notifications on its own along with the other players. Covering watching for these is outside of the scope of this tutorial (as active player clients will need to watch these as well).

This is just a basic example of watcher support. Games that are more complicated may require more support to work properly.