6
votes

I've got a 2D game that I'm working on that is in 4:3 aspect ratio. When I switch it to fullscreen mode on my widescreen monitor it stretches. I tried using two viewports to give a black background to where the game shouldn't stretch to, but that left the game in the same size as before. I couldn't get it to fill the viewport that was supposed to hold the whole game.

How can I get it to go fullscreen without stretching and without me needing to modify every position and draw statement in the game? The code I'm using for the viewports is below.

            // set the viewport to the whole screen
            GraphicsDevice.Viewport = new Viewport
            {
                X = 0,
                Y = 0,
                Width = GraphicsDevice.PresentationParameters.BackBufferWidth,
                Height = GraphicsDevice.PresentationParameters.BackBufferHeight,
                MinDepth = 0,
                MaxDepth = 1
            };

            // clear whole screen to black
            GraphicsDevice.Clear(Color.Black);

            // figure out the largest area that fits in this resolution at the desired aspect ratio
            int width = GraphicsDevice.PresentationParameters.BackBufferWidth;
            int height = (int)(width / targetAspectRatio + .5f);
            if (height > GraphicsDevice.PresentationParameters.BackBufferHeight)
            {
                height = GraphicsDevice.PresentationParameters.BackBufferHeight;
                width = (int)(height * targetAspectRatio + .5f);
            }
            //Console.WriteLine("Back:  Width: {0}, Height: {0}", GraphicsDevice.PresentationParameters.BackBufferWidth, GraphicsDevice.PresentationParameters.BackBufferHeight);
            //Console.WriteLine("Front: Width: {0}, Height: {1}", width, height);

            // set up the new viewport centered in the backbuffer
            GraphicsDevice.Viewport = new Viewport
            {
                X = GraphicsDevice.PresentationParameters.BackBufferWidth / 2 - width / 2,
                Y = GraphicsDevice.PresentationParameters.BackBufferHeight / 2 - height / 2,
                Width = width,
                Height = height,
                MinDepth = 0,
                MaxDepth = 1
            };

            GraphicsDevice.Clear(Color.CornflowerBlue);

The image below shows what the screen looks like. The black on the sides is what I want (and is from the first viewport) and the second viewport is the game and the cornflower blue area. What I want is to get the game to scale to fill the cornflower blue area.

Not correctly scaling

4
You might be interested to know that there is actually a Game Development Stack Exchange site, where you might get a better answer for this: gamedev.stackexchange.comWayne Koorts

4 Answers

0
votes

As is also the case in commercial games, you should provide an option to the user that allows them to switch between 4:3 aspect and 16:9 aspect. You should be able to just modify the camera viewing ratio accordingly.

EDIT:

As far as I have seen, there are no games that 'auto-detect' the proper aspect ratio to use.

As has been pointed out, there are ways to make a good guess as to what the proper aspect ratio is. If XNA allows you to get at the current Windows user's screen settings data, you can determine an aspect ratio based off of the monitor resolution.

Once you have determined the monitor resolution of the user, you can best decide how to deal with it. At first, the best bet may be to just put black bars on the left/right side of the screen to allow full-screen with a 16:9 aspect ratio that is essentially still using the 4:3 artwork.

Eventually you could modify the game so that it changes the viewing port size when the aspect ratio is 16:9. This wouldn't require changing any art assets, just how they are being rendered.

0
votes

First of all I'm assuming you're talking about XNA 4.0, which AFAIK there are breaking changes between XNA 3.x and XNA 4.0.

I'm relatively new at XNA, however it seems to me that your assets does not fit the size of the window. Let's say that your game are is 320x240 and your window is bigger e.g. 640x480.

Thus you can specify PreferredBuffer in order to scale up your application. So, tell to XNA you are going to use 320x240 by setting the following values;

_graphics.PreferredBackBufferWidth = 320;
_graphics.PreferredBackBufferHeight = 240;

Additionally you can start fullscreen mode by setting:

_graphics.IsFullScreen = true;

Also, you have to handle manually the how the items should change their size once the Window has changed their size.

Checkout my sample at. https://github.com/hmadrigal/xnawp7/tree/master/XNASample02

(BTW, you can press F11 to switch between fullscreen and normal view)

Best regards, Herber

0
votes

I'm not sure if you can actually scale your view port like that. I understand what you're trying to do, but to do it you'd have to do the following.

  1. Set your screen backbuffer width and height to the 16:9 resolution.
  2. Program in the displacement so that objects didn't draw in those borders.

The thing is, all major games these days, if you play them on a 16:9 monitor and select a 4:3 resolution, will stretch to fit the screen. This isn't something you usually want to overcome. You either support many resolutions in your game, or you will get stretching when a user uses the wrong resolution for his or her screen type.

Usually, one sets up their game, and their textures to work based on the relative dimensions of the current viewport or backbuffer width and height. This way, regardless of the resolution inputted, the game scales to work with that width/height ratio.

It's a bit more work, but in the end, makes your game far more polished and compatible with a wide array of systems.

The only time this may not be done is if the app runs in a window (NOT fullscreen).