游戏服务器之角色移动

来源:互联网 发布:中美合作 规范网络 编辑:程序博客网 时间:2024/05/01 06:47

角色移动主要是要处理前后端的移动同步和阻挡检测。

(1)前端发送移动请求

(2)检查该角色是否可以移动到该位置,并记录移动请求

(3)根据当前位置和请求位置,循环计算位移

(4)遇到不可移动处(非法位置和阻挡位置)需要弹回

(5)刷新角色位置和屏索引

(6)广播给九宫格内其他玩家

角色移动的调用层次:

逻辑主循环-->场景管理器遍历->场景循环-->角色遍历-->角色循环-->角色移动


bool scene_player::loop()
{

//每隔500毫秒计算角色的移动
if(_five_hundred_msec(main_logic_thread::currentTime) )
    {
        autoMove();//根据当前位置和请求位置,循环计算位移

   }

......

}

//根据当前位置和请求位置,计算位移

bool scene_player::autoMove()
{
if (!scene)
{
error_log("autoMove,场景指针为空");
return false;
}

const nPos dstPos = _moveDstPos;//目的位置
const nPos nowPos(getPos());//目前位置

if (nowPos == dstPos)//就在原地不需要移动
{
return true;
}
if(0 == _move_speed_x && 0 == _move_speed_y)//速度为0
{
return true;
}
int64 moveTime = main_logic_thread::currentTime.msec() - _last_move_time;//这次的移动时间
_last_move_time = main_logic_thread::currentTime.msec();//当前计算移动时间
if(moveTime <= 0)
{
return true;
}

int stepx = 0;//时间间隔移动距离(x坐标轴的移动距离,单位是格子(一个格子32*32像素))
int stepy = 0;
if(_move_speed_x)
{
if(_move_speed_x>0)
{
stepx = (int)((double)(moveTime/_move_speed_x)) + 1;
}
else
{
stepx = (int)((double)(moveTime/_move_speed_x)) - 1;
}
}
if(_move_speed_y)
{
if(_move_speed_y>0)
{
stepy = (int)((double)(moveTime/_move_speed_y)) + 1;//正常速度是320ms一个格子(速度是以单个格子需要时间大小来计算的
}
else
{
stepy = (int)((double)(moveTime/_move_speed_y)) - 1;
}
}

nPos newPos = nowPos;

//一次最多移动两格子
if(stepx > 2 )stepx = 2;//横向格子数
else if(stepx < -2 )stepx = -2;
if(stepy > 2 )stepy = 2;//纵向格子数
else if(stepy < -2 )stepy = -2;

//到达指定点
if(abs(stepx) > abs(dstPos.x - nowPos.x) && abs(stepy) > abs(dstPos.y - nowPos.y))
{
_move_speed_x = _move_speed_y = 0;
newPos = dstPos;
}
else
{
if (abs(stepx) > abs(dstPos.x - nowPos.x))
{
stepx = dstPos.x - nowPos.x;
}
else if (abs(stepy) > abs(dstPos.y - nowPos.y))
{
stepy = dstPos.y - nowPos.y;
}


//避免超出边界(MAP_MAX_POS是1024*1024,单位格子)
newPos.x = int(newPos.x + stepx) < 0?0:(newPos.x + stepx);
newPos.x = newPos.x > MAP_MAX_POS.x ? MAP_MAX_POS.x:newPos.x;
newPos.y = int(newPos.y + stepy) < 0?0:(newPos.y + stepy);
newPos.y = newPos.y > MAP_MAX_POS.y ? MAP_MAX_POS.y:newPos.y;
#ifdef DEBUG_CJY
debug_log("newPos(%u %u)",newPos.x,newPos.y);
#endif
}

//检查阻挡,如果有阻挡则弹回到最后的合法格子(未加动态阻挡,可加,根据屏索引的数据)
if (scene->checkMapBlock(newPos, this))

 {
sendMoveFailToMe();
        return false;
 }
 

//刷新角色位置和更新角色屏索引
if (!freshPos(newPos))
{
    sendMoveFailToMe();
    return false;
}
 //广播给九宫格内其他玩家(不含自己)
sendMoveToNine(nowPos, newPos);
return true;
}


0 0
原创粉丝点击