语录提交--登陆--注册--论坛交流--站长博客

Fms 数据同步

[作者:来自网络][日期:2007-12-28][导航:Flash教程 >> Fms2 >> Fms 数据同步]
  

趁着今天有空更新写下自己用fms做连网游戏的同步数据传输的处理方法~

大家用fms做连网游戏有一个概念,是一定要注意的,那就是同一个客户端文件因为为不同客户所用,当我们编写脚本时就得理清客户端既作为我自己的客户端的同时,也作为别人的客户端。

在这个的前提下我们就要涉及数据传输的问题了~

我个人认为,为了减轻服务端的负担,不是太重要的处理事件就得尽量写到客户端的脚本里去的~~,那样做有利于我们文件运行时的效率,而在那前提下数据同步的问题就不得不好好的在客户端写好了

下边看看我写的一个例子可能脚本会多了点:

//////////////////////////////////////////服务端脚本//////////////////////////////////////

application.onAppStart = function () {

menber = [];

id = 0;

ingame_num=0

};

application.onConnect = function (newClient, arr) {

ingame_num++

menber.push (arr[0][0]);

application.acceptConnection (newClient);

if(ingame_num<=100){

for (var i = 0; i < application.clients.length; i++) {

if (application.clients[i] == newClient) {

trace("呼叫ready")

application.clients[i].call ("ready", null, ingame_num);

}

}}

};

Client.prototype.reCall = function (obj) {

if (obj.type_ == "public" || obj.type_ == true) {

//广播信息

application.broadcastMsg (obj.func, obj.info);

}

//私聊机制

else if (obj.type_ == "private" || obj.type_ == false) {

for (var i = 0; i < application.clients.length; i++) {

if (menber[i] == obj.condition) {

application.clients[i].call (obj.func, null, obj.info);

}

}

}

//调用服务器自身函数

else if (obj.type_ == "main") {

this[obj.func](obj.info);

}

};

/////////////////////////////////////客户端部分////////////////////////////////////////////

/////////////////////////////上传数据帧听处理类////////////////////////

class watch_func {

function watch_func(obj:Object, name:String, info_arr:Array, mync2) {

var func = function (prop, oldVal, newVal, info_arr) {

if (arguments[1].x != arguments[2].x || arguments[1].y != arguments[2].y) {

function call_appliaction(who, func, info, type, condition) {

var Send = {};

Send.func = func;

Send.info = info;

Send.type_ = type;

Send.condition = condition;

//呼叫服务器中介函数

who.call("reCall", null, Send);

}

//移动物更新坐标~

info_arr[8][1] = obj.info;

//服务器调用的更新信息处理函数(根据type的定义类型为广播),用于同步更新其他客户端处于更新状态的移动物的信息

call_appliaction(mync2, "call_move", info_arr, true);

}

return newVal;

};

obj.watch(name, func, info_arr);

}

}

/////////////////////////////帧听数据及影射同步类//////////////////////////////////

class watch_func_E {

function watch_func_E(obj:Object, name:String, map:MovieClip, name_, info) {

var w = [map, name_, info];

var Em_func = function (prop, oldVal, newVal, w) {

//arguments[3] 在这里是参数w的内容

//arguments[3][0]这里等于类的自身参数map元件,这里用于表示路径

//arguments[3][0][arguments[2][8][1].name_等于场景中map元件内的元件(具体元件名由obj所帧听的对象决定)

for (var i in arguments[3][0][arguments[2][8][1].name_]) {

//遍历mc的属性

for (var j = 0; j //i 为属性名,arguments[2][j][0]为更新对象的信息,if条件用于检测属性名是否一致

if (i == arguments[2][j][0]) {

//将更新的属性值赋值给场景中对应的元件属性

arguments[3][0][arguments[2][8][1].name_][i] = arguments[2][j][1];

}

}

}

//更新场景对应的元件的坐标

trace("x="+arguments[3][0][arguments[2][8][1].name_].info.x)

trace("y="+arguments[3][0][arguments[2][8][1].name_].info.y)

arguments[3][0][arguments[2][8][1].name_]._x = arguments[3][0][arguments[2][8][1].name_].info.x;

arguments[3][0][arguments[2][8][1].name_]._y = arguments[3][0][arguments[2][8][1].name_].info.y;

};

obj.watch(name, Em_func, w);

}

}

