实时多人游戏 - 区域广播

时间:2016-08-08 01:24:17

标签: javascript node.js performance sockets

我正在编写实时多人游戏(使用Nodejs,socket.io),我想请求您帮助优化一点。

我实施了一个权威服务器,其更新循环 60次/秒和广播循环 20次/ s ,客户端预测和插值。 然后,在广播循环中,我尝试了区域广播,这会导致性能问题。

要成为极简主义者,服务器的数组为:

  • 玩家实体(id +位置)
  • 食品实体(id +职位)

在一张大地图中生成1000种食物(就像agar.io一样),在服务器的数组 server.foods 中。玩家只需要知道他的视口中的食物状态(让我们说 200种可见食物)。因此,服务器仅向播放器发送带有200个可见食物(id +位置)的一个数据包。然后,为了让服务器知道,我们在Player对象中的数组中推送200个可见食物( player.foods

但播放器可以移动,因此必须发送其他数据包:

  • initFoods 这是一系列食物(id +位置)到初始化(仅当玩家可以看到新食物时: distFoodPlayer< 500

  • removeFoods 这是一系列要删除的食物(ID +位置)(仅当玩家看不到新食物时: distFoodPlayer> 600

要了解这些信息,我会这样做:

for (var i = server.foods.length; i--;) {
    //Edit: added the next line
    if (distPlayerFood < 900) {
        var food = server.foods.entities[i];
        var inPlayerFoods = false;
        for (var j = player.foods.length; j--;) {
            if (food.id === player.foods[j]) {
                inPlayerFoods = true;
                if (distPlayerFood > 600) {
                    removeFoods.push(food.id);
                    player.foods.splice(i, 1);
                }
            }
        }
        if (distPlayerFood < 500) {
            if (!inPlayerFoods) {
                player.foods.push(food.id);
                initFoods.push([food.id, food.state]);
            }
        }
    }
});

1000种食物和1种播放器的性能良好(服务器的更新循环保持~58FPS)。但是对于5000种食物和1种播放器(或1000种食物和5种播放器),性能非常糟糕,因为这种双循环(服务器最大可达~25-40FPS)但带宽最小化。 性能测试已在我的计算机上完成(localhost)。也许对于更大的服务器,我不会遇到这些问题吗?

你觉得我做得好吗?你有更好的主意吗?

非常感谢你。

编辑:我更改了代码,只检查了不太远的食物。服务器最大约为35-50FPS

1 个答案:

答案 0 :(得分:1)

你的算法的复杂性是O(n!),这就是为什么它会减慢大量食物的速度。除非你的目标是让玩家在一个大世界中移动,否则你的方法似乎很好。优化您的实现的一种方法是将我的世界划分为瓷砖,每个瓷砖包含对其中食物的参考。然后,您可以快速获取可能在范围食物中的列表,这样您就无法检查播放器与距离太远的食物之间的距离。