我正在做一个networking游戏,在客户端,我插入客户端位置与服务器发送外推位置。 客户端有自己的物理模拟,这是由服务器逐步纠正。 问题是,当它滞后,我“踢”球,服务器得到一个延迟的信息,并把我的位置向后的客户端位置,使球来回。 我想忽略这些,也许在服务器上补偿,但不知道。 问题是在这些情况下的时钟差异是0.07毫秒或0.10毫秒,这是不是很高,忽略我猜的消息。
当我得到服务器的位置,我外推的时钟间隔* serverBallVelocity
我可以检查我的新球服务器位置是否在我的实际的球vector位置后面吗? 我试图使用两个向量归一化后的点积来检查它们是否相反,但是它不能正常工作。
任何建议检查?
所以你有这样一个问题: 是一个点B S在一个点B C和一个法向量N定义的平面的前面还是后面?
因此,vector ,从客户端指向服务器的球位置,如果服务器的球位置在飞机的前面,则指向与N大致相同的方向,而在服务器的球的后面,如果在它的后面,则指向大致相同的方向。 因此,这两个点的产品 –
– 如果B S在B C的前面,则为正;如果在后面,则为负;如果在边的话,则为零。
这个计算是简单的,在伪C,并假设三个欧几里德尺寸:
bool is_in_front(vector3 ball_server, vector3 ball_client, vector3 front_direction) { double product = (ball_server.x - ball_client.x) * front_direction.x + (ball_server.y - ball_client.y) * front_direction.y + (ball_server.z - ball_client.z) * front_direction.z; return (product > 0.0); }
这是你要求回答错误问题的一个很好的例子。
你不想检测传入的vector是否在你的球后面。 它总是会在你的球后面,因为你的服务器和客户端之间总是存在滞后。
正确的解决scheme是测量客户端和服务器之间的往返时间并进行相应的调整。 如果你知道你有40毫秒的延迟,那么球正在以速度(1,-1)移动,你想告诉客户球现在在(4,7),你想发送该位置为(4.04,6.96)。
这样,当客户端在40ms之后收到更新时,它将把服务器发送消息的位置设置为(1,-1)* 40ms,这正是应该在的位置。
你也要做平滑和插补,而不是传球到要求的位置。
作为一个真实的例子,我想看看我的玩家是否被允许用武器攻击僵尸。
僵尸必须在玩家面前
var playerDirection:Vector2 = VectorUtility.createFromAngle( worldState.playerLocation.radians); var dot:Number = VectorUtility.dotProduct(worldState.delta, playerDirection); var isInfrontofPlayer:Boolean = dot <= -.8;
我决定检查-.8,因为我不希望玩家攻击位于玩家两侧的僵尸。