PDA

View Full Version : Multiuser Characters Synchorinization


maani786
03-10-2009, 09:28 AM
Hello to everybody,

i am working on a multiuser game using flash cs3, FMS 3.5, php and mysql.
whenever some body logins to game page its character (MovieClip) selected by user at registration page appears on the screen and other online users can also see it at their own screens.

The main issue is when some one moves his/her character using arrow keys its movement is not affected to other users. i want this to work. uptill now what i figure out is the problem with character reference passed to FMS.

can any body suggest me some tips or solution to it.

thanks in advance

maani786
03-10-2009, 09:38 AM
hello
am working on a multi player game in flash cs3 and FMS 3.5,

user can register, select their characters (small movieclips i have only one at this time and that is Fairy) and then login to game.

every person can see character of all online users at his/her screen with username popped up at the head of characters.

user can move his/her character on screen using arrow keys of keyboard but their movement is not synchronized and visible to all users. i want to synchronize character movements at all screens simultaneously.

any positive response or help will be highly appreciated..

regards
maani

Paul Ferrie
03-10-2009, 10:29 AM
You need to create a serverside as file that communicates to each of the users what the other is doing.
The best thing you can do is to check out some of the chat examples.
That's what i did then just modified to fit my own needs.

hope it helps

maani786
03-10-2009, 10:44 AM
thanks for your instant response Paul Ferrie

i have developed main.asc
and use shared objects also for updating users list. user list works fine but the character position synchronization is not working


here is my code for user character synchronization
-----------
main.asc
-----------
application.onAppStart = function()
{

application.users_so = SharedObject.get("users_so", false);
application.users = new Array();
application.currCharacters = new Array();
}

application.onConnect = function( newClient, username ) {

// declaring some client specific variables
newClient.name = username;
application.acceptConnection(newClient);
newClient.call("setUserId", null, newClient.id);
trace(username+" Connected ");


user = new Object();
user.id = newClient.id;
user.name = newClient.name;
user.status = "Online";
application.users.push(user);
application.users_so.setProperty("users", application.users);


newClient.sync_character_position = function(character, xpos, ypos, screenWidth, screenHeight)
{
trace("sync_character_position: "+character+" x: "+xpos+" y: "+ypos);
for (var j=0; j<application.currCharacters.length; j++) {
if(character == application.currCharacters[j].ref) {
application.currCharacters[j].x = xpos;
application.currCharacters[j].y = ypos;
}
}
for (var i=0; i<application.clients.length; i++) {
if(application.clients[i].id != newClient.id) {
application.clients[i].call("change_characterPosition", null, character, xpos, ypos, screenWidth, screenHeight);
}
}
}


newClient.server_openCharacter = function(ch_ref, ch_title, ch_x, ch_y, ch_w, ch_h, screen_width, screen_height)
{
trace("server_openCharacter: character = "+ch_ref);
var chinfo = new Object();
chinfo.ref = ch_ref;
chinfo.title = ch_title;
chinfo.x = ch_x;
chinfo.y = ch_y;
chinfo.w = ch_w;
chinfo.h = ch_h;
chinfo.rw = screen_width;
chinfo.rh = screen_height;
application.currCharacters.push(chinfo);

for (var i=0; i<application.clients.length; i++) {
if(application.clients[i].id != newClient.id) {
application.clients[i].call("open_character", null, ch_ref, ch_title, ch_x, ch_y, ch_w, ch_h, screen_width, screen_height);

}
}
}
}
//
application.onDisconnect = function(client)
{
trace(client.name+" Disconnected");
for(i=0; i<application.users.length; i++) {
if(application.users[i].id == client.id) {
application.users.splice(i,1);
}
}

application.users_so.setProperty("users", application.users);

for (var i=0; i<application.clients.length; i++) {
if(application.clients[i].id != client.id) {
application.clients[i].call("close_character", null);
}
}
}

----------------
fla source code
----------------


// ... import necessary packages ... \\
import flash.net.*;
import flash.events.*;
import fl.events.*;

var userId:String = null;
var chrc:Fairy;
var conn:NetConnection = new NetConnection();

doConnect();

// ... Functionss ... \\

