Ninguém discorda que o SharedBall é o melhor exemplo de sincronização entre ambientes. Eu quando descobri o FMS foi meu primeiro exemplo que fiz, naquele caso era flash, para esta sincronização.
Para o SharedBall pode ser usado o Red5, com o serviço fitcDemo, ou outro serviço, e no FMS apenas criando uma pasta em /FMS/applications.
Basicamente temos um funcionamento parecido com o Chat, porém neste exemplo não utilizo o send, e sim o setProperty. Estou usando o setProperty para que quando manter o valor da ultima posição da bola através do evento SyncEvent.
Para testar, chame um amigo e peça para ele abrir a esta página e mostre que quando você arrasta a bola, ela é arrastada na maquina dele também.
Aqui vai o link do PNG da bola de futebol usada no exemplo:
http://img300.imageshack.us/img300/8048/bola.png
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute"
horizontalAlign="left"
backgroundColor="#f6f6f6"
backgroundGradientColors="[#f6f6f6, #bbbbbb]"
creationComplete="init()"
rollOut="mouseUp( event )"
viewSourceURL="247/index.html">
<mx:Script>
<![CDATA[
// Conexão com o servidor de Streaming
private var netConnection:NetConnection;
// Canal para o Chat
private var sharedObject:SharedObject;
// Guarda se o usuário esta movendo o
// a bola
private var isMoved:Boolean=false;
// Status da conexão com o RTMP
[Bindable]
private var isConnected:Boolean=false;
/**
* executa após carregar o aplicativo
*/
private function init():void
{
netConnection=new NetConnection();
netConnection.addEventListener( NetStatusEvent.NET_STATUS, netStatus );
netConnection.addEventListener( AsyncErrorEvent.ASYNC_ERROR, asyncError );
netConnection.connect( "rtmp://localhost/SharedBall" );
sharedBall.addEventListener( MouseEvent.MOUSE_DOWN, mouseDown );
sharedBall.addEventListener( MouseEvent.MOUSE_UP, mouseUp );
this.addEventListener( MouseEvent.MOUSE_MOVE, mouseMove );
}
/**
* Método que recebe o Status da conexão
*/
private function netStatus( e:NetStatusEvent ):void
{
RTMPstatus.text=e.info.code
switch ( e.info.code )
{
case "NetConnection.Connect.Success":
connectado();
isConnected=true;
break;
case "NetConnection.Connect.Closed":
isConnected=false;
break;
case "NetConnection.Connect.Rejected":
isConnected=false;
break;
case "NetConnection.Connect.Failed":
isConnected=false;
break;
default:
isConnected=false;
break;
}
}
/**
* Chamado quando deu sucesso na conexão com o Red5
*/
private function connectado():void
{
sharedObject=SharedObject.getRemote( "sharedBallExemplo", netConnection.uri, true )
sharedObject.addEventListener( SyncEvent.SYNC, OnSync );
sharedObject.addEventListener( AsyncErrorEvent.ASYNC_ERROR, asyncError );
sharedObject.connect( netConnection );
sharedObject.client=this;
}
/**
* Método responsável por tratar os AsyncErrorEvent
*/
private function asyncError( e:AsyncErrorEvent ):void
{
trace( e )
}
/**
* Método responsável por tratar os SyncEvent
*/
private function OnSync( e:SyncEvent ):void
{
if ( !isMoved )
{
sharedBall.x=sharedObject.data.x;
sharedBall.y=sharedObject.data.y;
}
}
private function mouseDown( e:MouseEvent ):void
{
isMoved=true
var rectangle:Rectangle=this.transform.pixelBounds
rectangle.width-=sharedBall.width
rectangle.height-=sharedBall.height
sharedBall.startDrag( false, rectangle );
}
private function mouseUp( e:MouseEvent ):void
{
isMoved=false
sharedBall.stopDrag();
}
private function mouseMove( e:MouseEvent ):void
{
if ( isMoved )
{
if ( sharedObject != null )
{
sharedObject.setProperty( "x", sharedBall.x );
sharedObject.setProperty( "y", sharedBall.y );
}
}
}
]]>
</mx:Script>
<mx:Label id="RTMPstatus"
text="Aguardando Conexão"
fontSize="18"
fontWeight="bold"
color="#AA0000"
bottom="10"
left="10"/>
<mx:Image id="sharedBall"
source="@Embed('assets/bola.png')"
visible="{isConnected}"
x="25"
y="25"/>
</mx:Application>