我尝试过在网上找到的每一种方式来获得相对于相机的鼠标位置,但没有任何效果。选择图块总是远离鼠标。另外,我如何只更改我点击的图块而不是每个具有相同纹理的图块
相机类
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);
}
答案 0 :(得分:3)
可能有更好的方法,但是:
// 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;
答案 1 :(得分:1)
我现在没有XNA来测试它,但我记得有这个问题。
我的代码片段可能有所帮助:
Vector2 mouse = new Vector2(ms.X, ms.Y);
Matrix transform = Matrix.Invert(camera.ViewMatrix);
Vector2.Transform(ref mouse, ref transform, out mouse);
selectedRow = (int)(mouse.Y / Tile.SIZE);
if (selectedRow < 0) selectedRow = 0;
else if (selectedRow >= rows) selectedRow = rows - 1;
selectedCol = (int)(mouse.X / Tile.SIZE);
if (selectedCol < 0) selectedCol = 0;
else if (selectedCol >= cols) selectedCol = cols - 1;
两件事:
1.注意行取决于鼠标的Y分量和X分量的列
2.请注意,直接获取鼠标放置的图块要快得多,而不是询问每个图块是否有鼠标“内部”。