【问题标题】:Finding things with-in range寻找范围内的东西
【发布时间】:2016-08-28 00:46:09
【问题描述】:

我正在构建我的第一个在线多人游戏,并试图找出找到特定范围内所有玩家的最佳方法。

我环顾四周;所有其他解决方案都基于内置测距功能的游戏引擎 API。

每个玩家都有一个原始的x,y 坐标对。

我想到的第一件事是:遍历服务器上的每个用户并过滤掉范围内的用户 - 只需使用毕达哥拉斯定理 - 但是我知道必须有更好的方法来做到这一点。

我想到的最好的事情是将地图分成大约 100 (10 x 10) 的部分,并将用户相应地放置到部分中。然后我可以获取用户所在的部分,而不是遍历服务器上的每个用户,而是遍历 9 个方格内的每个用户(3x3,用户部分及其周围的所有其他部分)。

我确信这比简单地每秒循环遍历整个服务器 1000 次要好,但有没有标准的方法,或者它是如何完成的?

我想在客户端和服务器端都保持精简。

【问题讨论】:

    标签: algorithm server range game-engine game-physics


    【解决方案1】:

    是的,您的想法是渐近最优的,因为它是每个玩家的恒定操作次数,除非他们都在同一个象限中彼此靠近。为了避免为数组分配大量内存,您可以使用 (hashset / table / dictionary) 和将 x、y 映射到 x / distance、y / distance 的散列函数,以便检查字典是否有周围条目,然后检查相关玩家距离内的玩家的条目。

    This video 谈到了一个几乎同构的问题:用一堆圆圈进行命中检测。虽然在视频中,你不能在同一个地方有一堆圈子。

    如果您正在寻找更简单的优化,您可以先检查其他玩家的 x 和 y 是否都在相关玩家的 x 和 y 范围内,然后再检查 x 和y 小于您要检查的距离的平方。

    一些伪代码是:

    distance = 100
    sections = {}
    
    # initial setup
    for player in players:
        section_x = player.x / distance
        section_y = player.y / distance
        index = [section_x, section_y]
        if !sections.get(index):
            sections[index] = []
        sections[index].push(player)
    
    def players_near(player):
        nearby_players = []
        section_x = player.x / distance
        section_y = player.y / distance
        for section_dx in -1..1:
            for section_dy in -1..1:
                index = [section_x + section_dx, section_y + section_dy]
                players = sections[index]
                if players:
                    nearby_players.extend(players)
    
        result = []
        for nearby_player in nearby_players:
            dx = abs(player.x - nearby_player.x)
            dy = abs(player.y - nearby_player.y)
            if dx <= distance and dy <= distance and sqr(dx) + sqr(dy) < sqr(distance):
                result.push(nearby_player)
    
        return result
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-13
      • 2019-07-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-24
      相关资源
      最近更新 更多