在XNA中统一调整窗口大小

好吧,我试图让我的游戏窗口能够统一resize。 我到处检查过,但我似乎找不到任何关于它的信息。

有任何想法吗?

由于字符限制,我无法发布代码。 非常感谢有人可以帮助我,看看我做错了什么:)

同样有用的是如何在发生这种情况时调整后备缓冲区的大小,因为我不认为只有一半的精灵可以玩游戏:)

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

谢谢,

亲切的问候,Darestium

保持宽高比你的意思是?

您可以像任何WinForms项目一样执行此操作:

当窗体加载时,存储方面无线电:( (float)Width/(float)Height 。 在XNA中,这可能位于游戏的LoadContent中(因为窗口将在那时创建)。

然后,处理表单的sizechanged事件。 您需要跟踪用户是否正在更改高度,宽度或两者。 如果它是高度,则设置Width = Height / AspectRatio ,如果宽度更改设置Height = Width * AspectRatio

如果两者都改变​​了,那么决定宽度或高度,(我的意思是在设计中选择一个,而不是每个resize)并按上述方式进行。


一旦你完成了这个操作,你可能不得不做一些特定于XNA的事情,例如调整后备缓冲区的大小等等。但这并不是特定于这个问题,所以我会把它留下来(如果需要,可以提出另一个问题)。


编辑。 以下是最小的工作样本:

它保持纵横比,并通过绘制渲染目标窗口的原始大小来调整图形大小,然后绘制缩放以适合新窗口。 如果您不希望这样删除重写的BeginDrawEndDraw方法。

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

我的猜测是这段代码不起作用,因为它会继续调用自身,因为ClientSizeChanged事件将触发ClientSizeChanged事件。

也许您需要检查窗口是否已经具有正确的宽高比,而不是进一步更改窗口。