C# 基于XNA瓷砖的游戏:使用二维阵列中的网格位置检查两个对象之间的碰撞

C# 基于XNA瓷砖的游戏:使用二维阵列中的网格位置检查两个对象之间的碰撞,c#,multidimensional-array,collision-detection,xna-4.0,C#,Multidimensional Array,Collision Detection,Xna 4.0,我想知道是否有人能帮我找出如何检查二维数组中两个对象之间的碰撞 我想做一个简单的2D自上而下的游戏。地图由20x20二维正方形阵列组成。玩家和敌人都是方格,每个人都占据方格内的一个方格。网格由多个不同类型的正方形组成。到目前为止,我有地板方格(玩家和敌人可以移动),墙壁方格(玩家和敌人不能移动过去或移动),然后是敌人和玩家方格。以下是它的屏幕截图: 我在游戏类中创建并初始化2D数组。使用0-3中的数字,我可以选择每个正方形包含的内容: 0-楼层广场1-墙壁广场2-敌人广场3-玩家广场 首先,我

我想知道是否有人能帮我找出如何检查二维数组中两个对象之间的碰撞

我想做一个简单的2D自上而下的游戏。地图由20x20二维正方形阵列组成。玩家和敌人都是方格,每个人都占据方格内的一个方格。网格由多个不同类型的正方形组成。到目前为止,我有地板方格(玩家和敌人可以移动),墙壁方格(玩家和敌人不能移动过去或移动),然后是敌人和玩家方格。以下是它的屏幕截图:

我在游戏类中创建并初始化2D数组。使用0-3中的数字,我可以选择每个正方形包含的内容: 0-楼层广场1-墙壁广场2-敌人广场3-玩家广场

首先,我让玩家通过使用嵌套的for循环,检查玩家的上、下、左、右网格位置,查看2D数组中的值是否为1,从而与墙方块发生碰撞。如果它不是,那么这意味着它不是一堵墙,这意味着玩家可以移动

但是,在检查玩家和敌人之间的碰撞时,我不能使用这种方法,因为我只使用2D数组(2和3)中的值来选择最初绘制敌人和玩家方块的位置。这意味着它们在任何时候当前所在的栅格位置都包含值0

我想我会通过存储每个玩家和敌人对象的“网格位置”来实现这一点。这样我就可以检查玩家周围的每个格挡,看它是否等于敌人的格挡位置。如果它是相等的,那么我会将我用来在那个特定方向上移动玩家的移动向量设置为(0,0),以防止他们在那个方向上移动。当敌人不再在玩家的一个区块内时,移动向量将返回其原始值

我在这方面取得了一些成功,但它似乎只适用于一个敌方目标。有一个敌人我不能从任何角度穿过,但有其他敌人我可以直接穿过他们

注意:屏幕最远的敌人似乎是玩家方格唯一可以与之碰撞的敌人

我使用了断点,我可以看到,当我接近我能通过的任何敌人时,它确实会进行检查,看看玩家旁边的方块是否是敌人,但它实际上并不能阻止玩家穿过敌人

所以我的问题是,我是不是把碰撞弄错了,有没有更简单的方法?或者,也许我的代码中有一个错误阻止了它的工作

下面是我的一些代码:

第一个示例用于玩家/敌人碰撞。这是包含在敌人类中的。如前所述,我使用玩家和敌人的网格位置来检查他们是否在一个正方形内,如果在一个正方形内,那么我将玩家的移动向量设置为0,0。当它们不再在彼此的一个正方形内时,我将运动向量重置回其原始值

public void CheckCollision(Player playerObject)
    {
        //Check above player
        if (playerObject.PlayerGridPosition.Y - 1 == gridPosition.Y && playerObject.PlayerGridPosition.X == gridPosition.X)
        {
            //north is a vector2 variable that I use to add to the players position in order to move them about the screen. I use it to update both the players position
            //and the grid position. North, South, East and West are all similar except the values contained in each are for a specific direction
            playerObject.north.X = 0;
            playerObject.north.Y = 0;
            //This bool is used to check for when an enemy is beside and no longer beside the player.
            besidePlayer = true;
        }
        //Check below player
        if (playerObject.PlayerGridPosition.Y + 1 == gridPosition.Y && playerObject.PlayerGridPosition.X == gridPosition.X)
        {
            playerObject.south.X = 0;
            playerObject.south.Y = 0;
            besidePlayer = true;
        }
        //Check to right of player
        if (playerObject.PlayerGridPosition.Y == gridPosition.Y && playerObject.PlayerGridPosition.X + 1 == gridPosition.X)
        {
            playerObject.east.X = 0;
            playerObject.east.Y = 0;
            besidePlayer = true;
        }
        //This if statement just checks to see if any of the enemies are within a squares space of the player, if they are not then the besidePlayer bool is set to false
        else if (playerObject.PlayerGridPosition.Y != gridPosition.Y && playerObject.PlayerGridPosition.X + 1 != gridPosition.X && playerObject.PlayerGridPosition.Y - 1 != gridPosition.Y && playerObject.PlayerGridPosition.X != gridPosition.X && playerObject.PlayerGridPosition.Y + 1 != gridPosition.Y && playerObject.PlayerGridPosition.X != gridPosition.X)
        {
            besidePlayer = false;
        }
        //When an enemy is no longer beside the player then we can reset all the North, South, East and West vector velues back to their original values.
        if (besidePlayer == false)
        {
            playerObject.north.X = 0;
            playerObject.north.Y = -1;

            playerObject.south.X = 0;
            playerObject.south.Y = 1;

            playerObject.east.X = 1;
            playerObject.east.Y = 0;
        }
    }
