Advertisement
Guest User

ScreenManager

a guest
May 26th, 2018
385
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 7.81 KB | None | 0 0
  1. using ArbitraryPixel.Common.Graphics;
  2. using ArbitraryPixel.Common.Graphics.Factory;
  3. using Microsoft.Xna.Framework;
  4. using Microsoft.Xna.Framework.Graphics;
  5. using System;
  6.  
  7. namespace ArbitraryPixel.Common.Screen
  8. {
  9.     /// <summary>
  10.     /// An object that manages resolution scaling for screens, scaling up the world to best fit the screen area while maintaining aspect ratio.
  11.     /// </summary>
  12.     public class ScreenManager : IScreenManager
  13.     {
  14.         #region Private Members
  15.         private Viewport _viewport = new Viewport(0, 0, 1, 1);
  16.         private bool _matrixNeedsUpdate = false;
  17.         private Matrix _scaleMatrix = Matrix.Identity;
  18.         #endregion
  19.  
  20.         #region Public Properties
  21.         /// <summary>
  22.         /// The unscaled world size.
  23.         /// </summary>
  24.         public Point World
  25.         {
  26.             get { return _world; }
  27.             set
  28.             {
  29.                 if (value != _world)
  30.                 {
  31.                     _world = value;
  32.                     CalculateViewport();
  33.                 }
  34.             }
  35.         }
  36.         private Point _world = new Point(1, 1);
  37.  
  38.         /// <summary>
  39.         /// The screen size.
  40.         /// </summary>
  41.         public Point Screen
  42.         {
  43.             get { return _screen; }
  44.             set
  45.             {
  46.                 if (value != _screen)
  47.                 {
  48.                     _screen = value;
  49.                     CalculateViewport();
  50.                 }
  51.             }
  52.         }
  53.         private Point _screen = new Point(1, 1);
  54.  
  55.         /// <summary>
  56.         /// True if fullscreen is desired, False if windows behaviour is desired.
  57.         /// </summary>
  58.         public bool IsFullScreen { get; set; } = false;
  59.  
  60.         /// <summary>
  61.         /// The scale of this screen manager's screen size to its world size.
  62.         /// </summary>
  63.         public Vector3 Scale
  64.         {
  65.             get
  66.             {
  67.                 return new Vector3(
  68.                     _viewport.Width / (float)this.World.X,
  69.                     _viewport.Height / (float)this.World.Y,
  70.                     1f
  71.                 );
  72.             }
  73.         }
  74.  
  75.         /// <summary>
  76.         /// The scale matrix for this ScreenManager
  77.         /// </summary>
  78.         public Matrix ScaleMatrix
  79.         {
  80.             get
  81.             {
  82.                 if (_matrixNeedsUpdate)
  83.                 {
  84.                     _scaleMatrix = Matrix.CreateScale(this.Scale);
  85.                 }
  86.  
  87.                 return _scaleMatrix;
  88.             }
  89.         }
  90.  
  91.         /// <summary>
  92.         /// The options for this screen manager.
  93.         /// </summary>
  94.         public ScreenManagerOptions Options { get; set; } = null;
  95.         #endregion
  96.  
  97.         #region Constructor(s)
  98.         /// <summary>
  99.         /// Construct a new object.
  100.         /// </summary>
  101.         public ScreenManager()
  102.         {
  103.         }
  104.         #endregion
  105.  
  106.         #region Public Methods
  107.         /// <summary>
  108.         /// Convert a point in screen coordinates to world coorindates.
  109.         /// </summary>
  110.         /// <param name="screenPoint">A point relative to screen coordinates</param>
  111.         /// <returns>The point converted to world coordinates.</returns>
  112.         public Vector2 PointToWorld(Vector2 screenPoint)
  113.         {
  114.             Vector2 worldPoint = screenPoint;
  115.  
  116.             Vector3 scale = this.Scale;
  117.  
  118.             worldPoint.X /= scale.X;
  119.             worldPoint.Y /= scale.Y;
  120.  
  121.             worldPoint.X -= _viewport.X / scale.X;
  122.             worldPoint.Y -= _viewport.Y / scale.Y;
  123.  
  124.             return worldPoint;
  125.         }
  126.  
  127.         /// <summary>
  128.         /// Convert a point in screen coordinates to world coorindates.
  129.         /// </summary>
  130.         /// <param name="screenPoint">A point relative to screen coordinates</param>
  131.         /// <returns>The point converted to world coordinates.</returns>
  132.         public Vector2 PointToWorld(Point screenPoint)
  133.         {
  134.             return PointToWorld(new Vector2(screenPoint.X, screenPoint.Y));
  135.         }
  136.  
  137.         /// <summary>
  138.         /// Convert a point in world coordiantes to screen coordinates.
  139.         /// </summary>
  140.         /// <param name="worldPoint">A point relative to world coordinates.</param>
  141.         /// <returns>The point converted to screen coordinates.</returns>
  142.         public Vector2 PointToScreen(Vector2 worldPoint)
  143.         {
  144.             Vector2 screenPoint = worldPoint;
  145.  
  146.             Vector3 scale = this.Scale;
  147.  
  148.             screenPoint.X += _viewport.X / scale.X;
  149.             screenPoint.Y += _viewport.Y / scale.Y;
  150.  
  151.             screenPoint.X *= scale.X;
  152.             screenPoint.Y *= scale.Y;
  153.  
  154.             return screenPoint;
  155.         }
  156.  
  157.         /// <summary>
  158.         /// Convert a point in world coordiantes to screen coordinates.
  159.         /// </summary>
  160.         /// <param name="worldPoint">A point relative to world coordinates.</param>
  161.         /// <returns>The point converted to screen coordinates.</returns>
  162.         public Vector2 PointToScreen(Point worldPoint)
  163.         {
  164.             return PointToScreen(new Vector2(worldPoint.X, worldPoint.Y));
  165.         }
  166.  
  167.         /// <summary>
  168.         /// Apply this screen manager's settings to the specified graphics device manager object. This should be called during initialization, or when screen dimensions need to change.
  169.         /// </summary>
  170.         /// <param name="manager">An object responsible for managing a graphics device.</param>
  171.         public void ApplySettings(IGrfxDeviceManager manager)
  172.         {
  173.             manager.PreferredBackBufferWidth = this.Screen.X;
  174.             manager.PreferredBackBufferHeight = this.Screen.Y;
  175.             manager.IsFullScreen = this.IsFullScreen;
  176.  
  177.             manager.ApplyChanges();
  178.         }
  179.  
  180.         /// <summary>
  181.         /// Set the specified graphics device up for rendering. This should be called at the start of a draw/render pass.
  182.         /// </summary>
  183.         /// <param name="device">An object responisible for representing a graphics device.</param>
  184.         public void BeginDraw(IGrfxDevice device)
  185.         {
  186.             device.Clear(Color.Black);
  187.  
  188.             device.Viewport = new Viewport(0, 0, this.Screen.X, this.Screen.Y);
  189.             if (this.Options != null && this.Options.ScreenBackground != null)
  190.             {
  191.                 this.Options.SpriteBatch.Begin();
  192.                 this.Options.SpriteBatch.Draw(this.Options.ScreenBackground.Texture, new Rectangle(0, 0, this.Screen.X, this.Screen.Y), this.Options.ScreenBackground.Mask);
  193.                 this.Options.SpriteBatch.End();
  194.             }
  195.  
  196.             device.Viewport = _viewport;
  197.  
  198.             if (this.Options != null && this.Options.WorldBackground != null)
  199.             {
  200.                 this.Options.SpriteBatch.Begin();
  201.                 this.Options.SpriteBatch.Draw(this.Options.WorldBackground.Texture, new Rectangle(0, 0, _viewport.Width, _viewport.Height), this.Options.WorldBackground.Mask);
  202.                 this.Options.SpriteBatch.End();
  203.             }
  204.         }
  205.         #endregion
  206.  
  207.         #region Private Methods
  208.         private void CalculateViewport()
  209.         {
  210.             float worldAspectRatio = this.World.X / (float)this.World.Y;
  211.  
  212.             int width = (int)this.Screen.X;
  213.             int height = (int)(width / worldAspectRatio + 0.5f);
  214.  
  215.             if (height > this.Screen.Y)
  216.             {
  217.                 height = this.Screen.Y;
  218.                 width = (int)(height * worldAspectRatio + 0.5f);
  219.             }
  220.  
  221.             _viewport = new Viewport();
  222.             _viewport.X = (this.Screen.X / 2) - (width / 2);
  223.             _viewport.Y = (this.Screen.Y / 2) - (height / 2);
  224.             _viewport.Width = width;
  225.             _viewport.Height = height;
  226.             _viewport.MinDepth = 0;
  227.             _viewport.MaxDepth = 1;
  228.  
  229.             _matrixNeedsUpdate = true;
  230.         }
  231.         #endregion
  232.     }
  233. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement