获取鼠标在网格上的位置

时间:2016-04-22 09:59:23

标签: c# grid xna monogame

所以我一直坚持如何将我在monogame / XNA中的鼠标位置转换为我网格的位置。我想要实现的基本上是当我点击它们时,将网格中特定单元格上的矩形颜色更改为不同的颜色。

这是我第一次使用网格系统,但我并不知道如何做到这一点。

以下是我构建网格的方法。这里基本上发生的是我首先使用0填充网格中的每个单元格。根据我在Game1类的update方法中赋值的值,矩形的颜色会发生变化。

谢谢!

 public int[,] gridCell;
    Texture2D texture;
    public Rectangle rect;
    int col;
    int row;
    const int gridSize = 32;



    //Initializes the constructor
    public Grid(int sizeCol, int sizeRow)
    {
        //texture = sprite;
        col = sizeCol;
        row = sizeRow;
        gridCell = new int[col, row];

        for(int i = 0; i<col;i++)
        {
           for(int j = 0; j<row;j++)
            {
                gridCell[i, j] = 0;
            }
        }
    }


    public void Draw(SpriteBatch spritebatch)
    {
        for (int i = 0; i <= col-1; i++)
        {
            for (int j = 0; j <= row-1; j++)
            {
                if (gridCell[i, j] == 0)
                {
                    spritebatch.FillRectangle(i * 32, j * 32, 31, 31, Color.CornflowerBlue, 0f);
                    spritebatch.DrawRectangle(new Vector2(i * 32, j * 32), new Vector2(32, 32), Color.Black, 1f);
                }

                else if( gridCell[i,j] == 1)
                {
                    spritebatch.FillRectangle(i * 32, j * 32, 31, 31, Color.Yellow, 0f);
                    spritebatch.DrawRectangle(new Vector2(i * 32, j * 32), new Vector2(32, 32), Color.Black, 1f);
                }
                else if (gridCell[i, j] == 2)
                {
                    spritebatch.FillRectangle(i * 32, j * 32, 31, 31, Color.Red, 0f);
                    spritebatch.DrawRectangle(new Vector2(i * 32, j * 32), new Vector2(32, 32), Color.Black, 1f);
                }
                else if (gridCell[i, j] == 3)
                {
                    spritebatch.FillRectangle(i * 32, j * 32, 31, 31, Color.Purple, 0f);
                    spritebatch.DrawRectangle(new Vector2(i * 32, j * 32), new Vector2(32, 32), Color.Black, 1f);
                }
                else if (gridCell[i, j] == 4)
                {
                    spritebatch.FillRectangle(i * 32, j * 32, 31, 31, Color.Blue, 0f);
                    spritebatch.DrawRectangle(new Vector2(i * 32, j * 32), new Vector2(32, 32), Color.Black, 1f);
                }
                else if (gridCell[i, j] == 5)
                {
                    spritebatch.FillRectangle(i * 32, j * 32, 31, 31, Color.Black, 0f);
                    spritebatch.DrawRectangle(new Vector2(i * 32, j * 32), new Vector2(32, 32), Color.Black, 1f);
                }
            }
        }
    }

2 个答案:

答案 0 :(得分:2)

好的,这是怎么回事:让我们说你的网格的一个方格是8x8。鼠标的位置可以在8到0之间,你需要它只有0/8/16/24 / ...当你将鼠标位置除以8时(假设Mposition是4x20),你将得到0.5x2 .5,如果你将它乘以8,你将再次获得4x20, BUT :如果你截断除法结果,你将得到0x2,并且乘以8是0x16,所以(0x16)是鼠标所在的正方形的真实位置,0x2是鼠标的矩阵位置。这是一个简单的功能,可以满足您的需求:

public Vector2 PositionByGrid (int gridSize)
    {
        Vector2 result = new Vector2(MouseState.GetState().X, MouseState.GetState().Y);
        result.X = (int)(result.X / gridSize) * gridSize;
        result.Y = (int)(result.Y / gridSize) * gridSize;
        return result;
    }

此函数将返回方块的位置。如果您想要矩阵中的位置,只需添加result.X = (int)(result.X / gridSize);而不是result.X = (int)(result.X / gridSize) * gridSize;

修改:
正如@Slubberdegullion建议的那样,如果您的网格不是正方形,而是矩形(矩阵的原理相同),这里是函数:

public Vector2 PositionByGrid (int gridWidth, int gridHeight)
    {
        Vector2 result = new Vector2(MouseState.GetState().X, MouseState.GetState().Y);
        result.X = (int)(result.X / gridWidth) * gridWidth;
        result.Y = (int)(result.Y / gridHeight) * gridHeight;
        return result;
    }



编辑2: 这是一个建议 此外,您可以缩短Draw功能,看起来像这样(建议2中的解释):

public void Draw(SpriteBatch spritebatch)
{
    for (int i = 0; i <= col-1; i++)
    {
        for (int j = 0; j <= row-1; j++)
        {
            Color newColor;
            switch(gridCell[i, j])
            {
                case 0: newColor = Color.CornflowerBlue; break;
                case 1: newColor = Color.Yellow; break;
                case 2: newColor = Color.Red; break;
                case 3: newColor = Color.Purple; break;
                case 4: newColor = Color.Blue; break;
                case 5: newColor = Color.Black; break;
                default: newColor = Color.White; break;
            }
            spritebatch.FillRectangle(i * 32, j * 32, 31, 31, newColor, 0f);
            spritebatch.DrawRectangle(new Vector2(i * 32, j * 32), new Vector2(32, 32), Color.Black, 1f);

        }
    }
}

确实,这将使用更多的RAM(相当于为游戏添加4个新的整数变量,因为颜色是Vector4 basicaly但是使用int而不是float)和CPU时间,但是这个成本非常低您的游戏完整性和可读性的成本。
建议No2:从你的代码中我得知我是一个初学者,并且据说,我觉得我的责任是告诉你不要在代码中重复相同的(一组)代码行。相反,创建一个函数/做我用Draw函数做的事情等等。你的方式,如果你到了必须改变1的东西,你将不得不在X位置改变它。那么如果你必须再次改变它,或者多次改变呢?通过将重复代码保存在一个函数中,当需要时,您将不得不仅在该函数中更改那一件事。

答案 1 :(得分:0)

在构建网格时为网格生成一系列碰撞矩形。

onActivityResult

然后对于Rectangle[,] gridRects = new Rectangle[row, col]; for (int i = 0; i < row; i++) { for (int j = 0; j < col; j++) { gridRects[i,j] = new Rectangle(i * gridSize, j * gridSize, gridSize, gridSize); } } 中的每一帧,检查碰撞

Update