I'm creating a game in XNA similar to Minecraft - Minecraft 2D
It looks like this
Here's how it works:
All blocks are generated once with fixed x,y coordinates and just re-drawn.
//generate world
for (int i = 0; i < 25; i++)
{
blocks.Add(new Block("top", i * 32, 32 * 7, Color.White));
for (int j = 8; j < 20; j++)
{
blocks.Add(new Block("dirt", i * 32, 32 * j, Color.White));
}
}When user clicks on a block, I just browse through all blocks and check whether block exists.
if ((mouseCoordinate.X - (mouseCoordinate.X % 32)) == block.x && (mouseCoordinate.Y - (mouseCoordinate.Y % 32)) == block.y) {
//destroy block
}Currently, without any camera movements, everything works. When I move my camera just about 32px to the right, for example, it's all broken. I can't do previous step anymore.
- What I need: I need to get mouse position relative to the map, not to the game window. How can I get mouse position relative to the map? Basically, I want mouse position 0,0 on the point I have circled here
How do I calculate it?
EDIT: here's my camera class (yes, Matrix)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using System.Reflection;
namespace MojePrvniHra
{
public class Camera2d
{
protected float _zoom; // Camera Zoom
public Matrix _transform; // Matrix Transform
public Vector2 _pos; // Camera Position
protected float _rotation; // Camera Rotation
public Camera2d()
{
_zoom = 1.0f;
_rotation = 0.0f;
_pos = Vector2.Zero;
}// Sets and gets zoom
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; }
}
// Auxiliary function to move the camera
public void Move(Vector2 amount)
{
_pos += amount;
}
// Get set position
public Vector2 Pos
{
get { return _pos; }
set { _pos = value; }
}
public Matrix get_transformation(GraphicsDevice graphicsDevice)
{
_transform =
Matrix.CreateTranslation(new Vector3(-_pos.X, -_pos.Y, 0)) *
Matrix.CreateRotationZ(_rotation) *
Matrix.CreateScale(new Vector3(Zoom, Zoom, 1)) *
Matrix.CreateTranslation(new Vector3(graphicsDevice.Viewport.Width * 0.5f, graphicsDevice.Viewport.Height * 0.5f, 0));
return _transform;
}
}
}
and here's how I start my spriteBatch
spriteBatch.Begin(SpriteSortMode.BackToFront,
BlendState.AlphaBlend,
null,
null,
null,
null,
cam.get_transformation(graphics.GraphicsDevice));
Answer
Solution
Is your camera simulated using a view matrix? If so, all you need to do is:
Vector2 worldPosition = Vector2.Transform(mousePosition, Matrix.Invert(viewMatrix));
And if you're not using a view matrix... you should :-)
Explanation
The view matrix transforms coordinates from world space into view space. The inverse of this matrix does the opposite - it transforms coordinates from view space back into world space.
Since your mouse coordinates are defined in view space, all you need to do is transform them with the inverse view matrix to convert them into world space.
No comments:
Post a Comment