目前在写大厅类型的RPG游戏,游戏基于Flex3 + FMS3.5 + Asp.net(C#) + sqlServer2008开发,开发过程中有一些经验放在csdn上;
下面的例子用到了Flex3和Fms3.5,实现了大厅功能
基于Fms3.5的服务器端开发:
main.asc
// 游戏大厅
userList = []; // 用户列表
times = new Date(); // 当前时间
isBanIp = false; // 是否IP限制(Boolean)
isBanPtacc = 20; // 用户名位数限制(int)
application.allowDebug = true;
load("bill/onApp.asc");
load("bill/onConnect.asc");
load("bill/onDisconnect.asc");
load("bill/createGameRoom.asc")
load("bill/exception.asc");
以下asc在bill目录下
onApp.asc
/**
* 初始化和服务器结束相关服务器端方法
*
*/
// 应用程序被服务端装载时调用
application.onAppStart=function()
{
trace(times.toTimeString() + " FMS Game Hall Server Start ... ...");
}
// 应用程序被服务端卸载时调度
application.onAppStop=function()
{
trace(times.toTimeString() + " FMS Game Hall Server Stop ... ...");
}
onConnect.asc
// ptaccId 账户
// userInfo 用户属性(数组形式)
// roomId 房间Id(0)Game1
// readyId 用户是否准备好 false
// ip IP地址
// 客户机连接时调度
application.onConnect = function(client)
{
application.acceptConnection(client); // 允许客户端连接
// 客户端调度
client.communicateServer = function(ptacc, objUserInfo)
{
// 验证未通过
if (!validateClient(ptacc, client))
return;
client.ptaccId = ptacc;
userList.push({ptaccId:client.ptaccId, userInfo:objUserInfo, roomId:'0', readyId:false, ip:client.ip});
conInformation(client); // 打印信息
if(userList.length > 0)
{
trace(" ↓ " + times.toTimeString() + " userList informartion");
for(a=0; a<userList.length; a++)
trace(" ptaccId:" + userList[a].ptaccId + " roomId:" + userList[a].roomId + " readyId:" + userList[a].readyId + " ip:" + userList[a].ip);
trace(" ");
application.broadcastMsg("outUserList", userList); // 调度客户端方法 返回大厅用户列表
}
if(gameRoomList.length > 0)
application.broadcastMsg("outGameRoomList", gameRoomList); // 调度客户端方法 返回游戏房间列表
}
// 创建房间 客户端调度
client.createGameRoom = function(roomname, prsoncei)
{
if(newGameRoom(client, roomname, prsoncei))
{
application.broadcastMsg("outGameRoomList", gameRoomList); // 调度客户端方法 返回游戏房间列表
application.broadcastMsg("outThisGameRoomList", gameRoomList); // 创建房间成功调度客户端方法 返回游戏房间列表(用于获取当前用户的房间信息)
}
else
client.call("showServerMsg", null, "800x30010012"); // 创建房间失败(用户重复创建房间)
}
}
// 打印信息
function conInformation(_client)
{
trace(" → " + _client.ptaccId + " 进入大厅");
trace(" ");
}
// 验证用户信息
function validateClient(_ptacc, _client)
{
isValidate = false; // 验证是否通过
// 调用客户端方法 ptacc不能为空或者超过20位
if (_ptacc.length <= 0 || _ptacc.length >= 20)
{
_client.call("showServerMsg", null, "800x30010007");
application.disconnect(_client);
return isValidate;
}
for (i=0; i < userList.length; i++)
{
// 用户IP限制
if ((isBanIp) && (userList[i].ip == _client.ip))
{
_client.call("showServerMsg",null,"800x30010009");
application.disconnect(_client);
return isValidate;
}
// 用户名相同踢除
if (userList[i].ptaccId.toUpperCase() == _ptacc.toUpperCase())
{
_client.call("showServerMsg",null,"800x30010010");
application.disconnect(_client);
return isValidate;
}
}
isValidate = true;
return isValidate;
}
onDisconnect.asc
// 客户机断开连接时调度
application.onDisconnect=function(client)
{
disInformation(client); // 打印信息
for(j=0; j<userList.length; j++)
{
if (userList[j].ptaccId == client.ptaccId)
userList.splice(j,1);
}
if(userList.length > 0)
{
trace(" ↓ " + times.toTimeString() + " userList informartion");
for(a=0; a<userList.length; a++)
trace(" ptaccId:" + userList[a].ptaccId + " roomId:" + userList[a].roomId + " readyId:" + userList[a].readyId + " ip:" + userList[a].ip);
trace(" ");
application.broadcastMsg("outUserList", userList); // 呼叫客户端方法 返回当前房间用户列表
}
else
disInformation1(); // 打印信息2
if (gameRoomList.length > 0)
application.broadcastMsg("outGameRoomList", gameRoomList); // 调度客户端方法 返回游戏房间列表
}
// 打印信息
function disInformation(_client)
{
if(_client.ptaccId == null)
{
trace(" → 用户离开房间");
trace(" ");
}
else
{
trace(" → " + _client.ptaccId + " 离开房间");
trace(" ");
}
}
// 打印信息2
function disInformation1()
{
trace(" ↑ 大厅无人在线");
trace(" ");
}
exception.asc
/**
* 异常处理相关服务器端方法
*
*/
application.onStatus = function()
{
trace("发生错误");
}
createGameRoom.asc
gameRoomList = []; // 游戏房间(Array)
soGameId = SharedObject.get('sGameId', false); // 游戏房间Id
soGameId.setProperty('gameId', 0); // 设置房间起始ID
// 创建游戏房间
function newGameRoom(_client, _roomname, _prsoncei)
{
// roomId 房间(Game1)
// roomMaster 房主(ptacc)
// gameStart 游戏是否开始(false)
// personNum 游戏人数(0)
// personCei 人数上限
isCreate = false; // 是否创建成功
if (gameRoomList.length > 0)
{
for (i=0; i<gameRoomList.length; i++)
{
if (gameRoomList[i].roomMaster == _client.ptaccId)
return isCreate; // 不允许重复创建房间
}
}
soGameId.lock(); // 锁定SharedObject,禁止其他用户更改
soGameId.setProperty('gameId', soGameId.getProperty('gameId') + 1);
sTmp = 'Game' + soGameId.getProperty('gameId');
for (j=0; j<userList.length; j++)
{
if (userList[j].ptaccId == _client.ptaccId)
{
userList[j].roomId = sTmp; // 房间号
}
}
gameRoomList.push({roomId:sTmp, roomName:_roomname, roomMaster:_client.ptaccId, gameStart:false, personNum:0, personCei:_prsoncei});
soGameId.unlock(); // 解除SharedObject锁定
trace('准备创建游戏房间 ' + sTmp);
trace(' ');
isCreate = true;
return isCreate
}
下面的例子用到了Flex3和Fms3.5,实现了房间、分组、同时转发消息等功能;
main.asc
// 游戏房间
userList = []; // 用户列表
times = new Date(); // 当前时间
redList = ["Ra", "Rb", "Rc", "Rd"]; // 红队列表
blueList = ["Ba", "Bb", "Bc", "Bd"]; // 兰队列表
// application.allowDebug = true;
load("bill/onApp.asc");
load("bill/onConnect.asc");
load("bill/onDisconnect.asc");
load("bill/exception.asc");
以下asc在房间服务器的bill目录下
onApp.asc
/**
* 初始化和服务器结束相关服务器端方法
*
*/
// 应用程序被服务端装载时调用
application.onAppStart=function()
{
trace(times.toTimeString() + " FMS Game Hall Server Start ... ...");
}
// 应用程序被服务端卸载时调度
application.onAppStop=function()
{
trace(times.toTimeString() + " FMS Game Hall Server Stop ... ...");
}
onConnect.asc
// 客户机连接到这个应用程序调度
application.onConnect = function(client)
{
if (userList.length >= 2)
{
// 调用客户端方法 已经达到最大用户数
client.call("showServerMsg", null, "800x30010006");
application.rejectConnection(client);
}
else
{
application.acceptConnection(client); // 允许客户端连接
client.communicateServer = function(userGroup, ptacc)
{
if (ptacc.length <= 0 || ptacc.length >= 20) // 判断用户名
{
// 调用客户端方法 ptacc未输入或者超过20位
client.call("showServerMsg",null,"800x30010007");
application.disconnect(client); // 断开链接
return;
}
for (i=0; i < userList.length; i++)
{
/* if (userList[i].ip == client.ip) // 判断用户IP
{
// ip限制
client.call("showServerMsg",null,"800x30010009");
application.disconnect(client); // 断开链接
return;
}*/
if (userList[i].name.toUpperCase() == ptacc.toUpperCase()) // 用户名相同
{
// 用户名相同踢除
client.call("showServerMsg",null,"800x30010010");
application.disconnect(client);
return;
}
}
if (userGroup == 1) // 红队
{
if ((redList.length) > 0) // 红队未满
{
client.groupId = redList[0];
redList.splice(0,1);
}
else // 红队满了加兰队
{
if ((blueList.length) > 0)
{
client.groupId = blueList[0];
blueList.splice(0,1);
}
}
}
else // 兰队
{
if ((blueList.length) > 0) // 兰队未满
{
client.groupId = blueList[0];
blueList.splice(0,1);
}
else // 兰队满了加红队
{
if ((redList.length) > 0)
{
client.groupId = redList[0];
redList.splice(0,1);
}
}
}
client.username = ptacc; // 获取用户名
trace(" → " + client.username + " 进入房间");
userList.push({name:client.username, group:client.groupId, ip:client.ip});
if(userList.length > 0)
{
trace(" ");
trace(" ↓ " + times.toTimeString() + " userList informartion");
for(a=0; a<userList.length; a++)
{
trace(" name:" + userList[a].name + " group:" + userList[a].group + " ip:" + userList[a].ip);
}
trace(" ");
// 呼叫客户端方法 返回当前房间用户列表
application.broadcastMsg("outUserList", userList);
}
else
{
trace(" ");
trace(" ↑ 当前无用户在线");
trace(" ");
}
}
}
}
onDisconnect.asc
// 客户机从这个应用程序断开连接时调用
application.onDisconnect=function(client)
{
if(client.username == null)
trace(" → 用户被踢出房间");
else
trace(" → " + client.username + " 离开房间");
for(j=0; j<userList.length; j++)
{
if (userList[j].name == client.username)
{
_proceId = client.groupId
if (_proceId.indexOf("R") != -1) // 红队
redList.push(_proceId);
else // 兰队
blueList.push(_proceId);
userList.splice(j,1);
}
}
if(userList.length > 0)
{
trace(" ");
trace(" ↓ " + times.toTimeString() + " userList informartion");
for(a=0; a<userList.length; a++)
{
trace(" name:" + userList[a].name + " group:" + userList[a].group + " ip:" + userList[a].ip);
}
trace(" ");
// 呼叫客户端方法 返回当前房间用户列表
application.broadcastMsg("outUserList", userList);
}
else
{
trace(" ");
trace(" ↑ 当前无用户在线");
trace(" ");
}
}
exception.asc
/**
* 异常处理相关服务器端方法
*
*/
application.onStatus = function()
{
trace("发生错误");
}
== 完 ==