When I start my application, the object spawns at the given position (given vector). But when I minimize the monogame window and reopen it, then the object is in the upper-left corner.
Why is this happening?
NOTE: this is my Draw
method:
public virtual void Draw(GameTime gameTime, SpriteBatch spriteBatch)
{
// Position is the object position
spriteBatch.Draw(textureImage, position, new Rectangle(
(currentFrame.X * frameSize.X),
(currentFrame.Y * frameSize.Y),
frameSize.X, frameSize.Y),
Color.White, 0, Vector2.Zero, 2, SpriteEffects.None, 0);
}
How the starting position is calculated:
// Vector2 position is the starting position for the object
public PlayerMovement(Texture2D textureImage, Vector2 position, Point frameSize, int collisionOffSet, Point currentFrame, Point startFrame, Point sheetSize, float speed, float speedMultiplier, float millisecondsPerFrame)
: base(textureImage, position, frameSize, collisionOffSet, currentFrame, startFrame, sheetSize, speed, speedMultiplier, millisecondsPerFrame)
{
children = new List<Sprite>();
}
I use Vector2 direction
to know which direction the sprite is facing:
public abstract Vector2 direction
{
get;
}
I use the get
in my PlayerMovement
class and return inputDirection * speed
(inputDirection
is a Vector2
)
Finally in my Update
method, I do position += direction
and I also check if the player isn't touching the borders of the screen(he can't move out the screen.).
From my own experience, using Game.Window.ClientBounds
in an Update
call has caused problems when the window is minimized. Here is some sample code from my project:
Rectangle gdm = Game.Window.ClientBounds;
if (DrawLocation.X < 0) DrawLocation = new Vector2(0, DrawLocation.Y);
if (DrawLocation.Y < 0) DrawLocation = new Vector2(DrawLocation.X, 0);
if (DrawLocation.X > gdm.Width - DrawAreaWithOffset.Width) DrawLocation = new Vector2(gdm.Width - DrawAreaWithOffset.Width, DrawLocation.Y);
if (DrawLocation.Y > gdm.Height - DrawAreaWithOffset.Height) DrawLocation = new Vector2(DrawLocation.X, gdm.Height - DrawAreaWithOffset.Height);
The problem I had when minimizing was that Game.Window.ClientBounds was returning some width/height around -32000
. This would always reset my game objects to some default location when restoring the window. I fixed it by first checking that the ClientBounds Width
and Height
were both greater than zero:
Rectangle gdm = Game.Window.ClientBounds;
if (gdm.Width > 0 && gdm.Height > 0) //protect when window is minimized
{
if (DrawLocation.X < 0)
DrawLocation = new Vector2(0, DrawLocation.Y);
if (DrawLocation.Y < 0)
DrawLocation = new Vector2(DrawLocation.X, 0);
if (DrawLocation.X > gdm.Width - DrawAreaWithOffset.Width)
DrawLocation = new Vector2(gdm.Width - DrawAreaWithOffset.Width, DrawLocation.Y);
if (DrawLocation.Y > gdm.Height - DrawAreaWithOffset.Height)
DrawLocation = new Vector2(DrawLocation.X, gdm.Height - DrawAreaWithOffset.Height);
}
For reference, here is a diff of changes that fixed the minimize problem for my own project.
A separate bug I was having involved interaction with the game still happening when the game was not the primary, active window. You can also add a check for Game.IsActive
at the beginning of your Update
and Draw
calls:
public override void Update(GameTime gt)
{
if(!IsActive) return;
//etc...
}
Or if using Game Components, your component update/draw would look like:
public override void Update(GameTime gt)
{
if(!Game.IsActive) return;
//etc...
}