我试图使用Node.JS和Socket.IO创建服务器。我想做一个只有简单运动事件的在线游戏。我写了一些代码,但它并没有很好地工作。我有很多延迟。您可以查看下面的视频。顺便说一下,我在我的DigitalOcean服务器甚至是我的LocalHost上测试它。我的问题有什么诀窍?我真的很想学习网络编程,但我总是陷入困境。
Latency GAMEPLAY YouTube Link -- Especially check 13th seconds
我将在下面解释我的所有作品。但是如果要查看详细信息代码。您可以访问GitHub项目链接。
在客户端,我使用Unity3D。如果用户键按下任何箭头键,如upArrow,rightArrow比我将此信息发送到服务器。通过这样做,服务器知道我想去哪个方向。
if (Input.GetKey(KeyCode.UpArrow))
{
Movement = Vector3.up;
JSONObject data = new JSONObject();
data.AddField("x", Movement.x);
data.AddField("y", Movement.y);
socket.Emit("move", data);
}
// if Input.GetKey(KeyCode.RightArrow)
// if Input.GetKey(KeyCode.RightArrow) .. etc
在服务器端,我只使用了Node JS和Socket.IO。我创建了一个间隔函数,只将所有玩家发送给客户。此间隔功能每1秒触发60次。您可以在下面看到代码。
setInterval(function() {
io.emit('state', players);
}, 1000 / 60);
顺便说一下,当服务器收到任何移动事件时,它会这样做:
socket.on('move', function(data) {
var player =players[socket.id] ||{};
player.x =player.x+(data.x*0.1);
player.y =player.y+(data.y*0.1);
});
答案 0 :(得分:0)
您还需要在本地移动。因此,当在客户端发出“移动”命令时,也开始在客户端移动播放器。如果从服务器收到新信息,请合并它们。关键字是插值。
答案 1 :(得分:0)
首先,您不需要间隔,除非您在节点中的服务器上进行实时物理模拟。
其次,以事件驱动的方式更多地考虑node.js。 I.E.当玩家在他们附近做出动作时,只向其他玩家发送更新。
第三次使用客户端预测。 I.E.继续并在客户端上移动播放器,即使服务器尚未收到它。然后根据服务器说的有效的最后位置进行插值。如果从服务器发送时间戳,简单的线性插值就可以正常工作。
第四,沟槽插座io。套接字时,套接字io的速度非常慢。如果你想使用websockets,那么我建议只使用节点库WS。 WS库高效且快速。或者,如果您想要一个事件驱动的库,如socket io,但基于WS库。然后,您可以尝试我使用的自定义库,并在多个基于在线的游戏中进行测试:https://github.com/Metric/data.io。我仍然积极维护它,并将在几周内推出对c#客户端的更新。对c#客户端的更新修复了我最近在新项目中使用它时发现的一些问题。但是,tcp比websockets更有效。与原始tcp或udp连接相比,Websockets的开销增加。是的,您仍然会遇到延迟,仍然需要客户端预测。
有关网络和预测的更多信息,请参阅:http://gafferongames.com/networking-for-game-programmers/
他还使用一些代码示例来涵盖所有概念。
另见:https://developer.valvesoftware.com/wiki/Source_Multiplayer_Networking