从给定半径内的X、Y、Z数组中获取数据

本文关键字:数组 数据 获取 | 更新日期: 2023-09-27 18:26:27

我正在开发一个游戏服务器,目前我需要能够在一个区域内吸引观众,但我担心我使用的服务器非常丑陋和"慢",但我还没有遇到任何性能问题,因为我正在本地测试它,而不是在实时服务器上。

这是我的GetSpectators函数:

public void GetSpectators(ref HashSet<Player> Players, Coordinate_t coordinate, bool MultiFloor = false)
        {
            for (int x = coordinate.X - 11; x != coordinate.X + 11; x++)
            {
                for (int y = coordinate.Y - 11; y != coordinate.Y + 11; y++)
                {
                    if (MultiFloor)
                    {
                        for (int z = coordinate.Z - 2; z != coordinate.Z + 2; z++)
                        {
                            Tile tile = GetTile(x, y, z);
                            if (tile != null)
                            {
                                foreach (Player p in tile.Creatures)
                                {
                                    Players.Add(p);
                                }
                            }
                        }
                    }
                    else
                    {
                        Tile tile = GetTile(x, y, coordinate.Z);
                        if (tile != null)
                        {
                            foreach (Player p in tile.Creatures)
                            {
                                Players.Add(p);
                            }
                        }
                    }
                }
            }
        }

我有一个类Map,它包含了另一个字典和类Tile,每个Tile都用X、Y和Z坐标表示,每个Tile都包含一个名为Player的类列表,有些Tile有玩家,有些没有。

我需要一个好的方法而不是丑陋的得到例如:

例如,半径11内x=100,y=100,z=7的所有玩家。

从给定半径内的X、Y、Z数组中获取数据

我认为如果你还没有在Player类中引用tile,然后将所有参与者传递给GetSpectators()方法是明智的。。。

类似。。。

public class Player
{
    // a reference to the tile that the player is currently on.
    public Tile CurrentTile { get; set; }
}

这将允许你循环浏览玩家,而不是这么多瓦片。而且,在没有所有循环嵌套的情况下,以你想要的方式找到玩家应该更干净、更高效。例如:

public List<Player> GetSpectators(Hashset<Player> playersInGame, Coordinate coord)
{
    var playersInRange = new List<Player>();
    // iterate through each player.
    foreach (var p in playersInGame)
    {
        // check if the tile the player is sitting on is in range of radius given.
        if ((p.CurrentTile.X < coord.X + 6 || p.CurrentTile.X > coord.X - 6)
            &&
            (p.CurrentTile.Y < coord.Y + 6 || p.CurrentTile.Y > coord.Y - 6))
        {
            // Player is within radius.
            playersInRange.Add(p);
        }
    }
    return playersInRange;
}

您可以添加对Z坐标和任何其他条件语句的额外检查。但正如您所看到的,这将允许您使用一个循环,而不是3个嵌套循环。你可能觉得它有用,也可能不有用。但我希望它能有所帮助。

您可以使用圆方程来检查玩家是否位于其他玩家的给定半径内,即

if
x1=100,y1=100,z=7 and r=11
then
(x-x1)^2+(y-y1)^2+(z-z1)^2=r^2.

任何满足这个方程的点都将位于该区域中。