Равномерное изменение размера окна в XNA - PullRequest
4 голосов
/ 06 декабря 2011

Ну, я пытаюсь дать окну моей игры возможность изменять размер равномерно .Я проверял везде, но не могу найти что-нибудь об этом.

Любые идеи?

Я не могу опубликовать код из-за ограничения по количеству символов.Было бы очень полезно, если бы кто-то мог помочь мне и посмотреть, что я делаю неправильно:)

Также было бы полезно, как изменить размер буфера, когда это произойдет, поскольку я не думаю, что игра будетиграбелен только с половиной видимых спрайтов:)

   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

Ответы [ 2 ]

6 голосов
/ 06 декабря 2011

Чтобы сохранить соотношение сторон, которое вы имеете в виду?

Вы бы сделали это так же, как любой проект WinForms:

Когда форма загрузится, сохраните радио аспекта: (float)Width/(float)Height.В XNA это может быть в LoadContent вашей игры (поскольку к тому времени будет создано окно).

Затем обработайте событие формы sizechanged.Вам нужно будет отслеживать, меняет ли пользователь высоту, ширину или и то, и другое.Если это высота, тогда установите Width = Height / AspectRatio, если ширина изменяется, установите Height = Width * AspectRatio.

Если оба изменятся, тогда выберите либо ширину, либо высоту (я имею в виду, выбирайте либо один в дизайне, но не каждый размер) и сделайте, как указано выше.


Вам, вероятно, придется делать что-то специфичное для XNA, как только вы это сделаете, например, изменять размер буфера и т. д., но это не относится к этому вопросу, поэтомуЯ оставлю это (задать другой вопрос, если это будет необходимо).


РЕДАКТИРОВАТЬ.Ниже приведен минимальный рабочий пример:

Он поддерживает соотношение сторон, а также изменяет размеры графики, рисуя для цели рендеринга исходный размер окна, а затем рисуя с масштабированием, чтобы соответствовать новому окну.,Если вы не хотите этого, удалите переопределенные методы BeginDraw и EndDraw.

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();
        }
    }
}
0 голосов
/ 07 декабря 2011

Я предполагаю, что этот код не будет работать, потому что он будет продолжать вызывать себя, потому что событие ClientSizeChanged вызовет событие ClientSizeChanged.

Возможно, вам нужно проверить и посмотреть, находится ли окно уже вправильное соотношение сторон, а не изменять его дальше.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...