Well, I am trying to give my game's window the ability to resize uniformly. I have checked everywhere but I can't seem to find anything about it.
Any ideas?
I can't post the code due to the character limit. It would be much appreciated if someone could please help me out and see what I am doing wrong :)
Also helpful would be how to resize the backbuffer when this happens, as I don't think the game would be playable with only half the sprites visible :)
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,
Kind Regards, Darestium
To keep the aspect ratio you mean?
You'd do this the same as any WinForms project:
When the form loads up store the aspect radio: (float)Width/(float)Height
. In XNA, this could be in the LoadContent
of your game (since the window would be created by then).
Then, handle the form's sizechanged
event. You'll need to keep track of whether the user is changing height, width or both. If it's height, then set the Width = Height / AspectRatio
, if the width changes set Height = Width * AspectRatio
.
If both change, then decide on either width or height, (i mean pick either one in design, not each resize) and do as above.
You'll probably have to do things XNA-specific once you've done this, such as resize the backbuffer etc. but this isn't specific to this question so i'll leave it out (ask another question if need be).
EDIT. Below is a minimal, working sample:
It maintains aspect ratio, as well as resizes the graphics by drawing to a render target the original size of the window, then drawing that scaled to fit the new window. If you don't want this remove the overridden BeginDraw
and EndDraw
methods.
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();
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With