在随机生成的图块上执行鼠标拾取的最佳方法

时间:2012-03-29 01:30:48

标签: c# xna mouse picking

我的主要问题是我不明白如何获取生成的图块的位置或如何判断鼠标的位置。我应该使用碰撞来检测鼠标或其他东西吗?我可以采取哪些措施来优化我的代码并使其更容易获得像位置

这样的东西

我从我的代码中取出了一些内容,比如加载纹理只是为了让它们更短,因为这不是问题的一部分。

我的平铺代码

    public Block[] tiles = new Block[3];
    public int width, height;
    public int[,] index;
    public Rectangle tileRect;

public void Load(ContentManager content)
    {
        tiles[0] = new Block { Type = BlockType.Grass, Position = Vector2.Zero, texture = grass};
        tiles[1] = new Block { Type = BlockType.Dirt, Position = Vector2.Zero, texture = dirt};

        width = 50;
        height = 50;

        index = new int[width, height];

        Random rand = new Random();
        for (int x = 0; x < width; x++)
        {
            for (int y = 0; y < height; y++)
            {
                index[x,y] = rand.Next(0,2);
            }
        }
    }

    public void Draw(SpriteBatch spriteBatch)
    {
        for (int x = 0; x < width; x++)
        {
            for (int y = 0; y < height; y++)
            {
                    spriteBatch.Draw(tiles[index[x,y]].texture, tileRect = new Rectangle(x * 64, y * 64, 64, 64), 
                        Color.White);          
            }
        }  
    }

阻止属性代码

public enum BlockType
{
    Dirt,
    Grass,
    Selection
}

public class Block
{
    public BlockType Type { get; set; }
    public Vector2 Position { get; set; }
    public Texture2D texture { get; set; }
}

2 个答案:

答案 0 :(得分:1)

在XNA Update功能中,您可以使用Mouse.GetState()获取鼠标位置,它将为您提供鼠标的X和Y坐标属性。只需按照您的图块大小划分它们并向下舍入(向下)以获得最接近的图块坐标索引。

已添加代码

public static Vector2 GetGridCoordinates(MouseState mouseState, int gridSize){
    return new Vector2(
        (int)Math.Floor(mouseState.X / gridSize),
        (int)Math.Floor(mouseState.Y / gridSize)
    );
}

你甚至可以将它作为MouseState类的扩展函数,所以你需要做的就是:

Vector2 gridCoords = Mouse.GetState().GetGridCoordinates(MyGridSize);

但我可能会过度思考......

答案 1 :(得分:1)

这段代码可以解决问题。您可以在tile生成类中添加此方法。 (未经测试)

public bool IsMouseInsideTile(int x, int y)
{
    MouseState MS = Mouse.GetState();
    return (MS.X >= x * 64 && MS.X <= (x + 1) * 64 &&
        MS.Y >= y * 64 && MS.Y <= (y + 1) * 64);
}

您可以根据自己的需要编辑此功能。

修改 我会稍微解释一下这段代码。

  • Mouse.GetState()获取鼠标的当前位置,为Vector2

  • 图块[a ,b]位于[a * 64, b * 64]位置,正如您的绘图方法所示

  • 图块的最大x和y坐标位于[(a + 1) * 64, (b + 1) * 64],因为纹理为64 by 64 pixels尺寸。

  • 我检查鼠标是否在每个瓷砖内。如果您愿意,可以添加MouseHover事件。

更多修改: 根据您的评论编辑了我的代码。

更多修改: 以下是Draw方法的代码:

public void Draw(SpriteBatch spriteBatch)
    {
        for (int x = 0; x < width; x++)
        {
            for (int y = 0; y < height; y++)
            {
                    spriteBatch.Draw(tiles[index[x,y]].texture, tileRect = new Rectangle(x * 64, y * 64, 64, 64), 
                        Color.White);
                    if(IsMouseInsideTile(x, y))
                        spriteBatch.Draw(selected.texture, tileRect = new Rectangle(x * 64, y * 64, 64, 64), 
                                        Color.White);
            }
        }  
    }