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