Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/322.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 计算矩阵中各个方向连接的点之间的距离_C#_Unity3d_Matrix_Modular Arithmetic - Fatal编程技术网

C# 计算矩阵中各个方向连接的点之间的距离

C# 计算矩阵中各个方向连接的点之间的距离,c#,unity3d,matrix,modular-arithmetic,C#,Unity3d,Matrix,Modular Arithmetic,我正在尝试制作一个在线游戏,我想模拟一个四面八方相连的世界,就像“吃豆人”一样。当玩家越过地图的边界时,他将处于网格的另一边 到目前为止,我成功地构建了一个服务器,该服务器保存了一个10x10矩阵(我附加了一些作为参考),并使用一些模块化算法计算并向客户端发送给定玩家位置的地图的相应分幅 例如,假设“view_distance=2”,服务器会根据玩家的位置发送相应的磁贴: 我想我已经表达了我的观点,现在让我们面对我的问题 当客户机从服务器获取要渲染的分片列表时,它需要计算每个分片到播放器的

我正在尝试制作一个在线游戏,我想模拟一个四面八方相连的世界,就像“吃豆人”一样。当玩家越过地图的边界时,他将处于网格的另一边

到目前为止,我成功地构建了一个服务器,该服务器保存了一个10x10矩阵(我附加了一些作为参考),并使用一些模块化算法计算并向客户端发送给定玩家位置的地图的相应分幅

例如,假设“view_distance=2”,服务器会根据玩家的位置发送相应的磁贴:

我想我已经表达了我的观点,现在让我们面对我的问题

当客户机从服务器获取要渲染的分片列表时,它需要计算每个分片到播放器的距离(单位向量),以便在正确的位置对其进行实例化。每个实例化的互动程序都有一个脚本,该脚本在玩家每次移动时都会重新计算与玩家的距离,因此当距离超过“查看距离”时,它会将自身摧毁

例如,如果客户机位于(9,5)位置,则平铺(7,7)的单位向量为(-2,2)

客户拥有以下信息:

  • 他站的位置:
    Globals.PlayerInfo.PlayerPosition
  • 地图的长度:
    Globals.map\u lenght
    (在本例中为10)
  • 视图距离:
    Globals.DATA\u distance
    (在本例中为2)
如何计算单位向量?我做了以下函数,但它似乎不起作用。我错过什么了吗

public static Position GetPlayerDistance(Position position)
    {
        var unitVector = new Position() { X = position.X, Y = position.Y };
        if (position.Y > Math.Truncate(Globals.PlayerInfo.PlayerPosition.Y) + Globals.DATA_DISTANCE)
        {
            unitVector.Y = position.Y - Globals.MAP_LENGHT;
        }

        if (position.X > Math.Truncate(Globals.PlayerInfo.PlayerPosition.X) + Globals.DATA_DISTANCE)
        {
            unitVector.X = position.X - Globals.MAP_LENGHT;
        }
        unitVector.X -= (float)Math.Truncate(Globals.PlayerInfo.PlayerPosition.X);
        unitVector.Y -= (float)Math.Truncate(Globals.PlayerInfo.PlayerPosition.Y);

        return unitVector;
    }

你自己说,电网是在各个方向连接的。所以,因为你的网格是“无限”的,所以每个位置都存在“无限”的次数。你要寻找的不是两点之间的距离,而是多个可能性中最小的一个

不过不用担心;)在每个方向(上、下、左、右)检查一次就足够了,并在这些方向上选择最小的结果距离,因为任何其他方向都会更远

这只是我所说的一个例子。 比方说

  • 播放机位于
    1,1
    (红色)
  • 敌人在
    8,2
    (蓝色)
因此,如果我们想得到X轴上的最小距离,我们只需在左右两个方向上进行检查

在这种情况下,找到左边的下一个位置很简单:它是实际的玩家位置
x=1

现在我们该怎么向右转呢?→ 我们只需扩展网格(浅灰色),并将玩家位置映射到扩展网格中的位置→ <代码>x=11(浅红色)

这是一个图像,以便更好地将其可视化

在代码中,这可能看起来像

