Creating a cooperative drawing whiteboard

We have created a basic example to log in to the SmartFoxServer. Now we are going to create a whiteboard so every connected user can draw on the same whiteboard.

The concept is to add mouse listeners to handle the event when mouse is down, mouse moves, and mouse is up. When the mouse is down and moves, the application broadcasts the mouse coordination to all users within the room and all users then draw the lines according to the received coordination.

We will have a glance of the full code and explain it part by part in detail.

package {
import it.gotoandplay.smartfoxserver.SmartFoxClient;
import it.gotoandplay.smartfoxserver.SFSEvent;
import it.gotoandplay.smartfoxserver.data.Room;
import it.gotoandplay.smartfoxserver.data.User;
import flash.display.*;
import flash.events.MouseEvent;
public class Ch03_03 extends MovieClip{
private var _sfs:SmartFoxClient;
private var _drawing:Boolean = false;
//---------------------------------------
// CONSTRUCTOR
//---------------------------------------
public function Ch03_03()
{
_sfs = new SmartFoxClient(true);
_sfs.addEventListener(SFSEvent. onConnection,onConnection);
_sfs.addEventListener(SFSEvent.onRoomListUpdate, onRoomListUpdate);
_sfs.addEventListener(SFSEvent.onPublicMessage, onPublicMessage);
_sfs.connect("127.0.0.1",9339);
stage.addEventListener(MouseEvent.MOUSE_DOWN, startDrawing);
stage.addEventListener(MouseEvent.MOUSE_ MOVE,drawing);
stage.addEventListener(MouseEvent.MOUSE_UP, stopDraw);
}
private function onConnection(e:SFSEvent):void
{
var ok:Boolean = e.params.success;
if (ok){
/* Login to the zone 'simpleChat' with empty name and empty password */
_sfs.login("simpleChat","","");
}
}
private function onRoomListUpdate(e:SFSEvent):void
{
/* Auto-join the default room of the zone */
_sfs.autoJoin();
}
private function onPublicMessage(e:SFSEvent):void
{
/* Get the message from the onPublicMessage Event*/
var message = e.params.message;
// Split the Array into three parts by the comma ','
var splitArray = message.split(','),
/* The starting indicates that the coordinatation
* is a starting point or drawing point */
var starting = Number(splitArray[0]);
/* The coordination of the drawing point */
var pointX = Number(splitArray[1]);
var pointY = Number(splitArray[2]);
/* Move the starting point if it is the first point of the line*/
if (starting == 1){
this.graphics.moveTo(pointX,pointY);
}else{
/* Draw the line accroding to the received cooredination */
this.graphics.lineStyle(5,0x000000);
this.graphics.lineTo(pointX,pointY);
}
}
private function startDrawing(e:MouseEvent):void
{
/* Send a public message with coordination as message text */
_sfs.sendPublicMessage('1,'+mouseX+','+mouseY);
_drawing = true;
}
private function drawing(e:MouseEvent):void
{
if (_drawing){
_sfs.sendPublicMessage('0,'+mouseX+','+mouseY);
}
}
private function stopDraw(e:MouseEvent):void
{
_drawing = false;
}
}
}

Let's get in to detail of the code part by part. We are using mouse as input so we need to import MouseEvent to the class.

