3D寻路算法,出现频繁拉回问题

角色行走频繁点击地面进行行走,会频繁出现客户端被拉回。

拉回的原因是客户端的位置和服务器的位置出现偏差。服务器强制拉回客户端。经过持续半个月间断性的查找,终于找到原因是,因为

int CCoordinatePath::GetCompletePath( DWORD dwNowTime )

{

// 无变速的移动距离计算

DWORD dwMoveTime = dwNowTime-m_dwStartMoveTime;

 

return (m_nCompletePath + m_wCurSpeed*dwMoveTime/1000);

}

之前行走距离进行了取整,不停的发送角色行走,不停的计算路径长度的过程,把角色行走距离给取整时过滤掉了,最终导致客户端比服务器位置提前,进行拉回。服务器也应该使用浮点数进行处理行走,这样才能保持客户端与服务器同步。解决客户端频繁拉回的问题。下面是修改后的代码。

 

获取角色当前位置的源代码(修正后)CoordinatePath.zip

#pragma once

 

class CCoordinatePath

{

public:

CCoordinatePath(void);

~CCoordinatePath(void);

 

public:

// 更新行走路径

void UpdatePath(COORDINATE_3D stopCoordinate3D);

void UpdatePath(vector<COORDINATE_3DPATH> vtPath, COORDINATE_3D stopCoordinate3D, float nCompletePath = 0);

// 开始行走(移动计算)

void StartMove(DWORD dwStartTime);

// 获取当前空间位置

COORDINATE_3D GetCoordinate(DWORD dwNowTime);

// 获取行走路径

const vector<COORDINATE_3DPATH>* GetPath();

// 获取停止位置

COORDINATE_3D GetStopCoordinate();

// 获取移动总距离(从开始行走到现在的行走总距离)

float GetCompletePath(DWORD dwNowTime);

// 更新玩家速度

void UpdateSpeed(unsigned short wSpeed, DWORD dwNowTime);

// 获取当前速度

unsigned short GetSpeed();

// 玩家是否正在移动

bool IsMoving(DWORD dwNowTime);

 

private:

// 行走路径

vector<COORDINATE_3DPATH> m_vtPath;

// 停止点

COORDINATE_3D m_stopCoordinate3D;

 

// 已完成路径

float m_nCompletePath;

// 玩家当前速度

unsigned short m_wCurSpeed;

// 行走路径开始时间

DWORD m_dwStartMoveTime;

};

 

#include "StdAfx.h"

#include "CoordinatePath.h"

 

CCoordinatePath::CCoordinatePath(void)

{

m_wCurSpeed = 4;

}

 

CCoordinatePath::~CCoordinatePath(void)

{

}

 

void CCoordinatePath::UpdatePath( COORDINATE_3D stopCoordinate3D )

{

m_vtPath.clear();

m_stopCoordinate3D = stopCoordinate3D;

m_nCompletePath = 0;

}

 

void CCoordinatePath::UpdatePath( vector<COORDINATE_3DPATH> vtPath, COORDINATE_3D stopCoordinate3D, float nCompletePath /*= 0*/ )

{

m_vtPath = vtPath;

m_stopCoordinate3D = stopCoordinate3D;

m_nCompletePath = nCompletePath;

}

 

void CCoordinatePath::StartMove( DWORD dwStartTime )

{

m_dwStartMoveTime = dwStartTime;

}

 

COORDINATE_3D CCoordinatePath::GetCoordinate(DWORD dwNowTime)

{

if (m_vtPath.size() == 0)

{

return m_stopCoordinate3D;

}

 

float nTotalDistance = GetCompletePath(dwNowTime);

 

if (nTotalDistance < 0)

{

cout << "计算玩家移动距离错误" << endl;

return m_stopCoordinate3D;

}

 

// ceshi

//cout << "距离:" << nTotalDistance << "时间" << (dwNowTime-m_dwStartMoveTime) << endl;

 

COORDINATE_3D coordinate3D;

 

// 上面已经计算出玩家行走总距离,计算玩家位置

vector<COORDINATE_3DPATH>::iterator itPath = m_vtPath.begin();

for (; itPath!=m_vtPath.end(); ++itPath)

{

if (itPath->allDistance > nTotalDistance)

{

// 角色当前位置在当前path中,计算当前位置

float nCurDistance = nTotalDistance - (itPath->allDistance - itPath->curDistance);

 

if (nCurDistance < 0)

{

cout << "[严重错误]获取坐标" << endl;

return m_stopCoordinate3D;

}

 

coordinate3D.x = itPath->x + itPath->dFormula*itPath->xDistance*nCurDistance;

coordinate3D.y = itPath->y + itPath->dFormula*itPath->yDistance*nCurDistance;

coordinate3D.z = itPath->z + itPath->dFormula*itPath->zDistance*nCurDistance;

coordinate3D.dir = itPath->dir;

 

if (coordinate3D.x ==1 && coordinate3D.y==1 && coordinate3D.z == 1)

{

int i = 0;

}

///yang

//cout << "当前移动坐标:x:" << coordinate3D.x << ",y:" << coordinate3D.y << ",z:" << coordinate3D.z << endl;

///yang

return coordinate3D;

}

}

 

// 到达目标点做先前点路径的清理工作

m_vtPath.clear();

 

return m_stopCoordinate3D;

}

 

const vector<COORDINATE_3DPATH>* CCoordinatePath::GetPath()

{

return &m_vtPath;

}

 

COORDINATE_3D CCoordinatePath::GetStopCoordinate()

{

return m_stopCoordinate3D;

}

 

float CCoordinatePath::GetCompletePath( DWORD dwNowTime )

{

// 无变速的移动距离计算

DWORD dwMoveTime = dwNowTime-m_dwStartMoveTime;

 

return (m_nCompletePath + m_wCurSpeed*dwMoveTime/1000.0f);

}

 

void CCoordinatePath::UpdateSpeed( unsigned short wSpeed, DWORD dwNowTime )

{

// 计算已经完成路径

m_nCompletePath += GetCompletePath(dwNowTime);

m_dwStartMoveTime = dwNowTime;

 

m_wCurSpeed = wSpeed;//当前速度

}

 

unsigned short CCoordinatePath::GetSpeed()

{

return m_wCurSpeed;

}

 

bool CCoordinatePath::IsMoving( DWORD dwNowTime )

{

GetCoordinate(dwNowTime);

 

if (m_vtPath.size() > 0)

{

return true;

}

else

{

return false;

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值