0

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.).

Jelle
  • 165
  • 8
  • how are currentFrame and frameSize calculated? – Marco Fatica Nov 03 '15 at 17:26
  • `currentFrame` is the current frame in the animation. I assigned a variable for how long the game waits when it displays the next sprite in the animation. The `frameSize` is how big one sprite in an animation is (how many pixels in height and in witdth). But this is not the problem I think, because the animations work well. – Jelle Nov 03 '15 at 17:30
  • Do I check for `IsActive` in the main `Game` class? – Jelle Nov 03 '15 at 17:54
  • Yes, `IsActive` belongs to `Game`, but I was thinking of another fix I made (so comment deleted). I checked my change history for that project and what happened is that the way I was setting position was doing a ` < 0` check, and minimizing the game was creating VERY invalid values so that the check I was doing basically reset everything to zero (to keep things in bounds). Can we see how position is calculated? – E. Moffat Nov 03 '15 at 17:56
  • I updated my information on the position. – Jelle Nov 03 '15 at 18:08
  • I'm guessing you're using `Game.Window.ClientBounds` to keep player from moving out of the screen? – E. Moffat Nov 03 '15 at 18:12
  • yes, so that the player can't walk outside of the screen – Jelle Nov 03 '15 at 18:27
  • Ok - I'll update with an answer later today (I have meetings :-/) – E. Moffat Nov 03 '15 at 18:31

1 Answers1

1

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...
}
E. Moffat
  • 3,165
  • 1
  • 21
  • 34