Examples (iOS)
Examples (Android)


» Avatar Chat

» Overview

The Avatar Chat example is aimed at showing the usage of the SmartFoxServer 2X User Variables.

User Variables are one of the three server variable objects available in SmartFoxServer to store data to be shared among the clients of an application or game (the other two are Room Variables and Buddy Variables, which we will deal with in other examples). What's the difference between a server variable and a regular one? The main difference is that the first one (as the word says) is stored on the server and broadcasted to the other clients. In particular, a User Variable is broadcasted to all the other users in the same Room where the owner of that variable is located. This means that a change in a User Variable will be reflected on all other clients within the same Room so that, for example, they can update the scene accordingly.

In this example all the users are represented by an avatar (a crash test dummy) that they can move around in a simple environment (which represents the server Room), so we need to get position updates from all the clients to keep the scene in sync. For this reason we use two User Variables, "x" and "y", that represent the position of the corresponding avatar on the screen. When we create or update these variables, all the other clients in the Room are notified and they can put the avatar of its owner in the right place, or make it walk from one place to another.

As this is a simple example, made for educational purposes, our avatars move on a straight line, without anything acting as an obstable on their path. For this reason we can largely optimize the behavior of the client by updating the User Variables just once per movement, setting them at the value of the target coordinates and leaving to each client the task of interpolating the animation from the initial position to the final one (a simple tween is enough). This reduces a lot the bandwith usage .
More complex games involving path finding techniques or requiring a perfect synchronization of the clients may require constant position updates and advanced techniques for animation interpolation and position prediction. You can check the more advanced examples provided with SmartFoxServer2X for more informations on this subject.

Back to the Avatar Chat example. In addition to the position variables, we use a third User Variable, called "dir", in which we store the direction faced by the avatar, among the eight possible ones. This variable allows us to display the existing avatars in the right direction as soon as the current user enters a Room.

Possible improvements of this example, that we will leave up to you, could be creating different backgrounds for different Rooms (hint: use a Room Variable to store the id of the background to be used) and adding "non-walkability" areas to the environments.

>> DOWNLOAD the source files <<

» Installation

» Running the example

In order to run the application follow these steps:

  1. make sure your SmartFoxServer 2X installation contains the BasicExamples Zone definition;
  2. start SmartFoxServer 2X;
  3. make sure the client will connect to the right IP address by editing the <ip> entry in the xml file available under the /deploy folder;
  4. open the /deploy/AvatarChat.html file in a browser.

» Source code setup

The example assets are contained in the /source folder and they don't require a specific setup: simply open the .fla file in Adobe Flash.

» Code highlights

The timeline of the example's main FLA is divided into sort of "scenes" identified by these labels: load, connect and chat. Both connect and chat frames call a specific initialization method (initConnect and initChat respectively) on the document class.

In the initConnect method we retrieve a reference to the SmartFox client API from the SmartFoxBits Connector available on the stage (see the note below) and add the listeners to SmartFoxServer events we need for our application:

public function initConnect():void
	// Stop on current frame
	// Get the instance of the SmartFox class from the SmartFoxBits' Connector
	sfs = connector.connection

	// Add SFS2X event listeners
	sfs.addEventListener(SFSEvent.LOGIN, onLogin)
	sfs.addEventListener(SFSEvent.CONNECTION_LOST, onConnectionLost)
	sfs.addEventListener(SFSEvent.ROOM_JOIN, onRoomJoin)
	sfs.addEventListener(SFSEvent.USER_ENTER_ROOM, onUserEnterRoom)
	sfs.addEventListener(SFSEvent.USER_EXIT_ROOM, onUserExitRoom)
	sfs.addEventListener(SFSEvent.USER_VARIABLES_UPDATE, onUserVarsUpdate)
	sfs.addEventListener(SFSEvent.PUBLIC_MESSAGE, onPublicMessage)

The onLogin handler simply moves the playhead to the main chat scene. The onConnectionLost instead freezes the interface in case the connection with SmartFoxServer is lost. In a real-world scenario this method should be improved, for example showing a message to the user, or allowing him to try to reconnect.

The onRoomJoin event handler is called as soon as the current user enters a Room. Here we can remove all the avatars on the stage in case another Room was joined previously, create the avatars corresponding to users already inside the Room and set the position and direction User Variables for the current user, like this:

private function onRoomJoin(evt:SFSEvent):void
	// Create current user's avatar by setting its position user variables to a random value
	// This is required the first time only, because we are not clearing user position
	// when the room is changed
	if (!sfs.mySelf.containsVariable(USERVAR_X) && !sfs.mySelf.containsVariable(USERVAR_Y))
		var px:int = Math.round(Math.random() * panel_chat.avArea.width)
		var py:int = Math.round(Math.random() * panel_chat.avArea.height)
		var dir:String = AVATAR_DIRECTIONS[2]
		setAvatarVariables(px, py, dir)

private function setAvatarVariables(px:int, py:int, dir:String):void
	var userVars:Array = [];
	userVars.push(new SFSUserVariable(USERVAR_X, px));
	userVars.push(new SFSUserVariable(USERVAR_Y, py));
	userVars.push(new SFSUserVariable(USERVAR_DIR, dir));
	sfs.send(new SetUserVariablesRequest(userVars));

As the comment in the onRoomJoin method says, in our example we set the current user's position only the first time the user joins a Room after the login. For simplicity, in fact, on subsequent Room changes we decided to preserve the user position in the environment.
Similarly, the onUserEnterRoom and onUserExitRoom handlers respectively create and remove the avatars of those users who join or leave the Room in which the current users is.

Setting the User Variables makes the avatar appear on all the clients by means of the onUserVarsUpdate handler. As the variables are set when the user clicks on the environment too (to make his avatar move — see the onAvAreaClick method), inside the handler we have to differentiate between these two cases. If the avatar already exists, we have to make it move, otherwise we have to create it.

private function onUserVarsUpdate(evt:SFSEvent):void
	var changedVars:Array = evt.params.changedVars as Array;
	var user:User = evt.params.user as User;
	// Check if the user changed his position
	if (changedVars.indexOf(USERVAR_X) != -1 || changedVars.indexOf(USERVAR_Y) != -1)
		// Check if avatar exists
		if (getAvatar(user.id) != null)
			// Move the user avatar
			// Create the user avatar
			createAvatar(user, true)

Finally, the onPublicMessage handler is responsible of receiving the public chat messages sent using the text input field and send button available in the application, and display them in the chat bubble of the corresponding avatar.

This example makes use of some of the SmartFoxBits user interface components. Please read the corresponding paragraph in the introduction to the ActionScript 3 examples.

You should read the comments to methods and properties in the example source code for additional informations and possible code optimizations.

» More resources

You can learn more about the described feature by consulting the following resources:

Also, as this example shows the basic steps in creating an avatar chat, you may take a look at OpenSpace, a powerful ActionScript 3 isometric engine for rapid development of multi-user virtual worlds and MMO communities.