/////////////////////////////////////客户端部分//////////////////////////////////////////

//////////////////导入as部分///////////////////

function init_info(me, menber, info_arr) {

//for (var i =1; i <=11; i++) {

//var me = where["menber" + i];

me.side = info_arr[0];

me.status = info_arr[1];

me.appointment = info_arr[2];

me.power = info_arr[3];

me.spess = info_arr[4];

me.shoot = info_arr[5];

me.lost = info_arr[6];

me.id = i;

me.info = {name_:me._name, x:me._x, y:me._y};

menber.push(me);

//}

return menber;

}

//求两者距离

function dis_func(mc1, mc2) {

if (typeof (mc1) != "movieclip") {

var dx = mc1.x-mc2._x;

var dy = mc1.y-mc2._y;

} else if (typeof (mc2) != "movieclip") {

var dx = mc1._x-mc2.x;

var dy = mc1._y-mc2.y;

} else {

var dx = mc1._x-mc2._x;

var dy = mc1._y-mc2._y;

}

dis = Math.sqrt(Math.pow(dx, 2)+Math.pow(dy, 2));

return dis;

}

//寻最近者

function fine_nearest(arr, ball) {

//将距离放入数组

for (var i = 0; i arr[i][4] = dis_func(ball, arr[i][0]);

}

//排序

for (var i = 0; i for (var j = i+1; j if (arr[i][4]>arr[j][4]) {

var tmp = arr[i];

arr[i] = arr[j];

arr[j] = tmp;

}

if (arr[i][4] == arr[j][4]) {

}

}

}

//返回

var Obj = {};

Obj.near = arr[0];

Obj.arr = arr;

return Obj;

}

//距离

function dis_init(arr, target_obj) {

for (var i = 0; i var m = this["m"+i];

if (dis_func(m, target_obj)<60) {

follow_move(target_obj, m, m.spees);

}

}

}

//方向

function degree_func(trget_obj, move_obj) {

if (typeof (trget_obj) != "movieclip") {

var dx = move_obj._x-trget_obj.x;

var dy = move_obj._y-trget_obj.y;

} else if (typeof (move_obj) != "movieclip") {

var dx = move_obj.x-trget_obj._x;

var dy = move_obj.y-trget_obj._y;

} else {

var dx = move_obj._x-trget_obj._x;

var dy = move_obj._y-trget_obj._y;

}

if (dy == 0) {

if (dx>0) {

degree = 90;

} else {

degree = 270;

}

} else {

if (dy>0) {

degree = Math.atan(dx/dy)*180/Math.PI;

} else {

degree = Math.atan(dx/dy)*180/Math.PI+180;

}

}

move_obj.degree = -degree;

return move_obj.degree;

}

//跟随函数

function follow_move(trget_obj, move_obj, speed) {

var degree = -degree_func(trget_obj, move_obj);

if (dis_func(trget_obj, move_obj)<=10) {

} else {

move_obj._y += speed*Math.cos(degree*(Math.PI/180))*-1;

move_obj._x += speed*Math.sin(degree*(Math.PI/180))*-1;

}

return move_obj;

}

//斜率

function k_(obj1, obj2) {

if (typeof (obj1) != "movieclip") {

var k = (obj1.y-obj2._y)/(obj1.x-obj2._x);

} else if (typeof (obj2) != "movieclip") {

var k = (obj1._y-obj2.y)/(obj1._x-obj2.x);

} else {

var k = (obj1._y-obj2._y)/(obj1._x-obj2._x);

}

return k;

}

//////////////////第一帧///////////////////

stop();

var ID;

#include "player.as"

var mync2 = new NetConnection();

mync2.ready = function(what) {

ID = what;

gotoAndStop("play_game");

};

mync2.init_full = function(what) {

gotoAndStop("full");

};

play_btn.onPress = function() {

if (txt.text != "") {

ID_ = txt.text;

list_arr = [[ID_, 123456]];

mync2.connect("rtmp://localhost/ball_v1", list_arr);

mync2.onStatus = function(info) {

if (info.code == "NetConnection.Connect.Success") {

} else {

gotoAndStop("lost_game");

}

};

}

};

