1
votes

Is there a way that I could basically develop my XNA game at 1080p (or 720p) as my default resolution and then depending upon the set resolution just scale everything in the game to the proper size, without having to set the scaling factor in every Sprite Draw() method?

My thought is that, I could develop all the graphics, configure coordinates, etc based on a resolution of 1080p but then for the XBOX just set the res to 720p and scale down (so that the XBOX sees everything as being at 720 and therefore handles all resolutions as mentioned in the developer docs) and on PC scale to any needed resolution or aspect ratio by automatically letterboxing the view for resolutions that are not 16:9.

I already had my game setup so that spritebatch.begin() and end() were called at the highest level, around all the other Draw calls, so that I could technically just pass in the scaling matrix there, but whenever I do that it will do something weird like make the view off center, or only take up a quarter of the screen.

Is there a best practice way for achieving this?

1

1 Answers

4
votes

If you set a scaling matrix in SpriteBatch.Begin, then it will scale the sizes and positions of every single sprite you draw, with that SpriteBatch, up until you call End.

SpriteBatch uses a client space where zero is the upper left corner of the Viewport, and one unit in that space is equivalent to one pixel in the viewport.

When you give SpriteBatch a transformation, the sprites that you draw will have that transformation applied to them for you, before they are drawn. So you can (and should) use this same technique to translate your scene (to centre it on your player, for example).

For Example:

Your game is developed at 720p and you're using SpriteBatch without a transformation. You have a sprite centred at the bottom right corner. Let's say its texture is (32, 32) pixels and the sprite's origin is (16, 16) (origin is specified in texture space, so this is the centre of the sprite). The sprite's position is (1280, 720). The sprite's scale is 1, which makes its resulting size (32, 32). You will see the top left quarter of the sprite at the bottom-right corner of your screen.

Now you move to a screen that is 1080p (1.5 times bigger than 720p). If you don't add a scaling matrix to SpriteBatch, you can see the whole sprite, with its at two-thirds of the screen, rightwards and downwards.

But you want to scale up your whole scene so that at 1080p it looks just like it did at 720p. So you add the matrix Matrix.CreateScale(1.5f, 1.5f, 1f) (note using 1 for Z axis, because this is 2D not 3D) to your SpriteBatch.Begin, and do nothing else.

Now your scene of sprites will be scaled 1.5 times bigger. Without making any changes to the actual Draw call, your sprite will be drawn at position (1920, 1080) (the bottom right corner of the screen), its size will be (48, 48) (1.5 times bigger), and its origin will still be the centre. You will see the sprite's top-left quadrant at the bottom-right corner of your screen, just like you did at 720p, and at the same relative size.