Sign in to follow this  
buttermykittens

Resize window & background with XNA (MonoGame)

Recommended Posts

First post here, but everyone's got to start somewhere right? Not sure if this belongs here or the XNA section, but given that I'm just starting out and it's no doubt a basic problem, here will do...
 
So basically I've just started out on some XNA tutorials using MonoGame and have hit a bit of a snag with trying to resize a window (see attached files). Original is 800x480 and looks pretty enough. The resized one is changed to 1280x720. The Earth image still looks fine, however the background appears to have been stretched to fit a 1280x720 window yet still seems to occupy the original 800x480 space.
 
The main drawing function is as follows:
protected override void Draw(GameTime gameTime)
        {
            clsGameManager.Draw(graphics, gameTime);
            GraphicsDevice.Clear(Color.CornflowerBlue);
            spriteBatch.Begin();
            clsGameManager.Draw2D(spriteBatch);
            clsGameManager.DrawFont(spriteBatch, gameTime);
            spriteBatch.End();
            //clsGameManager.Draw3D();
            base.Draw(gameTime);
        }

The clsGameManager draw functions are:
public void Draw(GraphicsDeviceManager graphics, GameTime gameTime)
        {
            bool bApplyChange = false;

            if ((graphics.PreferredBackBufferHeight != clsGlobals.DisplayScreenHeight) || (graphics.PreferredBackBufferWidth != clsGlobals.DisplayScreenWidth) || (graphics.IsFullScreen != clsGlobals.DisplayScreenWindowed))
            {
                bApplyChange = true;
            }
            graphics.PreferredBackBufferHeight = clsGlobals.DisplayScreenHeight;
            graphics.PreferredBackBufferWidth = clsGlobals.DisplayScreenWidth;
            graphics.IsFullScreen = clsGlobals.DisplayScreenWindowed;
             
            if (bApplyChange)
            {
                graphics.ApplyChanges();
            }
        }

public void DrawFont(SpriteBatch spriteBatch, GameTime gameTime)
        {
            float fFPS = 1 / (float)gameTime.ElapsedGameTime.TotalSeconds;
            int nMouseX = clsGlobals.GameStateMouseX;
            int nMouseY = clsGlobals.GameStateMouseY;

            if (clsGlobals.GameStateDisplayFPS)
            {
                clsFont.Draw(spriteBatch, "FPS: " + fFPS.ToString(), 10, 10, Color.White);
                clsFont.Draw(spriteBatch, "Mouse x/y: " + nMouseX + "/" + nMouseY, 10, 25, Color.White);
            }

            // Temp controls help
            clsFont.Draw(spriteBatch, "Keys", 10, 390, Color.White);
            clsFont.Draw(spriteBatch, "Esc: Exit", 10, 405, Color.White);
            clsFont.Draw(spriteBatch, "Q: Explosion", 10, 420, Color.White);
            clsFont.Draw(spriteBatch, "W: Start Music", 10, 435, Color.White);
            clsFont.Draw(spriteBatch, "E: Stop Music", 10, 450, Color.White);
            clsFont.Draw(spriteBatch, "A: Show/Hide FPS", 120, 420, Color.White);
            clsFont.Draw(spriteBatch, "S: Toggle Screen Size", 120, 435, Color.White);
            clsFont.Draw(spriteBatch, "D: Toggle Window Mode", 120, 450, Color.White);

            clsFont.Draw(spriteBatch, "Controller", 650, 405, Color.White);
            clsFont.Draw(spriteBatch, "Back: Exit", 650, 420, Color.White);
            clsFont.Draw(spriteBatch, "X: Explosion", 650, 435, Color.White);
            clsFont.Draw(spriteBatch, "A: Show/Hide FPS", 650, 450, Color.White);
        }

        public void Draw2D(SpriteBatch spriteBatch)
        {
            clsDrawing.DrawBackground(spriteBatch, "Background", Color.White);
            clsDrawing.DrawImage(spriteBatch, "Earth", 200, 200, Color.White);
        }
I'm simply using the 'S' key to toggle between the two different sizes. Switch to/from full-screen brings about a whole bunch of new issues, but one problem at a time right?

Any ideas where this is going wrong?

Share this post


Link to post
Share on other sites

