2016-04-22 81 views
0

所以我被困在如何能够将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); 
       } 
      } 
     } 
    } 
+0

我不是太熟悉MonoGame,但你可能需要将鼠标光标的位置转换成游戏世界(网格)坐标系,这与其他游戏引擎相当常见,所以请牢记这一点。您需要测试鼠标位置是否在网格单元矩形中。为此,请查看[Rectangle.Contains方法](https://msdn.microsoft.com/en-us/library/microsoft.xna.framework.rectangle.contains.aspx)。然后,您可以对照您的网格单元测试鼠标的X/Y坐标。 –

+0

“更改网格中特定单元格上的矩形的颜色”但您只有1个矩形用于整个网格单元格?为什么不为每个单元格分配一个矩形并绘制这些矩形? – LibertyLocked

回答

2

好吧,这是怎么回事:让我们说你的网格的一个正方形是8x8。你的鼠标位置可以在8到0之间,你只需要0/8/16/24/...当你将鼠标位置除以8(让Mposition是4x20)时,你会得到0.5x2 .5,如果你乘以8,你会再次得到4x20,但是:如果你截断除法结果,你会得到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功能,看起来像这样(在建议NO2解释):

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

     } 
    } 
} 

这是事实,因为颜色是的Vector4 basicaly这将使用一些更多的RAM(相当于增加4个新的整数变量的比赛,但用int而不是float)和CPU时间,但是这个成本对于游戏完整性和可读性的代价是非常低的。
建议No2:从你的代码我发现我看到你是一个初学者,就这样说,我觉得我的义务是告诉你不要在代码中重复相同的(一组)代码行。相反,创建一个函数/做我的Draw函数/等等。你的方式,如果你到了必须改变一件事情的地步,你必须在X个地方改变它。那么如果你必须再次改变它,或者更多次呢?通过将重复代码保存在一个函数中,当需要出现时,您只能在该函数中更改那一个。

+1

这适用于宽度和高度相同的情况。否则,用适当的尺寸替换gridSize。如果你想知道你应该接受哪两种,这应该是被接受的答案。 – Slubberdegullion

+0

真棒,这比我需要的更多。感谢您帮助我解决这个问题! – Favonius

0

当您构建网格时,为您的网格生成一个碰撞矩形阵列。

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,检查碰撞

MouseState ms = Mouse.GetState(); 

for (int i = 0; i < row; i++) 
{ 
    for (int j = 0; j < col; j++) 
    { 
     if (gridRects.Contains(ms.X, ms.Y)) 
     { 
      // Mouse is on gridCell[i,j] 
     } 
    } 
}