function doConnect():void {
conn.connect("rtmpt://localhost:1935/TestApp/", userName);
conn.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler);
function netStatusHandler(param1:NetStatusEvent):void {
switch(param1.info.code){
case "NetConnection.Connect.Success": {
trace("connected.");
connectOnline();
break;
}// end case
case "NetConnection.Connect.Closed": {
trace("Disconnected.");
break;
}// end case
case "NetStream.Play.StreamNotFound": {
trace("Connection Failed.");
break;
}// end case
default: {
break;
}// end default
}// end switch
}// end netStatusHandlers

conn.client = new Object();
conn.client.setUserId = function(id) {
userId = id;
}

conn.client.change_characterPosition = function(chrc, xpos, ypos, server_width, server_height) {
tracer.text = "Character = "+Fairy(chrc)+" xpos: "+xpos+" ypos: "+ypos; //tracer is a dynamic text field on stage
Fairy(chrc).x = (xpos/server_width) * stage.stageWidth;
Fairy(chrc).y = (ypos/server_height)* stage.stageHeight;
}

conn.client.open_character = function() {
removeChild(root[chrc]);
}

conn.client.move_character = function(chrc, xpos, ypos) {
chrc.x = xpos;
chrc.y = ypos;
}

conn.client.open_character = function(chrc, ch_title, xpos, ypos, w, h, server_width, server_height) {
chrc = new Fairy();
chrc.x = (xpos/server_width) * stage.stageWidth;
chrc.y = (ypos/server_height)* stage.stageHeight;
chrc.width = w*stage.stageWidth/server_width;
chrc.height = h*stage.stageHeight/server_height;
chrc.fairy_name.text = ch_title;
addChild(chrc);
}
}// end doConnect

function connectOnline():void {

var users_so:SharedObject = SharedObject.getRemote("users_so", conn.uri);
users_so.addEventListener(SyncEvent.SYNC, onSyncEvt);
users_so.connect(conn);
function onSyncEvt(evt:SyncEvent) {
var users:Array = evt.target.data.users;
user_list.removeAll();
for (var i=0; i < users.length; i++) {
user_list.addItem({label: users[i].name+" ("+users[i].status+")", data: {id: users[i].id}});
}
user_list.sortItemsOn("label");
}

//show character at stage with directional movement
var fairy:Fairy = new Fairy();
fairy.x = 878;
fairy.y = 564;
fairy.width = fairy.height = 200;
fairy.fairy_name.text = userName;
addChild(fairy);
trace(fairy);
conn.call("server_openCharacter", null, Fairy(fairy), fairy.fairy_name.text, fairy.x, fairy.y, fairy.width, fairy.height, stage.stageWidth, stage.stageHeight);


stage.addEventListener(KeyboardEvent.KEY_DOWN, keyPressedDown);

function keyPressedDown(param1:KeyboardEvent) : void {

var keycode:uint;
var step:uint;
keycode = param1.keyCode;
step = 5;

switch(keycode) {
case Keyboard.LEFT: {
fairy.x = fairy.x - step;
conn.call("sync_character_position", null, Fairy(fairy), fairy.x, fairy.y, stage.stageWidth, stage.stageHeight);
break;
}// end case

case Keyboard.RIGHT: {
fairy.x = fairy.x + step;
conn.call("sync_character_position", null, Fairy(fairy), fairy.x, fairy.y, stage.stageWidth, stage.stageHeight);
break;
}// end case

case Keyboard.UP: {
fairy.y = fairy.y - step;
conn.call("sync_character_position", null, Fairy(fairy), fairy.x, fairy.y, stage.stageWidth, stage.stageHeight);
break;
}// end case

case Keyboard.DOWN: {
fairy.y = fairy.y + step;
conn.call("sync_character_position", null, Fairy(fairy), fairy.x, fairy.y, stage.stageWidth, stage.stageHeight);
break;
}// end case

default: {
break;
}// end default
}// end switch
}// end function
}


please help in fixing the issue
thanks in advance

Rossman
03-11-2009, 12:30 AM
Hmm, i did something like this just this past weekend but I didn't use SharedObjects to synchronize the data, I just make calls to the server and then broadcast messages back to all clients.

Basically, when the user presses a key (say Right Arrow), I send a movement change to the server (new x and y position), and when the server gets this call it broadcasts the change out to all clients, passing them all the coordinates for all the clients, and each client updates it's display accordingly.

This is a complex topic and I'm real new to it myself so I'm not sure I can offer much more than that!

Cheers!

maani786
03-19-2009, 10:39 AM
thanks..

i have done it with keeping user session at both server and client end.