下一段代码用于在2D数组中设置值并创建标高布局。这也是我创建敌人对象并设置玩家对象位置和网格位置的地方,使用网格上特定“数字”的行、列来选择绘制它们的位置

注意:行和列是翻转的,否则级别将被侧向绘制

public void LoadLevels(int level)
    {
        //More levels will be added in later.
        if(level == 1)
        {
            //Here I set the values inside the 2D array "grid". It is a 20x20 array.
            //0 = Floor Square, 1 = Wall square, 2 = Enemy Square, 3 = Player Square
            grid = new int[maxRows, maxCols]
            {
                {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
                {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
                {1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1},
                {1,0,1,0,0,0,0,1,0,1,1,0,0,0,0,0,0,0,0,1},
                {1,0,1,0,1,1,0,1,0,1,1,0,1,1,1,1,1,1,0,1},
                {1,0,1,2,1,1,0,1,0,1,1,0,0,0,0,0,0,0,0,1},
                {1,0,1,0,1,1,0,1,0,0,0,0,1,1,1,0,1,1,1,1},
                {1,0,1,0,1,1,0,1,0,1,1,0,0,0,0,0,0,0,0,1},
                {1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,1,1},
                {1,1,1,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1},
                {1,0,0,0,0,0,0,0,0,1,1,1,0,1,1,1,1,1,0,1},
                {1,1,1,1,1,1,1,1,0,0,0,3,0,0,0,2,0,0,0,1},
                {1,0,1,0,0,0,0,1,0,1,0,1,0,1,0,1,1,1,0,1},
                {1,2,1,0,1,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1},
                {1,0,1,0,1,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1},
                {1,0,1,2,1,1,0,1,0,1,0,1,0,1,0,0,0,0,0,1},
                {1,0,1,0,1,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1},
                {1,0,1,0,1,1,0,1,0,0,0,1,0,1,0,1,0,1,0,1},
                {1,0,0,0,0,0,0,0,0,1,0,1,0,1,0,1,1,1,0,1},
                {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}
            };
            //Cycle through the array with a nested if
            for (int i = 0; i < maxCols; i++)
            {
                for (int j = 0; j < maxRows; j++)
                {
                    //If the the value at grid[i, j] is a 2 then create an enemy at that position
                    if (grid[i, j] == 2)
                    { 
                        enemyList.Add(new Enemies(Content.Load<Texture2D>("redSquare"), new Vector2(j * squareWidth, i * squareHeight), new Vector2(j, i)));
                        //Reset the value at this position to 0 so that when the player/enemy moves from this spot, a floor tile will be drawn instead of a blank space.
                        grid[i, j] = 0;  
                    }
                    //If the value is 3 then set the players position and grid position to the value based of [i, j] values.
                    if (grid[i, j] == 3)
                    {
                        playerObject.PlayerPosition = new Vector2(i * squareWidth, j * squareHeight);
                        playerObject.PlayerGridPosition = new Vector2(i, j);
                        grid[i, j] = 0;
                    }
                }
            }

        }
        if (level == 2)
        {
        }
    }
public void加载级别(int级别)
{
//稍后将添加更多级别。
如果(级别==1)
{
//这里我设置了2D数组“grid”中的值。它是一个20x20数组。
//0=地板广场,1=墙壁广场,2=敌人广场,3=玩家广场
grid=newint[maxRows,maxCols]
{
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1},
{1,0,1,0,0,0,0,1,0,1,1,0,0,0,0,0,0,0,0,1},
{1,0,1,0,1,1,0,1,0,1,1,0,1,1,1,1,1,1,0,1},
{1,0,1,2,1,1,0,1,0,1,1,0,0,0,0,0,0,0,0,1},
{1,0,1,0,1,1,0,1,0,0,0,0,1,1,1,0,1,1,1,1},
{1,0,1,0,1,1,0,1,0,1,1,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,1,1},
{1,1,1,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,1,1,1,0,1,1,1,1,1,0,1},
{1,1,1,1,1,1,1,1,0,0,0,3,0,0,0,2,0,0,0,1},
{1,0,1,0,0,0,0,1,0,1,0,1,0,1,0,1,1,1,0,1},
{1,2,1,0,1,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1},
{1,0,1,0,1,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1},
{1,0,1,2,1,1,0,1,0,1,0,1,0,1,0,0,0,0,0,1},
{1,0,1,0,1,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1},
{1,0,1,0,1,1,0,1,0,0,0,1,0,1,0,1,0,1,0,1},
{1,0,0,0,0,0,0,0,0,1,0,1,0,1,0,1,1,1,0,1},
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}
};
//使用嵌套的if循环遍历数组
对于(int i=0;iloading () {
    load level to array, no need to perform additional modification
}
game_update () {
    for each tile within the array {
        if ( tile is player ) {
            read user's input
            temp <- compute the next position of the player
            if ( temp is floor ) then { current player position <- temp } // move allowed, update its position
            else { the player must stay on its current position } // move rejected
        }
        if ( tile is enemy ) {
            temp <- compute the next position of this enemy
            if ( temp is floor ) then { this enemy position <- temp } // move allowed, update its position
            else { this enemy must stay on its current position } // move rejected
        }
    }
}
game_draw () {
    for each tile within the array {
        draw the current tile
    }
}