public static Position GetPlayerDistance(Position position)
{
    // Get values local to not go through the accessors all the time
    Position playerPos = Globals.PlayerInfo.PlayerPosition;
    int playerX = (int)playerPos.X;
    int playerY = (int)playerPos.Y;

    int ownX = (int)position.X;
    int ownY = (int)position.Y;

    // On the X axis gather the next actual or virtual player position
    // where virtual means as if the grid was extended

    // Per default assume the positions are equal  
    var nextXLeft = ownX;
    var nextXRight = ownX;

    // Is the player actually left of us?
    if(playerX < ownX)
    {
        // Then trivial: the next left position is the actual one
        nextXLeft = playerX;
        // The next right position is a virtual one so we pretend
        // to extend the grid by the length and "copy" the player there
        nextXRight = Globals.MAP_LENGHT + playerX;
    } 
    // Or is the player actually right of us?
    else if (playerX > ownX)
    {
        // Just the other way round
        // this time the next position to the left is virtual
        nextXLeft = -Globals.MAP_LENGHT + playerX;
        // The next right position is the actual one
        nextXRight = playerX;
    }

    // Now we calculate the directed distances in both directions
    var distanceLeft = nextXLeft - ownX;
    var distanceRight = nextXRight - ownX;

    // use the Absolute only for comparing which is shorter
    var distanceX = Mathf.Abs(distanceRight) < Mathf.Abs(distanceLeft) ? distanceRight : distanceLeft;

    // And finally we want the smallest of both possible distances
    var distanceX = Mathf.Min(distanceLeft, distanceRight);

    // Repeat the same for the Y axis
    var nextYDown = ownY;
    var nextYUp = ownY;
    if(playerY < ownY)
    {
        nextYDown = playerY;
        nextYUp = Globals.MAP_LENGHT + playerY;
    } 
    else if (playerY > ownY)
    {
        nextYDown = -Globals.MAP_LENGHT + playerY;
        nextYUp = playerY;
    }

    var distanceDown = nextYDown - ownY;
    var distanceUp = nextYUp - ownY;

    var distanceY = Mathf.Abs(distanceUp) < Mathf.Abs(distanceDown) ? distanceUp : distanceDown;

    // Now you have a directed distance vector for both axis with the 
    // minimal absolute distance from the player
    return new Position(){ X = distanceX, Y = distanceY };
}
公共静态位置GetPlayerDistance(位置)
{
//获取本地值,使其不总是通过访问器
PlayerPosition=Globals.PlayerInfo.PlayerPosition;
intplayerx=(int)playerPos.X;
int playerY=(int)playerPos.Y;
int ownX=(int)position.X;
int ownY=(int)position.Y;
//在X轴上收集下一个实际或虚拟玩家位置
//其中虚拟意味着网格被扩展
//默认情况下,假设位置相等
var nextXLeft=ownX;
var nextXRight=ownX;
//球员真的离开我们了吗?
如果(playerXownX)
{
//正好相反
//这一次,左边的下一个位置是虚拟的
nextXLeft=-Globals.MAP_length+playerX;
//下一个正确的位置是实际位置
nextXRight=playerX;
}
//现在我们计算两个方向上的定向距离
var distanceLeft=nextXLeft-ownX;
var distanceRight=nextXRight-ownX;
//绝对值仅用于比较较短的值
var distanceX=Mathf.Abs(distanceRight)ownY)
{
nextYDown=-Globals.MAP_lengh+playerY;
下一步=玩耍;
}
var distanceDown=nextYDown-ownY;
var distanceUp=nextYUp-ownY;
var distanceY=Mathf.Abs(distanceUp)

下面是它现在工作原理的一点可视化



作为旁注:您可能已经想用它来代替您的自定义
位置

我需要知道方向。如果我使用你的代码,如果游戏者在(0,0)位置,你的函数的输出时间(8,8)应该是(2,2),但我需要它是(-2,-2)。谢谢你抽出时间来关注我的问题,我真的很感激:)@blacksmith在底部看到我的小更新;)我不确定方向的标志。。因此,您可能必须将顺序从
ownX-nextXLeft
etc更改为
nextXLeft-ownX
,具体取决于r的方向