每秒仅需要大约30次更新(甚至更少,也许10或20)。插入客户端移动对象的位置。通常,仅在真正需要时才发送数据。在《魔兽世界》中,您可能会从同组的玩家那里收到比同位置的玩家更多的更新。另外,如果另一个玩家离您很远,您每秒不会收到太多关于他的更新。
然后,仅在每个玩家连接时向其发送一个完整的快照。之后,仅发送游戏对象的更改。如果未发生任何更改,请不要发送。
然后,大量使用BitVectors,但是您可以调用它们来减少不需要的数据量!示例:您也可以尝试仅使用一个字节(在0到1或-1到1的范围内)写一个浮点数,因此只有256或128个不同的值。但是由于插值,玩家不会注意到任何剧烈的运动。
在LidgrenLibrary上查看有关如何压缩数据的示例:http : //code.google.com/p/lidgren-network-gen3/wiki/Optimization
下一步:尝试减小玩家移动时的视野半径,并且仅在该时间内传输重要信息。然后当他们停止时,再次增加其视线半径。您可以使用空间哈希系统或bsp树来减少查找“范围内”对象的开销。对于以下主题,这是一本好书:http : //en.wikipedia.org/wiki/Collision_detection
也压缩数据YOURSELF只有自己知道关于数据结构和在数据中的时间相干性(其可以并且应该被利用)。应该使用诸如Bzip2,Deflate之类的通用算法,但只能作为压缩的最后阶段!
此外,对于非游戏关键信息,您还可以采用其他P2P技术。示例:一个播放器播放“ hello”动画。(只是一种图形效果)播放器将此信息发送到服务器,但是服务器不会将信息中继给其他播放器。而是由播放器本身将此非关键效果发送给范围内的其他客户端。
编辑(由于评论):
减少每个播放器每秒平均位数的其他方法:
您写道,您发送“对象未更改”。没有理由这样做。如果您担心数据包丢失(并因此而使仿真不同步),请考虑以下事项:在每个固定的时间步长(例如100、200、300、400 ...),对仿真状态进行哈希处理并将其发送到服务器。服务器确认或发送回所有数据的完整快照。
对于诸如火箭甚至是玩家之类的事物,您不仅可以使用插值法,而且可以采用外推法,以使模拟更加逼真。示例“火箭”:无需使用“现在位于位置x”之类的消息进行更新,只需发送一次包含以下内容的消息即可:“火箭产生:position(vector),时间(产生火箭的模拟步骤),速度(向量)”。因此,您甚至不必包括旋转,因为尖端将始终处于“速度”方向。
在一条消息中组合多个命令,并且永远不要发送小于16-20字节的消息,因为udp标头将大于消息本身。另外,不要发送大于协议MTU的数据包,因为碎片会减慢传输速度。