最新消息: 电脑我帮您提供丰富的电脑知识,编程学习,软件下载,win7系统下载。

Socket.io工作很奇怪

IT培训 admin 7浏览 0评论

Socket.io工作很奇怪

我正在使用socket.io创建一个带有移动对象的游戏。在我的程序中,我有这个(非常简化的)代码:

socket.on('sync', function(newpos) {
    console.log(countcount + "{ x: " + object.x + " y: " + object.y + "}");
    countcount = 0;

    object.x = newpos.x;
    object.y = newpos.y;
});

function loop() {
    countcount++;
    console.log("loop")
    socket.emit('sync', SOME DATA);
    //A lot of game code
    ...
    //A lot of game code
    window.requestAnim(loop);
}

所以我有loop()我的游戏内容正在执行,我还有一个事件捕获器捕获从服务器发送的'sync'事件与我的对象的newpos。但是当我运行代码时,我的对象正在抽搐。不是很多,但它是可见的。以下是我在谷歌工具中的控制台告诉我的内容:

如果你看1)它告诉我循环运行,然后调用我的回调,然后循环再次运行,然后再次调用回调,但循环运行和回调被调用两次。怎么可能?我发出单个事件然后我有两次触发回调?

如果你看2)类似的事情发生。为什么?

您还要告诉我有关此事件处理程序如何在客户端的javascript中工作的信息吗?这个回调可以在执行过程中干扰我的循环吗?或者这个回调堆放在某个地方?

服务器端代码:

socket.on('sync', function(data){
    // Handle player commands
    if (data.left) {socket.speed.x += -1; }
    if (data.right) {socket.speed.x += 1; }
    if (data.up) {socket.speed.y += -1; }
    if (data.down) {socket.speed.y += 1; }

    socket.normSpeed = Controller.norm(socket.speed);//Controller.norm(socket.speed);
    socket.speed = Controller.mult(socket.normSpeed, 3);//Controller.mult(socket.normSpeed, 3);

    socket.pos.x += socket.speed.x;
    socket.pos.y += socket.speed.y;
    socket.emit('sync', socket.pos);

    socket.speed.x = 0;
    socket.speed.y = 0;
});
回答如下:

你的问题是游戏的整体流程。 Request Animation Frame被描述为通常每秒呼叫60次。如果你进行数学计算(除以1000毫秒/ 60帧/秒),那么每帧大约需要16毫秒。虽然看起来似乎只是一点点时间,但这一点点时间会产生巨大的后果。

与任何其他Websocket连接一样,Sockets.io往往会对数据包何时到达产生一些不确定性。由于延迟,数据包可能会提前到达或者可能会晚到,具体取决于网络。

问题是,数据包到达的“速率”与您的每秒约60帧的帧速率不匹配。结果有两种情况。

在第一种情况下,数据包迟到。帧循环始终以每帧16ms的速度继续,因为它独立于数据包。到数据包到达时,已经调用了帧循环。这就是为什么“循环”在图像的第1部分上方被调用两次的原因。

在第二种情况下,当第一个数据包迟到时,第二个数据包准时到达。主循环每16ms不断调用一次,与返回数据包是否已被接收的事实无关。因此,它会连续向服务器请求返回数据包(同步客户端的发送)。两个数据包都将被发送,但两个数据包将由客户端在同一“帧”中接收。这就是你看到两个“同步”调用的原因。

一个例子是你图像的第1部分之前发生的事情。循环被调用两次,但没有收到数据。返回数据在哪里?它进入下一帧,一直持续到第1部分中间的双响应。

这是你游戏的缺陷。永远不要让客户向服务器询问数据。始终有一个定时循环,两侧相互独立。

但是,这并不是你的游戏生涩的原因。原因是因为您在收到数据包后直接将对象移动到某个位置。这样做的正确方法是将interpolate与旧的位置进行平滑运动。

