/* * Ticker.cs * Authors: August Zinsser * * Copyright Matthew Belmonte 2007 */ using System; using System.Collections.Generic; using System.Text; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Content; using Nuclex.Fonts; namespace tAC_Engine { /// /// Displays text and/or pictures in various manners on top of all other graphics. /// This is uesful for outputting text to a HUD or displaying popup text or graphics. /// public static class Ticker { /// /// Defines the possible fonts to use with the text ticker /// public enum Font { Standard, Standard_Big, Space, Space_Big, InGame_Tiny }; /// /// Holds the information necsesary to display message /// private class Message { public Vector2 Position = Vector2.Zero; public Vector2 Velocity = Vector2.Zero; public int Width = 0; public int Height = 0; public int ImageWidth = 0; public int ImageHeight = 0; public bool FadesIn = false; public bool FadesOut = false; public Color Tint = Color.White; public float CurOpacity = 1f; public float FinOpacity = 1f; public string Text = ""; public float Lifetime = 0f; public Texture2D Image = null; public Ticker.Font Font = Ticker.Font.Standard; /// /// Draws this message to its own spritebatch /// public void Draw(SpriteBatch spriteBatch) { int padding = 0; if (Image != null) { spriteBatch.Draw(Image, new Rectangle((int)Position.X - Width / 2 - 5 - ImageWidth / 2, (int)Position.Y - ImageHeight / 2, (int)ImageWidth, (int)ImageHeight), new Color(Tint.R, Tint.G, Tint.B, (byte)(255 * CurOpacity))); padding = 5; } switch (Font) { case Ticker.Font.Standard: GenericBaseApplication.GameManager.StandardFont.DrawString(new Vector2((int)Position.X - Width / 2 + padding + ImageWidth / 2, (int)Position.Y + Height / 2), Text, new Color(Tint.R, Tint.G, Tint.B, (byte)(255 * CurOpacity))); break; case Ticker.Font.Standard_Big: GenericBaseApplication.GameManager.StandardFontBig.DrawString(new Vector2((int)Position.X - Width / 2 + padding + ImageWidth / 2, (int)Position.Y + Height / 2), Text, new Color(Tint.R, Tint.G, Tint.B, (byte)(255 * CurOpacity))); break; case Ticker.Font.Space: GenericBaseApplication.GameManager.SpaceFont.DrawString(new Vector2((int)Position.X - Width / 2 + padding + ImageWidth / 2, (int)Position.Y + Height / 2), Text, new Color(Tint.R, Tint.G, Tint.B, (byte)(255 * CurOpacity))); break; case Ticker.Font.Space_Big: GenericBaseApplication.GameManager.SpaceFontBig.DrawString(new Vector2((int)Position.X - Width / 2 + padding + ImageWidth / 2, (int)Position.Y + Height / 2), Text, new Color(Tint.R, Tint.G, Tint.B, (byte)(255 * CurOpacity))); break; case Ticker.Font.InGame_Tiny: GenericBaseApplication.GameManager.InGameFontTiny.DrawString(new Vector2((int)Position.X - Width / 2 + padding + ImageWidth / 2, (int)Position.Y + Height / 2), Text, new Color(Tint.R, Tint.G, Tint.B, (byte)(255 * CurOpacity))); break; } } } private static SpriteBatch mSpriteBatch = new SpriteBatch(GenericBaseApplication.GameManager.GraphicsDevice); private static List mMessages = new List(); private static float mFadeTime = 1f; /// /// Displays a string and/or graphic on top of all other graphics /// /// Offset in pixels to draw the message, relative to the screen's center and the message's center /// Which font to use /// The string to display /// Duration to display the message /// Whether or not to fade in and fade out the message /// The image to display /// Velocity (in pixels/second) to scroll the text public static void Display(string text, Texture2D image, Vector2 imageSize, Vector2 offsetFromCenter, Vector2 velocity, Ticker.Font font, Color color, float opacity, float seconds, bool fade) { Message mes = new Message(); mes.Text = text; mes.Image = image; mes.Position = new Vector2(GenericBaseApplication.GameManager.ScreenWidth / 2f + offsetFromCenter.X, GenericBaseApplication.GameManager.ScreenHeight / 2f + offsetFromCenter.Y); mes.Velocity = velocity; mes.ImageWidth = (int)imageSize.X; mes.ImageHeight = (int)imageSize.Y; mes.Font = font; mes.Tint = color; mes.Lifetime = seconds; mes.FinOpacity = opacity; mes.FadesIn = fade; mes.FadesOut = fade; if (fade) mes.CurOpacity = 0f; else mes.CurOpacity = opacity; // Find the string's dimensions Rectangle size = Rectangle.Empty; switch (font) { case Ticker.Font.Standard: size = GenericBaseApplication.GameManager.StandardFont.MeasureString(text); break; case Ticker.Font.Standard_Big: size = GenericBaseApplication.GameManager.StandardFontBig.MeasureString(text); break; case Ticker.Font.Space: size = GenericBaseApplication.GameManager.SpaceFont.MeasureString(text); break; case Ticker.Font.Space_Big: size = GenericBaseApplication.GameManager.SpaceFontBig.MeasureString(text); break; case Ticker.Font.InGame_Tiny: size = GenericBaseApplication.GameManager.InGameFontTiny.MeasureString(text); break; } mes.Width = size.Width; mes.Height = size.Height; mMessages.Add(mes); } /// /// Call this during the main game's update cycle /// /// public static void Update() { float dT = GenericBaseApplication.GameManager.ElapsedSeconds; List deathRow = new List(); foreach (Message message in mMessages) { // Update clock message.Lifetime -= dT; // Alter position message.Position += message.Velocity * dT; // Alter opacity if (message.FadesIn && message.CurOpacity < message.FinOpacity) { message.CurOpacity += dT * mFadeTime; if (message.CurOpacity >= message.FinOpacity) { message.FadesIn = false; message.CurOpacity = message.FinOpacity; } } if (message.FadesOut && message.Lifetime < 0) { message.CurOpacity -= dT * mFadeTime; } if (message.CurOpacity < 0) message.CurOpacity = 0f; // Check for expired messages if (message.Lifetime < 0 && !message.FadesOut || message.Lifetime < 0 - mFadeTime && message.FadesOut) deathRow.Add(message); } // Remove expired messages foreach (Message corpse in deathRow) mMessages.Remove(corpse); } /// /// Draws all registered text on a new spritebatch /// public static void Draw() { // Minimize creation of spritebatches if (mMessages.Count == 0) return; mSpriteBatch.Begin(SpriteBlendMode.AlphaBlend, SpriteSortMode.Texture, SaveStateMode.None); foreach (Message message in mMessages) message.Draw(mSpriteBatch); mSpriteBatch.End(); } } }