package {
import it.gotoandplay.smartfoxserver.SmartFoxClient;
import it.gotoandplay.smartfoxserver.SFSEvent;
import it.gotoandplay.smartfoxserver.data.Room;
import it.gotoandplay.smartfoxserver.data.User;
import flash.display.*;
import flash.events.MouseEvent;
...

Except for the SmartFoxClient instance variable, we need a Boolean flag to know whether the user is drawing.

private var _drawing:Boolean = false;

In the constructor, we add three more event listeners to listen to the mouse up, mouse down, and mouse move event. Also we will add an onPublicMessage event to receive the drawing coordination from other users.

public function Ch03_03()
{
_sfs = new SmartFoxClient(true);
_sfs.addEventListener(SFSEvent.onConnection,onConnection);
_sfs.addEventListener(SFSEvent. onRoomListUpdate,onRoomListUpdate);
_sfs.connect("127.0.0.1",9339);
_sfs.addEventListener(SFSEvent.onPublicMessage, onPublicMessage);
stage.addEventListener(MouseEvent.MOUSE_DOWN,startDrawing);
stage.addEventListener(MouseEvent.MOUSE_MOVE,drawing);
stage.addEventListener(MouseEvent.MOUSE_UP, stopDraw);
}

In the previous examples, we used "myname" as the login name. In this example we are going to test the Flash with multiple instances, therefore we need to log in with different names. However, we have not made the name input feature yet, so we will assign an empty name when joining the application. SmartFoxServer will make the name look like "Guest_1" when joining the zone with an empty name.

private function onConnection(e:SFSEvent):void
{
var ok:Boolean = e.params.success;
if (ok){
_sfs.login("simpleChat","","");
}
}

This is a drawing application so we will add logic to the mouse interactivity.

When the mouse is down, it will call the startDrawing function. This function will send a public message with the mouse coordination as the message text.

private function startDrawing(e:MouseEvent):void
{
_sfs.sendPublicMessage('1,'+mouseX+','+mouseY);
_drawing = true;
}

If the mouse is moving with the left button pressed, it means the user is drawing on the canvas. We will send out the drawing coordination in a public message too.

private function drawing(e:MouseEvent):void
{
if (_drawing){
_sfs.sendPublicMessage('0,'+mouseX+','+mouseY);
}
}

When the mouse is up, we need to reset the _drawing flag to false so that any mouse moving after mouse up will not be wrongly treated as drawing.

private function stopDraw(e:MouseEvent):void
{
_drawing = false;
}

We have added an onPublicMessage event listener. This event handler will be called when there is an incoming public message. We will draw the lines in the onPublicMessage handler.

private function onPublicMessage(e:SFSEvent):void
{
var message = e.params.message;
var splitArray = message.split(','),
var starting = Number(splitArray[0]);
var pointX = Number(splitArray[1]);
var pointY = Number(splitArray[2]);
if (starting == 1){
this.graphics.moveTo(pointX,pointY);
}else{
this.graphics.lineStyle(5,0x000000);
this.graphics.lineTo(pointX,pointY);
}
}

Let's take a detailed look at this handler.

We first retrieve the content of the public message.

var message = e.params.message;

The message is something like 0,{mouseX},{mouseY} and the three pieces of information are separated by a comma (","). The first number is either 0 or 1 to indicate that this is the start drawing point or a mouse moving point. The second and third numbers are the mouse coordination of the user who is drawing.

We split the received message into an array to retrieve those three numbers.

var splitArray = message.split(','),
var starting = Number(splitArray[0]);
var pointX = Number(splitArray[1]);
var pointY = Number(splitArray[2]);

If it is a starting point, we will move the point to the coordination and be ready for drawing the line. If it is a moving point, we draw the line with a five-pixels width black line.

if (starting == 1){
this.graphics.moveTo(pointX,pointY);
}else{
this.graphics.lineStyle(5,0x000000);
this.graphics.lineTo(pointX,pointY);
}

That is how the onPublicMessage handler draws the lines. Please note that a public message is sent to all users including the sender of that public message. Therefore, the sender also receives the onPublicMesasge event with the same message that is sent out.

To test the synchronization drawing effect, we have to publish the Flash file into HTML and SWF by File | Publish in Flash IDE.

Testing the cooperative whiteboard

Open the newly published HTML file in the web browser. If you read the Flash logfile, it will show the trace and debug messages from this Flash document.

We need another instance of Flash to test the synchronization effect. To open another instance, copy the URL of the opened web browser and paste in another web browser window. Then we will have two same Flash documents connected to the SmartFoxServer to simulate two users logging in to the same server.

Draw something in one of the Flash document and you will see every instance draws the same line magically. This is our first multiuser application with SmartFoxServer.

Testing the cooperative whiteboard

These are two web browsers opening the whiteboard application with one drawing the "Hello" text and the other drawing the shading.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.119.255.44