9
\$\begingroup\$

I am making a 2d game with xna/monogame. I want the main view area to always show 15x15 tiles, or 480x480px.

a drawing of the situation

I've got something that sort of works, following this guide. It expands the view range if you make the window smaller. However, it works somewhat properly if you expand it. It works as intended if the window is maximized.

I want the range of what is rendered to be no larger than 480px x 480px regardless of the the window's size, but I'd like the sprites to appear bigger if the window resolution is set larger (and conversely).

\$\endgroup\$
4
  • \$\begingroup\$ I edited to clarify as I could. I was confused by the parts that explain the behaviour you want and have. I tried to draw it. Is that anything like right? \$\endgroup\$
    – Anko
    Commented Sep 2, 2014 at 19:18
  • \$\begingroup\$ Yes sorry for me not being more clear, sometimes I have difficulties conveying what i'm actually thinking. That is exactly what I'm wanting to accomplish, the guide gets something extremely like it but the player's render range doesn't stay where I want it to. \$\endgroup\$
    – ChrisD3
    Commented Sep 3, 2014 at 2:47
  • 1
    \$\begingroup\$ It sounds like you may be after one of the solutions provided for: stackoverflow.com/questions/7591466/… \$\endgroup\$
    – lzcd
    Commented Sep 3, 2014 at 3:49
  • \$\begingroup\$ The chosen answer on that page I get a null reference exception on the form variable, and thats with it just copy pasted to try it out. \$\endgroup\$
    – ChrisD3
    Commented Sep 5, 2014 at 15:06

2 Answers 2

5
\$\begingroup\$

I've recently been implemented something like this in the MonoGame.Extended library. Creating a letterbox / pillarbox viewport in MonoGame is actually kinda tricky. I'll do my best to provide a good answer here.

There's basically 3 parts to it. The first is creating a scaling matrix to pass into the SpriteBatch.Begin call. The variables represent your actual resolution vs virtual resolution. For example, you code the game against a virtual resolution of 800x480 but render it on an actual resolution of 1024x768. This code will stretch the image to fit.

var scaleX = (float)ActualWidth / VirtualWidth;
var scaleY = (float)ActualHeight / VirtualHeight;
var scaleMatrix = Matrix.CreateScale(scaleX, scaleY, 1.0f);

_spriteBatch.Begin(transformMatrix: scaleMatrix);

The second part is how you get the letterbox / pillar box effect. It resizes the viewport on the GraphicsDevice and centers the image. This code needs to run every time the devices screen size or window size changes. For example, in the Window.ClientSizeChanged event.

var viewport = GraphicsDevice.Viewport;
var aspectRatio = (float) VirtualWidth / VirtualHeight;
var width = viewport.Width;
var height = (int)(width / aspectRatio + 0.5f);

if (height > viewport.Height)
{
    height = viewport.Height;
    width = (int) (height * aspectRatio + 0.5f);
}

var x = (viewport.Width / 2) - (width / 2);
var y = (viewport.Height / 2) - (height / 2);

GraphicsDevice.Viewport = new Viewport(x, y, width, height);

The last part is dealing with input coordinates from the mouse or touch screen. Because you've scaled and moved the graphics, you'll need to do the reverse for input coordinates. In this case, something like this

var viewport = GraphicsDevice.Viewport;
var matrix = Matrix.Invert(scaleMatrix);
var oldPosition = new Vector2(mousePoint.X - viewport.X, mousePoint.Y - viewport.Y);
var newPosition = Vector2.Transform(oldPosition, scaleMatrix).ToPoint();

I have a full tutorial with all this stuff in classes on my blog.

\$\endgroup\$
1
\$\begingroup\$

articles generally are not liked in Stack exchange but this is my go to blog post when trying to remember this

http://www.david-amador.com/2010/03/xna-2d-independent-resolution-rendering/

\$\endgroup\$
4
  • 1
    \$\begingroup\$ articles generally are not liked because if the site goes down, the answer is useless. How about quoting the relevant bits of your article in your answer? \$\endgroup\$
    – ashes999
    Commented Sep 7, 2014 at 2:33
  • \$\begingroup\$ not my article it's someone else's and probably covered by some copyright malarkey \$\endgroup\$
    – RoughPlace
    Commented Sep 7, 2014 at 8:54
  • \$\begingroup\$ How would I use this with a 2dcamera that i want always centered on the player. This answer offsets the camera by quite a bit. resulting in this \$\endgroup\$
    – ChrisD3
    Commented Sep 7, 2014 at 19:15
  • \$\begingroup\$ "copyright malarkey" If the material is posted for all to see, reposting a small amount is covered by fair use doctrine. \$\endgroup\$
    – user122973
    Commented Nov 19, 2022 at 20:26

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .