0

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

这是我的 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 类的字典,每个图块都用 X、Y 和 Z 坐标表示,每个图块都包含一个名为 Player 的类的列表,有些图块有玩家,有些则没有。

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

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

4

2 回答 2

1

Player如果您还没有这样做,我认为在您的班级中引用瓷砖会很聪明,然后将所有玩家传递给该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 个嵌套循环。你可能会也可能不会觉得它有用。但我希望它有所帮助。

于 2014-10-14T05:37:12.927 回答
0

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

if
x1=100,y1=100,z=7 and r=11

then
(x-x1)^2+(y-y1)^2+(z-z1)^2=r^2.

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

于 2014-10-14T05:20:54.813 回答