我已经尝试了我在网上找到的每一种方式来获得相对于相机的鼠标位置,但没有任何方法可行.选择图块总是远离鼠标.另外,我如何只更改我点击的图块而不是每个具有相同纹理的图块
相机类
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);
}
Game1 Draw
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);
}
解决方法:
可能有更好的方法,但是:
// 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;