I'm building a top down shooter but I have a little issue with my camera and mouse.
When I add the camera that I use to my game (see here) my mouse pointer seems to be in the wrong location.
When I call my Mouse.GetState().X
or Y
the location seems to be about 300 pixels off.
I've looked all over the net but I just can't find the solution.
I'm pretty new to coding, so I'll just post my main and my camera class. My objective is to get the green circle on the actual position of my mouse.
Camera class:
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;
namespace ZombieSurvival
{
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 = // Thanks to o KB o for this solution
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;
}
}
}
Game:
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;
//using Microsoft.Xna.Framework.Graphics.GraphicsDevice.SetCursorProperties;
namespace ZombieSurvival
{
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
int cursorX, cursorY;
Camera2D camera;
Player player;
Texture2D playertex;
Texture2D bulletTex;
Texture2D zombieTex;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
}
protected override void Initialize()
{
this.IsMouseVisible = true;
graphics.IsFullScreen = true;
graphics.ApplyChanges();
Mouse.SetPosition(0, 0);
cursorX = Window.ClientBounds.X + Mouse.GetState().X;
cursorY = Window.ClientBounds.Y + Mouse.GetState().Y;
//graphics.
base.Initialize();
}
protected override void LoadContent()
{
// Create a new SpriteBatch, which can be used to draw textures.
spriteBatch = new SpriteBatch(GraphicsDevice);
playertex = Content.Load <Texture2D>("player");
bulletTex = Content.Load<Texture2D>("bullet");
zombieTex = Content.Load<Texture2D>("zombie");
player = new Player(new Rectangle(100, 100, 50, 50), playertex, 5, bulletTex);
// TODO: use this.Content to load your game content here
}
protected override void UnloadContent()
{
// TODO: Unload any non ContentManager content here
}
protected override void Update(GameTime gameTime)
{
player.Update();
/*if (IsActive)
{
MouseState mouseState = Mouse.GetState();
int cx = graphics.GraphicsDevice.Viewport.Width / 2;
int cy = graphics.GraphicsDevice.Viewport.Height / 2;
int x = mouseState.X - cx;
int y = mouseState.Y - cy;
Mouse.SetPosition(cx, cy);
}*/
base.Update(gameTime);
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
Camera2D cam = new Camera2D();
cam.Pos = new Vector2(player.playerPosition.X, player.playerPosition.Y);
// cam.Zoom = 2.0f // Example of Zoom in
cam.Zoom = 0.5f; // Example of Zoom out
//// if using XNA 3.1
spriteBatch.Begin(SpriteBlendMode.AlphaBlend,
SpriteSortMode.Immediate,
SaveStateMode.SaveState,
cam.get_transformation(graphics.GraphicsDevice));
player.Draw(spriteBatch);
spriteBatch.Draw(zombieTex, new Rectangle(Mouse.GetState().X, Mouse.GetState().Y, 50, 50), Color.White);
// Draw Everything
// You can draw everything in their positions since the cam matrix has already done the maths for you
spriteBatch.End();
//Console.WriteLine(camera.Pos);
/*if (camera._pos.X - player.PlayerRect.X >= 100)
{
camera.Pos = new Vector2(camera.Pos.X - player._PlayerSpeed, camera.Pos.Y);
}
if (camera._pos.X - player.PlayerRect.X <= -300)
{
camera.Pos = new Vector2(camera.Pos.X + player._PlayerSpeed, camera.Pos.Y);
}
if (camera._pos.Y - player.PlayerRect.Y >= 0)
{
camera.Pos = new Vector2(camera.Pos.X, camera.Pos.Y - player._PlayerSpeed);
}
if (camera._pos.Y - player.PlayerRect.Y <= 250)
{
camera.Pos = new Vector2(camera.Pos.X, camera.Pos.Y + player._PlayerSpeed);
}*/
/*spriteBatch.Begin();
player.Draw(spriteBatch);
spriteBatch.End();*/
base.Draw(gameTime);
}
}
}
I realy hope someone has a solution for this, because I'm stuck right now. I'd really appreciate the help.
using
everything available isn't good programming practice. I can immediately tell if a class of mine handles input at all if I see it importsMicrosoft.Xna.Framework.Input
. It helps me to understand what my code is doing when I revisit it, and it'll help others when they begin to work with it. If your camera importsMicrosoft.Xna.Framework.Audio
then doesn't end up doing anything audio-related at all, your namespace references lose all the value they can add to understanding source code. \$\endgroup\$