I'm guessing your DrawBackground is drawing with the hardcoded dimensions 800 x 480. A quick fix to this is to base the DrawBackground dimensions on your chosen resolution.

 

The reason why your earth looks smaller is because you've increased the number of pixels on the screen. Let's say you had initialized your screen width/height to 100 x 100, and you draw a 100 x 100 red square. Then  you change resolutions to 100 x 200. If your square is still using the dimensions 100 x 100, your red square won't cover the entire canvas now.

 

Take a look at this related post for some different ways to implement aspect ratios.

http://www.gamedev.net/topic/649327-gui-aspect-ratio-independence/

 

- Eck

Share this post


Link to post
Share on other sites
Nah, I have my rectangle width & height set with the global variables as follows: spriteBatch.Draw(objBackground, new Rectangle(0, 0, clsGlobals.DisplayScreenWidth, clsGlobals.DisplayScreenHeight), strColour);
 
I've tried to create a whole new project (to rule out any of the extra stuff that I'm doing) but can still reproduce the issue. Full set of code is:
 
namespace GameName1
{
    public class Game1 : Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;
        Texture2D objBackground;
        private SpriteFont objFontCalibri;
        KeyboardState objKeyboardStateOld, objKeyboardStateNew;
        private int nDisplayScreenHeight, nDisplayScreenWidth;
        private bool bDisplayScreenFull;

        public Game1(): base()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
        }

        protected override void Initialize()
        {
            nDisplayScreenHeight = 480;
            nDisplayScreenWidth = 800;
            bDisplayScreenFull = false;
            base.Initialize();
        }

        protected override void LoadContent()
        {
            spriteBatch = new SpriteBatch(GraphicsDevice);
            objBackground = Content.Load<Texture2D>("Background");
            objFontCalibri = Content.Load<SpriteFont>("Calibri");
        }

        protected override void UnloadContent()
        {
        }

        protected override void Update(GameTime gameTime)
        {
            if (Keyboard.GetState().IsKeyDown(Keys.Escape))
                Exit();

            objKeyboardStateNew = Keyboard.GetState();
            if (objKeyboardStateOld.IsKeyUp(Keys.S) && objKeyboardStateNew.IsKeyDown(Keys.S))
            {
                if (nDisplayScreenWidth == 800)
                {
                    nDisplayScreenWidth = 1280;
                    nDisplayScreenHeight = 720;
                }
                else
                {
                    nDisplayScreenWidth = 800;
                    nDisplayScreenHeight = 480;
                }
            }
            if (objKeyboardStateOld.IsKeyUp(Keys.D) && objKeyboardStateNew.IsKeyDown(Keys.D))
            {
                bDisplayScreenFull = !bDisplayScreenFull;
            }
            objKeyboardStateOld = objKeyboardStateNew;

            base.Update(gameTime);
        }

        protected override void Draw(GameTime gameTime)
        {
            bool bApplyChange = false;

            if ((graphics.PreferredBackBufferHeight != nDisplayScreenHeight) || (graphics.PreferredBackBufferWidth != nDisplayScreenWidth) || (graphics.IsFullScreen != bDisplayScreenFull))
            {
                bApplyChange = true;
            }
            graphics.PreferredBackBufferHeight = nDisplayScreenHeight;
            graphics.PreferredBackBufferWidth = nDisplayScreenWidth;
            graphics.IsFullScreen = bDisplayScreenFull;

            if (bApplyChange)
            {
                graphics.ApplyChanges();
            }

            GraphicsDevice.Clear(Color.CornflowerBlue);
            spriteBatch.Begin();
            spriteBatch.Draw(objBackground, new Rectangle(0, 0, nDisplayScreenWidth, nDisplayScreenHeight), Color.White);
            spriteBatch.DrawString(objFontCalibri, "DisplayScreenWidth: " + nDisplayScreenWidth.ToString(), new Vector2(650, 10), Color.White);
            spriteBatch.DrawString(objFontCalibri, "DisplayScreenHeight: " + nDisplayScreenHeight.ToString(), new Vector2(650, 25), Color.White);
            spriteBatch.End();
            base.Draw(gameTime);
        }
    }
}

I even added the extra debug info to check that the width & height are being set correctly and they look to be fine as well.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this