c# - XNA 使用 2D 相机查找鼠标位置

标签 c# xna camera mouse tile

我已经尝试了我在网上找到的所有方法来获取鼠标相对于相机的位置,但没有任何效果。选择图 block 总是远离鼠标绘制。另外,我如何只更改我点击的图 block 而不是每个具有相同纹理的图 block

相机类

public class Camera : Game1
{
    protected float _zoom;
    public Matrix _transform;
    public Vector2 _pos;
    protected float _rotation;

    public Camera()
    {
        _zoom = 1.0f;
        _rotation = 0.0f;
        _pos = Vector2.Zero;
    }

    public float Zoom
    {
        get { return _zoom; }
        set { _zoom = value; if (_zoom < 0.1f) _zoom = 0.1f; } // Negative zoom will flip image
    }

    public float Rotation
    {
        get { return _rotation; }
        set { _rotation = value; }
    }


    public void Move(Vector2 amount)
    {
        _pos += amount;
    }

    public Vector2 Pos
    {
        get { return _pos; }
        set { _pos = value; }
    }

    public Matrix get_transformation()
    {
        _transform = 
                     Matrix.CreateTranslation(new Vector3(-_pos.X, -_pos.Y, 0)) *
                     Matrix.CreateRotationZ(Rotation) *
                     Matrix.CreateScale(_zoom) *
                     Matrix.CreateTranslation(new Vector3(1024 * 0.5f, 768 * 0.5f, 0));
        return _transform;
    }

    public void Update()
    {
        Input();
    }

    protected virtual void Input()
    {
        KeyboardState _keyState;
        _keyState = Keyboard.GetState();

        if (_keyState.IsKeyDown(Keys.A))
        {
            _pos.X -= 5f;
        }
        if (_keyState.IsKeyDown(Keys.D))
        {
            _pos.X += 5f;
        }
        if (_keyState.IsKeyDown(Keys.W))
        {
            _pos.Y -= 5f;
        }
        if (_keyState.IsKeyDown(Keys.S))
        {
            _pos.Y += 5f;
        }
    }
}

瓷砖类

class TileGeneration
{
    public Block[] tiles = new Block[3];
    public int width, height;
    public int[,] index;
    public Texture2D grass, dirt, selection;
    bool selected;
    MouseState MS;
    Vector2 mousePos;

    Camera camera;

    public TileGeneration()
    {

    }

    public void Load(ContentManager content, GraphicsDevice g)
    {
        grass = content.Load<Texture2D>(@"Tiles/grass");
        dirt = content.Load<Texture2D>(@"Tiles/dirt");
        selection = content.Load<Texture2D>(@"Tiles/selection");

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

        camera = new Camera();

        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 Update()
    {
        MS = Mouse.GetState();
        Matrix inverseViewMatrix = Matrix.Invert(camera.get_transformation());
        Vector2 mousePosition = new Vector2(Mouse.GetState().X, Mouse.GetState().Y);
        Vector2 worldMousePosition = Vector2.Transform(mousePosition, inverseViewMatrix);
        mousePos = worldMousePosition;
        Console.WriteLine(mousePos);

        if (MS.LeftButton == ButtonState.Pressed)
        {
            Console.WriteLine("Selected");
            selected = true;
        }
    }

    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, new Rectangle(x * 64, y * 64, 64, 64), 
                    Color.White);
              if (selected && IsMouseInsideTile(x, y))
              {
                  if (tiles[index[x,y]].texture == grass)
                      tiles[index[x,y]].texture = dirt;
              }
              if(IsMouseInsideTile(x, y))
                  spriteBatch.Draw(selection, new Rectangle(x * 64, y * 64, 64, 64), Color.White);
            }
        }    
    }

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

游戏1平局

protected override void Draw(GameTime gameTime)
    {
        GraphicsDevice.Clear(Color.CornflowerBlue);

        spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, null, null, null, null, 
            camera.get_transformation());

        tile.Draw(this.spriteBatch);
        player.Draw(this.spriteBatch);
        spriteBatch.End();

        base.Draw(gameTime);
    }

enter image description here

最佳答案

可能有更好的方法,但是:

// absoluteMouseX will be the value from your MouseState, and camera will be an instance of your class
// You may need to convert your rotation to radians.

float relativeMouseX = absoluteMouseX + camera.Pos.X;

float relativeMouseY = absoluteMouseY + camera.Pos.Y;

关于c# - XNA 使用 2D 相机查找鼠标位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10001277/

相关文章:

c# - 表达式方法,大于如何实现

C# 数学,碰撞检测,xna

c# - XNA 游戏在非常奇怪的情况下无法启动

Android翻转前置摄像头后视镜翻转视频

c# - 在 Visual Studio 2010 或更高版本中粘贴重复 ID 时,我可以更改控件的自动命名吗

c# - 如何以编程方式向 contentPlaceHolder 添加内容?

c# - 如何将重复的监视器检测为单独的屏幕

c# - XNA 框架 "Vector2"问题。 *第一个节目...*

camera - libGDX - 透视相机和视野

ios - AVCapture 在 iOS 7 中以 60 fps 捕获和获取帧缓冲区