最小化时重置位置

Position reset when minimizing

当我启动我的应用程序时,对象在给定位置(给定向量)生成。但是当我最小化 monogame window 并重新打开它时,对象位于左上角。

为什么会这样?

注意:这是我的 Draw 方法:

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);
}

如何计算起始位置:

// 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>();
}

我用Vector2 direction知道精灵面向哪个方向:

public abstract Vector2 direction
    {
        get;
    }

我在 PlayerMovement class 和 return inputDirection * speed

中使用 get

(inputDirection 是一个 Vector2)

最后在我的 Update 方法中,我执行 position += direction 并且我还检查玩家是否没有接触屏幕的边界(他不能移出屏幕。)。

根据我自己的经验,当 window 最小化时,在 Update 调用中使用 Game.Window.ClientBounds 会导致问题。这是我项目中的一些示例代码:

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

我在最小化时遇到的问题是 Game.Window.ClientBounds 在 -32000 附近返回了一些 width/height。在恢复 window 时,这总是会将我的游戏对象重置到某个默认位置。我通过首先检查 ClientBounds WidthHeight 是否都大于零来修复它:

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);
}

作为参考,这里有一个 diff of changes 解决了我自己项目的最小化问题。

当游戏不是主要的、活跃的 window 时,我遇到的一个单独的错误涉及与游戏的交互仍然发生。您还可以在 UpdateDraw 调用的开头添加对 Game.IsActive 的检查:

public override void Update(GameTime gt)
{
    if(!IsActive) return;
    //etc...
}

或者,如果使用游戏组件,您的组件 update/draw 将如下所示:

public override void Update(GameTime gt)
{
    if(!Game.IsActive) return;
    //etc...
}