///////////////////第2帧/////////////////////////////////////

import flash.geom.Point;

stop();

////////中介函数////////

function call_appliaction(who, func, info, type, condition) {

var Send = {};

Send.func = func;

Send.info = info;

Send.type_ = type;

Send.condition = condition;

who.call("reCall", null, Send);

}

///广播我方成员变更信息给其他玩家函数

mync2.call_move = function(info) {

if (int(info[info.length-1]) != ID) {

for (var i = 0; i<=11; i++) {

EM_arr[i].info = info;

}

} else {

}

};

////////编历储存信息函数//////

function putin(what, arr) {

for (var i in what) {

arr.push([i, mm[i]]);

}

}

///////

info_Marr = [];

info_Earr = [];

info_arr1 = ["m", "attack", 1, 5, 8, 1, 1];

info_arr2 = ["e", "attack", 1, 5, 8, 1, 1];

var cnt = 1;

ME_arr = [];

EM_arr = [];

for (var i = 1; i<=11; i++) {

////创建对象////

var ME = "ME"+i;

var EM = "EM"+i;

ME = {};

EM = {};

ME_arr.push(ME);

EM_arr.push(EM);

////创建对象////

////记录信息////

var m = map["m"+i];

var e = map["e"+i];

m.gotoAndStop(2);

e.gotoAndStop(3);

init_info(m, info_Marr, info_arr1);

init_info(e, info_Earr, info_arr2);

////记录信息////

}

///区分玩家敌我类型///

if (ID%2 == 0) {

var conter = map.m1;

play_side = "m";

} else {

var conter = map.e1;

play_side = "e";

}

for (var i = 1; i<=11; i++) {

var mm = map[play_side+i];

///创建信息数组

var info_arr = "info_arr"+i;

info_arr = [];

//编历储存对象信息

putin(mm, info_arr);

//信息整理

info_arr.reverse();

//添加id信息

info_arr.push(ID);

///////创建影射帧听实例/////

Em = EM_arr[i];

Em.info;

new watch_func_E(Em, "info", map, name_, info);

//创建玩家帧听控制对象帧听实例

var player = ME_arr[i-1];

player.info = mm.info;

new watch_func(player, "info", info_arr, mync2);

}

this.point_x = new Point(map[play_side+1]._x, map[play_side+1]._y);

/////////////////////玩家控制执行部分/////////////////

this.onEnterFrame = function() {

if (down) {

this.point_x = new Point(_xmouse, _ymouse);

}

for (var i = 1; i<=11; i++) {

var mm_ = map[play_side+i];

mm_.info = {name_:mm_._name, x:mm_._x, y:mm_._y};

var mc_ = map[play_side+i];

ME_arr[i-1].info = mm_.info;

if (mc_.hitTest(_xmouse, _ymouse, true)) {

conter = mc_;

break;

}

}

follow_move(this.point_x, conter, 5);

};

this.onMouseDown = function() {

down = true;

};

this.onMouseUp = function() {

down = false;

};

///////////////////////////////////////////////////////////////////////////////////////////////

当我们处理涉及多个元件的数据同步时~一般的过程是:帧听数据对象数据改变-------------》将要传输的数据放到一个对象或数组里------------》经由服务器传输,--------------》在服务器处理返回形式------------》解释返回数据-------------------》影射同步数据

上边的例子可能大家也发现了我服务端调用的函数很少,大多情况都是调用了我写的那个中介函数来处理,服务端主要的职能在这里只是用于数据的传输,运算的过程主要集中在客户端的。

我们在客户段要做的其实就是帧听对象的数据改变否,改变了我们就给服务端发送信息,然后再经由服务端分析要传输的类型,在返回客户端,再由客户端解释返回数据,然后解释,并影射相关数据。

[文章热度:]


上一页:FMS做在线视频录制

下一页:Flash Media Server 2的功能

最新话题

网站导航

搜索

网站公告


Copyright 2007 51as.com. Some Rights Reserved.
鄂ICP备07003189号

Powered by: KingCMS 5.0.1.0217