我正在研究2D自上而下的射手,并尽力复制类似Quake 3这样的网络游戏中使用的概念。
- 我有一个权威服务器。
- 服务器将快照发送到客户端。
- 快照包含时间戳和实体位置。
- 实体插值在快照位置之间,因此移动看起来很流畅。
- 根据需要,实体插值会稍微“过去”发生,因此我们可以在多个快照之间进行插值。
我面临的问题是“时钟同步”。
- 为了简单起见,让我们假设一下,在与服务器之间传输数据包时,延迟为零。
- 如果服务器时钟比客户端时钟早60秒,则快照时间戳将比客户端本地时间戳早60000ms。
- 因此,在客户端看到任何给定的实体进行移动之前,实体快照将收集并静置约60秒钟,因为客户端时钟要花很长时间才能赶上。
通过设法在每次接收快照时计算服务器时钟和客户端时钟之间的差异,我设法解决了这一问题。
// For simplicity, don't worry about latency for now...
client_server_clock_delta = snapshot.server_timestamp - client_timestamp;
确定实体插入插值的距离时,我只需将差值添加到客户的当前时间即可。但是,这样做的问题是,由于快照比其他快照更快或更慢地到达,这两个时钟之间的差异将突然波动,这将导致混乱。
如何才能使时钟足够紧密地同步,以使唯一可感知的延迟是硬编码用于插值的延迟,而该延迟是由普通网络延迟引起的?
换句话说,如何在时钟严重失步时防止插值开始得太晚或太早而又不引起混乱呢?
编辑:根据Wikipedia的说法,NTP可以用于在几毫秒内将互联网上的时钟同步。但是,该协议似乎很复杂,也许在游戏中使用会显得过分杀伤力?