Redimensionnement uniforme d’une fenêtre dans XNA

Eh bien, j’essaie de donner à la fenêtre de mon jeu la possibilité de redimensionner de manière uniforme . J’ai vérifié partout mais je n’arrive pas à trouver quoi que ce soit à ce sujet.

Des idées?

Je ne peux pas publier le code en raison de la limite de caractères. Ce serait très apprécié si quelqu’un pouvait m’aider et voir ce que je faisais mal 🙂

Il serait également utile de savoir comment redimensionner le backbuffer lorsque cela se produit, car je ne pense pas que le jeu serait jouable avec seulement la moitié des sprites visibles 🙂

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(); } 

Merci,

Cordialement, Darestium

Pour garder le rapport d’aspect tu veux dire?

Vous feriez ceci comme n’importe quel projet WinForms:

Lorsque le formulaire est chargé, enregistrez l’aspect radio: (float)Width/(float)Height . Dans XNA, cela pourrait être dans le LoadContent de votre jeu (puisque la fenêtre serait créée d’ici là).

Ensuite, gérez l’événement sizechanged du sizechanged . Vous devez savoir si l’utilisateur modifie la hauteur, la largeur ou les deux. S’il s’agit d’une hauteur, définissez la valeur Width = Height / AspectRatio . Si la largeur change, définissez Height = Width * AspectRatio .

Si les deux changent, décidez de la largeur ou de la hauteur (choisissez l’un des motifs, pas chaque redimensionnement) et procédez comme ci-dessus.


Vous devrez probablement faire des choses spécifiques à XNA une fois que vous aurez fait cela, telles que redimensionner la mémoire tampon, etc.


MODIFIER. Vous trouverez ci-dessous un exemple de travail minimal:

Il conserve les proportions, redimensionne les graphiques en dessinant de manière à rendre la taille d’origine de la fenêtre, puis en dessinant à l’échelle pour l’adapter à la nouvelle fenêtre. Si vous ne le souhaitez pas, supprimez les méthodes BeginDraw et EndDraw remplacées.

 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(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(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(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(); } } } 

Mon hypothèse est que ce code ne fonctionnera pas car il continuera à s’appeler lui-même, car l’événement ClientSizeChanged déclenchera l’événement ClientSizeChanged.

Peut-être devrez-vous vérifier si la fenêtre présente déjà le bon rapport hauteur / largeur et ne pas la modifier davantage.