Javascript 多人游戏 - game/physics 逻辑的 requestAnimationFrame?
Javascript multiplayer game - requestAnimationFrame for game/physics logic?
我正在开发一款基于 Javascript 的多人游戏。
到目前为止,我已经准备好基本的服务器、客户端和网络。
我确实遇到了一个问题,我的播放器在 120Hz 屏幕上移动速度比 60Hz 屏幕快。我通过将玩家的移动速度乘以 'requestAnimationFrame'.
的增量时间来解决这个问题
但是;将动画与逻辑分开会是更好的解决方案吗?
如:
//Game loop; Do each 1/60th of a second
setInterval(gameTick, 1000/60);
function gameTick(){
player.handleKeys();
enemies.foreach( (enemy) => {
enemy.update();
});
}
//Draw loop; match to player screen refresh rate
window.requestAnimationFrame(gameLoop);
function gameLoop() {
player.draw();
enemies.foreach( (enemy) => {
enemy.draw();
});
window.requestAnimationFrame(gameLoop);
}
虽然差异可能是 "neglectable" 我想避开 240Hz 'spamming' 服务器的玩家并且比其他玩家有优势。
另一方面,对于 240Hz 显示器; 4 帧中只有 1 帧会处理您的键盘输入,因此感觉可能不那么流畅?
我问的原因是这将是一个竞争性游戏,因此应该是平衡的。但是我检查了各种来源,似乎一致认为使用 requestAnimationFrame(即使是逻辑;不仅仅是绘图),尽管我对此表示怀疑并且想知道哪个是正确的(and/or 使用在职业竞技游戏中)。
requestAnimationFrame
(rAF) 将仅以 60fps 的最大速率发射。 (一些浏览器的一些旧版本有关闭 VSync 的标志,这确实影响了 rAF)
备注
rAf
、setTimeout
或 setInterval
不可靠,可能会因多种原因丢帧。
如果 Tab 或 Window 被隐藏或(tab)未聚焦,rAF 将停止发射。
setInterval
和 setTimeout
如果选项卡或 Window 被隐藏或(选项卡)未聚焦,将被限制。
rAF时间参数不代表(下一个显示的)帧的时间,而是调用rAF回调的时间。
这意味着...
- 如果从 rAF 时间参数计算帧之间的时间将浮动并且不能可靠地用作增量时间。
- 时间参数表示调用时间,而不是帧呈现给显示器的时间,并且可以比渲染内容呈现给显示硬件的时间早 < 1/60 秒。
本地网络
对于多人游戏,服务器应该提供服务时间,以便所有玩家 运行 有一个共同且可靠的时间戳。如果网络延迟数据包,客户端可以从上一个时间戳向前预测时间以避免冻结,但应该在收到时恢复到同步(服务器时间)时间。
大型网络
通信取决于距离,即使在完美的点对点网络上,如果客户端位于世界的另一端,由于光传输时间,最佳 ping 可能为 130 毫秒(接近 8 帧 @60Hz)。这不包括数据包交换和实际路由长度。通常,到地球上最远点的 ping 时间约为 300 毫秒。
专业游戏必须考虑这种延迟,这也是为什么许多多人游戏提供本地服务器,并且如果距离较远则限制某些服务器的玩家。 300 毫秒为距离较近的玩家提供了显着优势。
使用浏览器 API 来托管客户端的实时多人游戏充其量也会有问题,因为浏览器是不可靠且不一致的客户端主机,主要是 运行 上的客户端设备。
顺便说一句
window
是默认值 this
(globalThis
),因此不是必需的。例如 window.requestAnimationFrame
等同于 requestAnimationFrame
我正在开发一款基于 Javascript 的多人游戏。 到目前为止,我已经准备好基本的服务器、客户端和网络。
我确实遇到了一个问题,我的播放器在 120Hz 屏幕上移动速度比 60Hz 屏幕快。我通过将玩家的移动速度乘以 'requestAnimationFrame'.
的增量时间来解决这个问题但是;将动画与逻辑分开会是更好的解决方案吗?
如:
//Game loop; Do each 1/60th of a second
setInterval(gameTick, 1000/60);
function gameTick(){
player.handleKeys();
enemies.foreach( (enemy) => {
enemy.update();
});
}
//Draw loop; match to player screen refresh rate
window.requestAnimationFrame(gameLoop);
function gameLoop() {
player.draw();
enemies.foreach( (enemy) => {
enemy.draw();
});
window.requestAnimationFrame(gameLoop);
}
虽然差异可能是 "neglectable" 我想避开 240Hz 'spamming' 服务器的玩家并且比其他玩家有优势。
另一方面,对于 240Hz 显示器; 4 帧中只有 1 帧会处理您的键盘输入,因此感觉可能不那么流畅?
我问的原因是这将是一个竞争性游戏,因此应该是平衡的。但是我检查了各种来源,似乎一致认为使用 requestAnimationFrame(即使是逻辑;不仅仅是绘图),尽管我对此表示怀疑并且想知道哪个是正确的(and/or 使用在职业竞技游戏中)。
requestAnimationFrame
(rAF) 将仅以 60fps 的最大速率发射。 (一些浏览器的一些旧版本有关闭 VSync 的标志,这确实影响了 rAF)
备注
rAf
、setTimeout
或setInterval
不可靠,可能会因多种原因丢帧。如果 Tab 或 Window 被隐藏或(tab)未聚焦,rAF 将停止发射。
setInterval
和setTimeout
如果选项卡或 Window 被隐藏或(选项卡)未聚焦,将被限制。rAF时间参数不代表(下一个显示的)帧的时间,而是调用rAF回调的时间。
这意味着...
- 如果从 rAF 时间参数计算帧之间的时间将浮动并且不能可靠地用作增量时间。
- 时间参数表示调用时间,而不是帧呈现给显示器的时间,并且可以比渲染内容呈现给显示硬件的时间早 < 1/60 秒。
本地网络
对于多人游戏,服务器应该提供服务时间,以便所有玩家 运行 有一个共同且可靠的时间戳。如果网络延迟数据包,客户端可以从上一个时间戳向前预测时间以避免冻结,但应该在收到时恢复到同步(服务器时间)时间。
大型网络
通信取决于距离,即使在完美的点对点网络上,如果客户端位于世界的另一端,由于光传输时间,最佳 ping 可能为 130 毫秒(接近 8 帧 @60Hz)。这不包括数据包交换和实际路由长度。通常,到地球上最远点的 ping 时间约为 300 毫秒。
专业游戏必须考虑这种延迟,这也是为什么许多多人游戏提供本地服务器,并且如果距离较远则限制某些服务器的玩家。 300 毫秒为距离较近的玩家提供了显着优势。
使用浏览器 API 来托管客户端的实时多人游戏充其量也会有问题,因为浏览器是不可靠且不一致的客户端主机,主要是 运行 上的客户端设备。
顺便说一句
window
是默认值 this
(globalThis
),因此不是必需的。例如 window.requestAnimationFrame
等同于 requestAnimationFrame