The Multiplayer Aspect


graphics/cd_icon.gif

In this section we are going to look at the ActionScript needed to handle the multiplayer aspect of this game. Also, we will examine one major issue that we solve easily using room variables. Open tic_tac_toe.fla from the Chapter17 folder on the CD.

As you may remember from Chapter 13, after two people have agreed to play a game, they are taken to the Game frame. Let's look at the ActionScript on this frame in the Actions layer now. Here are the last few lines of that ActionScript:

 1   ES.moveReceived = this.moveReceived;  2   ES.onRoomVarChange = roomVarChanged; 3   ES.chatReceiver = this.messageArrived; 4   ES.joinGame(); 5   iAmIn(); 

In the first three lines we define the event handlers. In line 1 we define the moveReceived event handler so that a function is executed whenever a move is received. We will see this function later. In the next line we define the onRoomVarChange event handler. (Remember that with ElectroServer we can store variables in a room on the server.) When a variable is created, modified, or deleted, this event fires. We define the onRoomVarChange event handler so that we know when we can check for new information. In line 3 we redefine the chatReceiver event handler, which we defined with a different function on the Chat System frame. Next, in line 4, we join the game. This method joins you to a room in which the ElectroServerAS object chose for you to play your game. (You do not need to know the name of this room; the ElectroServerAS object always chooses it.) Make sure you don't use the joinRoom() method until you have defined all of the event handlers; otherwise, you may receive information about your game that does not trigger the right events. Finally, in line 5, iAmIn() is executed. This function, which we will discuss below, creates a variable in your room indicating that you are there. Here is the iAmIn() function:

 1   function iAmIn() { 2      var name = "player"+ES.player; 3      var val = "here"; 4      ES.createVariable(name, val); 5   } 

This function creates a variable in your room on the server called player1 or player2 (depending on which player you are). When you challenge someone, a property on the ElectroServerAS object called player is set to 1. If you are the person who was challenged, then this property is set to 2. It is accessed to create the name of the variable in line 2 above. The value of this variable is "here" (line 3). In line 4 we create the variable on the server by invoking the createVariable() method of the ElectroServerAS object. Next we will discuss the roomVarChanged() function and why we set these room variables in the first place.

This is the roomVarChanged() function:

 1   function roomVarChanged(ob) { 2      if (ob.player1 == "here" && ob.player2 == "here") { 3         locked = false; 4         if (!initializedYet) { 5            initializedYet = true; 6            startGame(); 7         } 8      } else { 9         locked = true; 10        if (initializedYet) { 11           popup.gotoAndStop("player left"); 12        } 13     } 14  } 

This function is called whenever a variable is created, modified, or deleted in your room. An object is passed in containing every variable that your room contains. There are some other optional parameters we don't use here that give information about which variable was modified or deleted. (See Appendix C, "The ElectroServerAS Object," for information on those, specifically the variable onRoomVarChange.) As you can see in line 2, we check to see if player1 and player2 have a value of "here". If they do, that means, of course, that both players are in the room and are ready to play. We then set the value of the variable locked to false. The value of locked is true before we verify that both players are there. We use this variable to keep a player from making a move before both players are ready. You will see this used again later. In line 4 we check to see if the variable initializedYet is not true. If it is not true, then we set it to true and call the startGame() function. The initializedYet variable is used to deter mine when a player has left. In line 10 you can see that if initializedYet is true and either player1 or player2 does not have a value of "here", then a player has left the game.

graphics/tip_icon.gif

Being able to correctly determine when a player has left the game has been a major issue in Flash games. It is more difficult than it should be to determine this. It can be done with traditional multiplayer servers, but it usually requires tedious user-list comparisons. You would compare the current user list with an older user list to see who has entered the room or who has left the room. With this room-variable technique you can very easily tell when your opponent is in the room. If the opponent leaves the room, the server deletes his variable from the room and you are informed. You then know that he is no longer in the game.

We have now covered the ActionScript needed to arrive at the Game frame, join the game, set a variable to the room to indicate that you are there, and determine when both players are available. Now we will look at the ActionScript needed to send a move to your opponent. In order to understand what is happening when sending the move, we must also cover a bit about the game itself (which we would ideally leave for the code section later in the chapter). What we don't cover about the game ActionScript here we will cover in the next section.

