diff --git a/UI/ColorBox.cs b/UI/ColorBox.cs index be1a97c..6fc68a5 100644 --- a/UI/ColorBox.cs +++ b/UI/ColorBox.cs @@ -10,12 +10,13 @@ public class ColorBox : UserInterfaceElement { public Color DrawColor; - public ColorBox(Color color, Vector2 relativeSize, Vector2 relativePos, Vector2 origin) + public ColorBox(Color color, Vector2 relativeSize, Vector2 relativePos, Vector2 origin, Int32 defaultScreenHeight = 540) { DrawColor = color; RelativeSize = relativeSize; RelativePosition = relativePos; RotationOrigin = origin; + DefaultDrawAreaHeight = defaultScreenHeight; } protected override void DrawElement(GameTime gameTime, SpriteBatch spriteBatch, Rectangle drawArea, float turn) { diff --git a/UI/ProgressBar.cs b/UI/ProgressBar.cs new file mode 100644 index 0000000..320a215 --- /dev/null +++ b/UI/ProgressBar.cs @@ -0,0 +1,59 @@ +using System; +using System.Collections.Generic; +using System.Text; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; + +namespace DotRPG.UI +{ + public class ProgressBar : UserInterfaceElement + { + public Color ForegroundColor; + public Color BackgroundColor; + Single _p = 0.0f; + public Single Progress_Percentage + { + get + { + return 100.0f * _p; + } + set + { + _p = Math.Max(0.0f, Math.Min(1.0f, value / 100.0f)); + } + } + + public ProgressBar(Color fgColor, Color ? bgColor, Vector2 relativeSize, Vector2 relativePosition, Int32 DefaultScreenHeight = 540) + { + ForegroundColor = fgColor; + BackgroundColor = bgColor ?? Color.Transparent; + RelativeSize = relativeSize; + RelativePosition = relativePosition; + DefaultDrawAreaHeight = DefaultScreenHeight; + } + + public override void Update(GameTime gameTime) + { + throw new NotImplementedException(); + } + + protected override void DrawElement(GameTime gameTime, SpriteBatch spriteBatch, Rectangle drawArea, float turn) + { + Vector2 v = new Vector2(drawArea.X + (drawArea.Width * RelativePosition.X), drawArea.Y + (drawArea.Height * RelativePosition.Y)); + Texture2D t1 = new Texture2D(spriteBatch.GraphicsDevice, (Int32)(drawArea.Width * RelativeSize.X), (Int32)Math.Ceiling(drawArea.Height * RelativeSize.Y)); + Texture2D t2 = new Texture2D(spriteBatch.GraphicsDevice, Math.Max((Int32)(t1.Width * _p), 1), t1.Height); + + Color[] d1 = new Color[t1.Width * t1.Height]; + Color[] d2 = new Color[t2.Width * t2.Height]; + + for (int i = 0; i < d1.Length; i++) d1[i] = BackgroundColor; + for (int i = 0; i < d2.Length; i++) d2[i] = ForegroundColor; + + t1.SetData(d1); + t2.SetData(d2); + + spriteBatch.Draw(t1, v, new Rectangle(0, 0, t1.Width, t1.Height), Color.White, Rotation + turn, new Vector2(t1.Width * RotationOrigin.X, t1.Height * RotationOrigin.Y), 1.0f, SpriteEffects.None, 0.1f); + spriteBatch.Draw(t2, v, new Rectangle(0, 0, t2.Width, t2.Height), Color.White, Rotation + turn, new Vector2(t1.Width * RotationOrigin.X, t1.Height * RotationOrigin.Y), 1.0f, SpriteEffects.None, 0.0f); + } + } +} diff --git a/UI/SharedGraphicsMethods.cs b/UI/SharedGraphicsMethods.cs index 3fb3ead..c457b4f 100644 --- a/UI/SharedGraphicsMethods.cs +++ b/UI/SharedGraphicsMethods.cs @@ -70,6 +70,15 @@ public static Rectangle FindEmbedDrawArea(Rectangle drawArea, Vector2 offset, Ve ); } + public static Rectangle ApplyPadding(Rectangle source, Vector4 padding, Single sizeMorph) + { + return new Rectangle( + source.X + (Int32)(padding.X * sizeMorph), + source.Y + (Int32)(padding.Y * sizeMorph), + source.Width - (Int32)(padding.X * sizeMorph) - (Int32)(padding.Z * sizeMorph), + source.Height - (Int32)(padding.Y * sizeMorph) - (Int32)(padding.W * sizeMorph) + ); + } public static Vector2 FindTextAlignment(SpriteFont sf, String line, Rectangle scr, Single AlignX, Single AlignY, Vector2 InitialFieldOffset, AlignMode anchor = AlignMode.Center, Single rescale = 1.0f) { Vector2 str = sf.MeasureString(line) * rescale; diff --git a/UI/UserInterfaceElement.cs b/UI/UserInterfaceElement.cs index e617fc0..ca8dd17 100644 --- a/UI/UserInterfaceElement.cs +++ b/UI/UserInterfaceElement.cs @@ -11,6 +11,8 @@ public abstract class UserInterfaceElement public readonly HashSet Subnodes = new HashSet(); public Single Rotation { get; set; } = 0.0f; public Int32 DefaultDrawAreaHeight { get; set; } + public Vector4 ElementPadding { get; set; } = Vector4.Zero; + public Vector4 SubnodePadding { get; set; } = Vector4.Zero; public Vector2 RelativeSize { get; set; } public Vector2 RelativePosition { get; set; } public Vector2 RotationOrigin { get; set; } = new Vector2(0.5f, 0.5f); @@ -18,8 +20,10 @@ public abstract class UserInterfaceElement protected abstract void DrawElement(GameTime gameTime, SpriteBatch spriteBatch, Rectangle drawArea, Single turn); public void Draw(GameTime gameTime, SpriteBatch spriteBatch, Rectangle drawArea, Single turn = 0) { + Single sizeMorph = 1.0f * drawArea.Height / DefaultDrawAreaHeight; + drawArea = SharedGraphicsMethods.ApplyPadding(drawArea, ElementPadding, sizeMorph); DrawElement(gameTime, spriteBatch, drawArea, turn); - Rectangle newDrawRect = SharedGraphicsMethods.FindEmbedDrawArea(drawArea, RelativePosition, RelativeSize); + Rectangle newDrawRect = SharedGraphicsMethods.ApplyPadding(SharedGraphicsMethods.FindEmbedDrawArea(drawArea, RelativePosition, RelativeSize), SubnodePadding, sizeMorph); foreach (UserInterfaceElement ui in Subnodes) { diff --git a/_Example/Game1.cs b/_Example/Game1.cs index 3605720..a035a6f 100644 --- a/_Example/Game1.cs +++ b/_Example/Game1.cs @@ -23,6 +23,7 @@ public class Game1 : Game private List FrameNames = new List(); private List Frames = new List(); private Frame ActiveFrame; + private Frame ActiveSubframe; private TextObject PressStart; private GraphicsDeviceManager _graphics; private SpriteBatch _spriteBatch; @@ -169,11 +170,12 @@ protected override void Update(GameTime gameTime) } if (ActiveFrame != null) { - if (ActiveFrame is LoadingScreen l) + if (ActiveSubframe is LoadingScreen l) { if (l.LoadedFrame.Loaded) { ActiveFrame = l.LoadedFrame as Frame; + ActiveSubframe = null; } if (ActiveFrame == null) { @@ -185,7 +187,7 @@ protected override void Update(GameTime gameTime) Frame toLoad = Frames[stageSelect.SelectedOption]; if (toLoad is ILoadable load) { - ActiveFrame = new LoadingScreen(load, this, ResourceHGlobal, LogicEventSet); + ActiveSubframe = new LoadingScreen(load, this, ResourceHGlobal, LogicEventSet); } else { @@ -241,7 +243,11 @@ protected override void Update(GameTime gameTime) } } - if (ActiveFrame != null) + if (ActiveSubframe != null) + { + ActiveSubframe.Update(gameTime, IsCtrlKeyDown); + } + else if (ActiveFrame != null) { ActiveFrame.Update(gameTime, IsCtrlKeyDown); } @@ -301,6 +307,10 @@ protected override void Draw(GameTime gameTime) { ActiveFrame.Draw(gameTime, _spriteBatch); } + if (ActiveSubframe != null) + { + ActiveSubframe.Draw(gameTime, _spriteBatch); + } #if DEBUG _spriteBatch.DrawString(_spriteFont, "FPS: " + FrameRate.ToString() + " || Fullscreen: " + FullScreen.ToString() + String.Format(" || Resolution: {0}x{1}", Window.ClientBounds.Width, Window.ClientBounds.Height) + " || Frame active: " + (ActiveFrame != null ? ActiveFrame.FrameID.ToString() : "-1") + " || Update rate: " + Math.Round(1000 / LastRegisteredEventTime), new Vector2(0, 0), (FrameRate > 50 ? Color.White : (FrameRate > 24 ? Color.Yellow : Color.Red))); #endif diff --git a/_Example/LoadingScreen.cs b/_Example/LoadingScreen.cs index c35f14d..955eee0 100644 --- a/_Example/LoadingScreen.cs +++ b/_Example/LoadingScreen.cs @@ -14,6 +14,10 @@ class LoadingScreen : Frame { public FrameLoader Loader; TextObject percentage; + ProgressBar progress; + ColorBox cb; + Single timeCountdown; + public ILoadable LoadedFrame { get @@ -35,7 +39,13 @@ public override int FrameID public LoadingScreen(ILoadable il, Game owner, ResourceHeap globalGameResources, HashSet globalEventSet) : base(owner, globalGameResources, globalEventSet) { Loader = new FrameLoader(il); - percentage = new TextObject(globalGameResources.Fonts["vcr_large"], "00.0%", 0.5f, 0.35f, Color.White, AlignMode.BottomCenter, 1080); + percentage = new TextObject(globalGameResources.Fonts["vcr_large"], "0%", 0.5f, 0.35f, Color.White, AlignMode.BottomCenter, 540); + progress = new ProgressBar(Color.Gray, Color.Black, new Vector2(0.75f, 0.05f), new Vector2(0.5f, 0.55f)); + progress.RotationOrigin = new Vector2(0.5f, 0.0f); + cb = new ColorBox(new Color(0, 0, 75), new Vector2(0.75f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f)); + cb.SubnodePadding = new Vector4(4.0f); + cb.Subnodes.Add(percentage); + cb.Subnodes.Add(progress); } public override void SetPlayerPosition(object sender, EventArgs e, GameTime gameTime) { @@ -43,34 +53,19 @@ public override void SetPlayerPosition(object sender, EventArgs e, GameTime game } public override void Update(GameTime gameTime, bool[] controls) { - Loader.Update(); + timeCountdown += (Single)gameTime.ElapsedGameTime.TotalSeconds; + cb.RelativeSize = new Vector2(0.75f, Math.Max(0.01f, Math.Min(0.5f, timeCountdown*4))); + if (timeCountdown > 0.125f) + { + Loader.Update(); + } + progress.Progress_Percentage = Loader.LoadPercentage; percentage.Text = Loader.LoadPercentage.ToString() + "%"; base.Update(gameTime, controls); } public override void Draw(GameTime gameTime, SpriteBatch spriteBatch, Rectangle drawZone) { - Vector2 v = new Vector2(drawZone.X + (drawZone.Width / 8), drawZone.Y + (drawZone.Height / 2)); - Texture2D t1 = new Texture2D(spriteBatch.GraphicsDevice, drawZone.Width * 3 / 4, drawZone.Height / 20); - Texture2D t2 = new Texture2D(spriteBatch.GraphicsDevice, Math.Max(drawZone.Width * 3 / 4 * (Loader.Loaded.ContentTasks_Done / Loader.Loaded.ContentTasks_Total), 1), drawZone.Height / 20); - Texture2D t3 = new Texture2D(spriteBatch.GraphicsDevice, Math.Max(drawZone.Width * 3 / 4 * (Int32)Loader.LoadPercentage/100, 1), drawZone.Height / 20); - - Color[] d1 = new Color[drawZone.Width * 3 / 4 * drawZone.Height / 20]; - Color[] d2 = new Color[Math.Max(drawZone.Width * 3 / 4 * (Loader.Loaded.ContentTasks_Done / Loader.Loaded.ContentTasks_Total), 1) * drawZone.Height / 20]; - Color[] d3 = new Color[Math.Max(drawZone.Width * 3 / 4 * (Int32)Loader.LoadPercentage / 100, 1) * drawZone.Height / 20]; - - for (int i = 0; i < d1.Length; i++) d1[i] = new Color(75, 75, 75); - for (int i = 0; i < d2.Length; i++) d2[i] = Color.Gray; - for (int i = 0; i < d3.Length; i++) d3[i] = Color.White; - - t1.SetData(d1); - t2.SetData(d2); - t3.SetData(d3); - - spriteBatch.Draw(t1, v, Color.White); - spriteBatch.Draw(t2, v, Color.White); - spriteBatch.Draw(t3, v, Color.White); - - percentage.Draw(gameTime, spriteBatch, drawZone); + cb.Draw(gameTime, spriteBatch, drawZone); } public override void Initialize() { diff --git a/_Example/Program.cs b/_Example/Program.cs index 7439df6..ffe0b55 100644 --- a/_Example/Program.cs +++ b/_Example/Program.cs @@ -10,15 +10,19 @@ public static class Program [STAThread] static void Main() { +#if !DEBUG try { +#endif using (var game = new Game1()) game.Run(); - } +#if !DEBUG + } catch (Exception e) { File.WriteAllText("error-" + DateTime.Now + ".txt", e.Message); } +#endif } } }