(我知道这是因为我是一名游戏开发者。如果你打算进行Agar.io实现,请查看https://github/huytd/agar.io-clone的灵感。他们也使用socket.io)

Socket.io工作很奇怪

我正在使用socket.io创建一个带有移动对象的游戏。在我的程序中,我有这个(非常简化的)代码:

socket.on('sync', function(newpos) {
    console.log(countcount + "{ x: " + object.x + " y: " + object.y + "}");
    countcount = 0;

    object.x = newpos.x;
    object.y = newpos.y;
});

function loop() {
    countcount++;
    console.log("loop")
    socket.emit('sync', SOME DATA);
    //A lot of game code
    ...
    //A lot of game code
    window.requestAnim(loop);
}

所以我有loop()我的游戏内容正在执行,我还有一个事件捕获器捕获从服务器发送的'sync'事件与我的对象的newpos。但是当我运行代码时,我的对象正在抽搐。不是很多,但它是可见的。以下是我在谷歌工具中的控制台告诉我的内容:

如果你看1)它告诉我循环运行,然后调用我的回调,然后循环再次运行,然后再次调用回调,但循环运行和回调被调用两次。怎么可能?我发出单个事件然后我有两次触发回调?

如果你看2)类似的事情发生。为什么?

您还要告诉我有关此事件处理程序如何在客户端的javascript中工作的信息吗?这个回调可以在执行过程中干扰我的循环吗?或者这个回调堆放在某个地方?

服务器端代码:

socket.on('sync', function(data){
    // Handle player commands
    if (data.left) {socket.speed.x += -1; }
    if (data.right) {socket.speed.x += 1; }
    if (data.up) {socket.speed.y += -1; }
    if (data.down) {socket.speed.y += 1; }

    socket.normSpeed = Controller.norm(socket.speed);//Controller.norm(socket.speed);
    socket.speed = Controller.mult(socket.normSpeed, 3);//Controller.mult(socket.normSpeed, 3);

    socket.pos.x += socket.speed.x;
    socket.pos.y += socket.speed.y;
    socket.emit('sync', socket.pos);

    socket.speed.x = 0;
    socket.speed.y = 0;
});
回答如下:

你的问题是游戏的整体流程。 Request Animation Frame被描述为通常每秒呼叫60次。如果你进行数学计算(除以1000毫秒/ 60帧/秒),那么每帧大约需要16毫秒。虽然看起来似乎只是一点点时间,但这一点点时间会产生巨大的后果。

与任何其他Websocket连接一样,Sockets.io往往会对数据包何时到达产生一些不确定性。由于延迟,数据包可能会提前到达或者可能会晚到,具体取决于网络。

问题是,数据包到达的“速率”与您的每秒约60帧的帧速率不匹配。结果有两种情况。

在第一种情况下,数据包迟到。帧循环始终以每帧16ms的速度继续,因为它独立于数据包。到数据包到达时,已经调用了帧循环。这就是为什么“循环”在图像的第1部分上方被调用两次的原因。

在第二种情况下,当第一个数据包迟到时,第二个数据包准时到达。主循环每16ms不断调用一次,与返回数据包是否已被接收的事实无关。因此,它会连续向服务器请求返回数据包(同步客户端的发送)。两个数据包都将被发送,但两个数据包将由客户端在同一“帧”中接收。这就是你看到两个“同步”调用的原因。

一个例子是你图像的第1部分之前发生的事情。循环被调用两次,但没有收到数据。返回数据在哪里?它进入下一帧,一直持续到第1部分中间的双响应。

这是你游戏的缺陷。永远不要让客户向服务器询问数据。始终有一个定时循环,两侧相互独立。

但是,这并不是你的游戏生涩的原因。原因是因为您在收到数据包后直接将对象移动到某个位置。这样做的正确方法是将interpolate与旧的位置进行平滑运动。

(我知道这是因为我是一名游戏开发者。如果你打算进行Agar.io实现,请查看https://github/huytd/agar.io-clone的灵感。他们也使用socket.io)

与本文相关的文章

发布评论

评论列表 (0)

  1. 暂无评论