Uniform window resizing in XNA

Well, I'm trying to give the game window the ability to resize evenly . I checked everywhere, but I can not find anything about it.

Any ideas?

I cannot post code due to character limit. It would be very appreciated if someone could help me and see what I'm doing wrong :)

It would also be helpful to resize the backbuffer when this happens, since I don't think the game will only play with visible sprites :)

void Window_ClientSizeChanged( object sender, EventArgs e ) { int new_width = graphics.GraphicsDevice.Viewport.Width; int new_height = graphics.GraphicsDevice.Viewport.Height; if (new_width != Variables.SCREEN_WIDTH) { Variables.SCREEN_HEIGHT = (int)(new_width * ascept_ratio); Variables.SCREEN_WIDTH = new_width; } if (new_height != Variables.SCREEN_HEIGHT) { Variables.SCREEN_WIDTH = (int)(new_height / ascept_ratio); Variables.SCREEN_HEIGHT = new_height; } UpdateParameters(); } 

...

  public void UpdateParameters() { graphics.PreferredBackBufferWidth = Variables.SCREEN_WIDTH; graphics.PreferredBackBufferHeight = Variables.SCREEN_HEIGHT; graphics.ApplyChanges(); } 

Thanks,

Regards, Darestium

+4
source share
2 answers

To keep the aspect ratio, you mean?

You would do this just like any WinForms project:

When the form loads, save the aspect radio: (float)Width/(float)Height . In XNA, this can be in the LoadContent your game (since the window will be created by then).

Then handle the sizechanged form sizechanged . You will need to keep track of whether the user is changing in height, width, or both. If it is height, then set Width = Height / AspectRatio , if the width changes, set Height = Width * AspectRatio .

If both changes change, then select the width or height (I mean the choice of one in the design, not each size) and do as described above.


You will probably have to do something specific to XNA as soon as you do, for example, resize the buffer, etc., but that doesn’t apply to this question, so I’ll leave it (ask another question if you need to be )


EDIT. Below is the minimum working sample:

It maintains the aspect ratio, and also resizes the graphics, drawing the original size of the window on the rendering target, and then drawing the scale corresponding to the new window. If you do not want the overridden BeginDraw and EndDraw methods to eliminate this.

 using System; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; namespace WindowsGame1 { public class Game1 : Game { GraphicsDeviceManager Graphics; float AspectRatio; Point OldWindowSize; Texture2D BlankTexture; RenderTarget2D OffScreenRenderTarget; SpriteBatch SpriteBatch; public Game1() { Graphics = new GraphicsDeviceManager(this); Content.RootDirectory = "Content"; Graphics.IsFullScreen = false; Window.AllowUserResizing = true; Window.ClientSizeChanged += new EventHandler<EventArgs>(Window_ClientSizeChanged); } void Window_ClientSizeChanged(object sender, EventArgs e) { // Remove this event handler, so we don't call it when we change the window size in here Window.ClientSizeChanged -= new EventHandler<EventArgs>(Window_ClientSizeChanged); if (Window.ClientBounds.Width != OldWindowSize.X) { // We're changing the width // Set the new backbuffer size Graphics.PreferredBackBufferWidth = Window.ClientBounds.Width; Graphics.PreferredBackBufferHeight = (int)(Window.ClientBounds.Width / AspectRatio); } else if (Window.ClientBounds.Height != OldWindowSize.Y) { // we're changing the height // Set the new backbuffer size Graphics.PreferredBackBufferWidth = (int)(Window.ClientBounds.Height * AspectRatio); Graphics.PreferredBackBufferHeight = Window.ClientBounds.Height; } Graphics.ApplyChanges(); // Update the old window size with what it is currently OldWindowSize = new Point(Window.ClientBounds.Width, Window.ClientBounds.Height); // add this event handler back Window.ClientSizeChanged += new EventHandler<EventArgs>(Window_ClientSizeChanged); } protected override void LoadContent() { // Set up initial values AspectRatio = GraphicsDevice.Viewport.AspectRatio; OldWindowSize = new Point(Window.ClientBounds.Width, Window.ClientBounds.Height); BlankTexture = new Texture2D(GraphicsDevice, 1, 1); BlankTexture.SetData(new Color[] { Color.FromNonPremultiplied(255, 255, 255, 255) }); SpriteBatch = new SpriteBatch(GraphicsDevice); OffScreenRenderTarget = new RenderTarget2D(GraphicsDevice, Window.ClientBounds.Width, Window.ClientBounds.Height); } protected override void UnloadContent() { if (OffScreenRenderTarget != null) OffScreenRenderTarget.Dispose(); if (BlankTexture != null) BlankTexture.Dispose(); if (SpriteBatch != null) SpriteBatch.Dispose(); base.UnloadContent(); } protected override bool BeginDraw() { GraphicsDevice.SetRenderTarget(OffScreenRenderTarget); return base.BeginDraw(); } protected override void Draw(GameTime gameTime) { GraphicsDevice.Clear(Color.CornflowerBlue); SpriteBatch.Begin(); SpriteBatch.Draw(BlankTexture, new Rectangle(100, 100, 100, 100), Color.White); SpriteBatch.End(); base.Draw(gameTime); } protected override void EndDraw() { GraphicsDevice.SetRenderTarget(null); SpriteBatch.Begin(); SpriteBatch.Draw(OffScreenRenderTarget, GraphicsDevice.Viewport.Bounds, Color.White); SpriteBatch.End(); base.EndDraw(); } } } 
+6
source

I assume that this code will not work because it will continue to call itself because the ClientSizeChanged event will fire the ClientSizeChanged event.

Perhaps you need to check and see if the window is already in the correct format, and not change it further.

0
source

Source: https://habr.com/ru/post/1384847/


All Articles