javascript - 实时多人游戏-区域广播

标签 javascript node.js performance sockets

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

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

为了简约,服务器具有以下数组:

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

让我们在一个大 map (就像agar.io)中生成 1000 种食物,位于服务器的server.foods数组中。玩家只需要知道其视口(viewport)中食物的状态(假设200 个可见食物)。因此,服务器仅向玩家发送包含 200 个可见食物(id + 位置)的一个数据包。然后,为了让服务器知道,我们将 200 个可见食物推送到 Player 对象的数组中 (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),性能非常糟糕,但带宽却被最小化。 性能测试是在我的计算机(本地主机)上完成的。也许使用更大的服务器,我不会遇到这些问题?

你认为我的做法好吗?你有更好的主意吗?

非常感谢。

编辑:我更改了代码以仅检查不太远的食物。服务器最高可达约 35-50FPS

最佳答案

你的算法的复杂度是 O(n!),这就是为什么它会因为大量的食物而变慢。除非你的目标是让玩家在一个大世界中移动,否则你的方法看起来不错。对我有用的优化实现的一种方法是将您的世界划分为图 block ,每个图 block 都包含对其内部食物的引用。然后,您可以快速获取可能在范围内的食物列表,这样您就无需检查玩家与距离太远的食物之间的距离。

关于javascript - 实时多人游戏-区域广播,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38820103/

相关文章:

javascript - 通过 Symfony2 Controller 将记录从数据库中提取到 javascript

node.js - 如何将此mongodb对象转换为普通版本?

javascript - 在 Express/Jade 模板内的 Javascript 函数中访问 JSON 数据时出现问题

Javascript一次请求多个JS文件

mysql - MySQL 有没有一种方法可以将多个查询合并到同一个表中,以便在自己的行中获得不同的结果?

python - 在没有设置的情况下更快地获得两个列表的差异

javascript - 使用选定的表格行预填充选择下拉列表

javascript - 在 Vanilla 中切换风格

javascript - webgl 中的 VertexIndices 是什么?

node.js - Nodejs 浏览器同步 - 日志记录