graphics/17fig04.gif

The game of tic-tac-toe has nine tiles (which are movie clips) in three rows and three columns. Using a naming convention similar to what we have used throughout this book, the tiles are named piece1_1 through piece3_3. The first number in the name is the column number; the second is the row number. So the piece found in column 1 and row 2 is piece1_2. Each of these movie clips contains three keyframes. The first one (frame 1) contains an invisible button (an invisible button contains only a hit state). The second (labeled X) shows the letter X, and the remaining frame label, O, shows the letter O. We will be looking at the ActionScript on the button.

 1   on (release) { 2      _root.iGotClicked(this); 3   } 

When the piece has been clicked, the function iGotClicked() is called, and a reference to the movie clip is passed in. Now let's look at iGotClicked().

 1   function iGotClicked(who) { 2      if (!locked && gameInPlay && myTurn) { 3         myTurn = false; 4         who.gotoAndStop(myLetter); 5         who.letter = myLetter; 6         var ob = {name:who._name, type:"move"}; 7         ++moves; 8         checkForWin(); 9         sendMove(ob); 10     } 11  } 

A reference to the movie clip containing the button that was clicked (one of the nine tiles) is passed into this function. In line 2 we check to make sure that the game is not locked, that the game has been started, and that it is your turn. When the startGame() function is called, which we'll look at in the next section, the gameInPlay variable is set to true. When the game is over, the gameInPlay variable is set to false. So in line 2 we look to make sure that gameInPlay is true otherwise you shouldn't be trying to make a move. In line 3 we set myTurn to false. Next, we tell the movie clip that contains the button you clicked to move to a frame to display your letter (either X or O). We then store your letter in this movie clip as the variable letter (line 5). This is done so that when the script is checking to see if the game is over, it can easily look in each movie clip to find out which letter it is displaying. By inspecting the letter in all nine movie clips, we can tell who won the game. In line 6 we create an object called ob with the properties name and type. The name property contains the name of the movie clip that contains the button you clicked. The type property contains the string value "move". This object is what will be sent to your opponent (line 9). When your opponent receives this move, then moveReceived() is called on his computer. (We'll talk about the moveReceived() function next.) In line 7 a variable called moves is incremented. This variable is used by the checkForWin() function, which we will talk about in the next section.

Here is the moveReceived() function:

 1   function moveReceived(ob) { 2      if (ob.type == "move") { 3         myTurn = true; 4         var name = ob.name; 5         _root[name].gotoAndStop(hisLetter); 6         _root[name].letter = hisLetter; 7         ++moves; 8         checkForWin(); 9      } else if (ob.type == "restart") { 10        restart(); 11     } 12  } 

This function is called when you receive a move from your opponent. The parameter ob is an object that has been sent to you from your opponent. This is the first time you have seen ElectroServerAS's ability to send an ActionScript object from one Flash client to another. It is one of the most powerful uses of the ElectroServerAS object; it allows for even very complicated moves to be sent easily. However, in the case of tic-tac-toe, we are using just about the simplest moves possible we've only got "move" and "restart." In other games we might have several types of moves. (Understand that I am using the term move generally restarting a game isn't really a move, but it just enables us to easily consider restarting a move.) In line 2 we check to see if the move type is "move". If it is a "move" move, then we do several things. We set the myTurn variable to true. Since your opponent just moved, it is now your turn. We extract the name property from ob and store it as the local variable name. It is used to tell a specific movie clip the one your opponent clicked to move to the frame to display your opponent's letter, hisLetter. We increment moves and call the checkForWins() function. If the move type is "restart", then we call the restart() function.

graphics/arrow_icon.gif

To see the moveReceived() function in action in other games, see Chapters 18 and 19.


You have now seen the absolute basics of a multiplayer game using ElectroServer and the ElectroServerAS object. You can chat, challenge, create room variables, and send moves to your opponent. This is a very powerful toolkit! Next we will look at the rest of the code needed to make this game function.



Macromedia Flash MX Game Design Demystified(c) The Official Guide to Creating Games with Flash
Macromedia Flash MX Game Design Demystified: The Official Guide to Creating Games with Flash -- First 1st Printing -- CD Included
ISBN: B003HP4RW2
EAN: N/A
Year: 2005
Pages: 163
Authors: Jobe Makar

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net