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);
                            }
                        }
                    }
                }
            }
        }

クラス Tile を持つこの他のディクショナリを保持するこのクラス Map があります。各タイルは 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 つのネストされたループではなく、1 つのループを使用できるようになります。役立つ場合とそうでない場合があります。しかし、それが役立つことを願っています。

于 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 に答える