MMORPG 基础 - (1)

目前在写大厅类型的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("发生错误");
}

== 完 ==

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值