从给定半径内的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的所有玩家。
我认为如果你还没有在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.
任何满足这个方程的点都将位于该区域中。