我正在构建我的第一个在线多人游戏,并试图找出找到特定范围内所有玩家的最佳方式。
我环顾四周;所有其他解决方案都基于内置测距的游戏引擎API。每位玩家都有一对原始的x,y
坐标。
我想到的第一件事是:循环遍历服务器上的每个用户并过滤掉范围内的用户 - 只需使用毕达哥拉斯定理 - 但我知道必须有更好的方法来实现它。
我想到的最好的事情是将地图分成大约100(10 x 10)的部分,并将用户分成相应的部分。然后,我可以获取用户所在的部分,而不是循环遍历服务器上的每个用户,循环遍历9个方格内的每个用户(3x3,用户部分以及围绕它的所有其他用户)。
我确信这比简单地在整个服务器上循环1000次更好但是有一种标准的方法,或者这是如何完成的?
我想在客户端和服务器端保持精简。
答案 0 :(得分:0)
是的,你想到的是渐近最优的,因为它是每个玩家的恒定操作次数,除非它们在相同的象限中彼此靠近。为了避免为数组分配大量内存,可以使用(hashset / table / dictionary)和散列函数将x,y映射到x /距离,y /距离,这样你就可以检查字典是否有周围输入然后检查相关玩家距离内的玩家的条目。
This video谈到一个几乎同构的问题:用一堆圆圈命中检测。虽然在视频中,你不能在同一个地方拥有一堆圆圈。
如果您正在寻找更简单的优化,您可以先检查其他玩家的x和y是否都在相关玩家的x和y范围内,然后再检查差异的平方和。 x和y小于您要检查的距离的平方。
对此的一些psudocode将是:
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