/*
* Message.cs
* Authors: August Zinsser, Adam Nabinger
* Copyright (c) 2007-2008 Cornell University
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;
using Util;
namespace MaritimeDefender
{
///
/// 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 class Message
{
#region Constants
///
/// Constant value for the duration of time for fading out
///
public const int FADE_TIME = 1;
#endregion
#region Fields
// The content manager used for loading content
private ContentManager mContent;
// The sprite batch used for rendering textures
private SpriteBatch mSpriteBatch;
// The texture to render
private Texture2D mImage;
// The sprite font used for rendering text
private SpriteFont mFont;
// The path name of the texture file to use
private string mImagePath;
// The path name of the sprite font to use
private string mFontPath;
// The text to be displayed in the message
private string mText = string.Empty;
// The position of the message via 2 dimensions
private Vector2 mPosition;
// The velocity of the message via 2 dimensions
private Vector2 mVelocity;
// The width of the message
private int mWidth;
// The height of the message
private int mHeight;
// Whether or not the message fades in
private bool mFadesIn;
// Whether or not the message fades out
private bool mFadesOut;
// The coloring tint of the message
private Color mTint = Color.White;
// The current opacity of the message
private float mCurOpacity = 1f;
// The opacity of the message at the end of fading out
private float mFinOpacity = 1f;
// The lifetime of the message
private float mLifetime;
// The scale size of the message
private float mScale = 1f;
#endregion
#region Properties
///
/// Sets the sprite batch object used for rendering textures
///
public SpriteBatch SpriteBatch { set { mSpriteBatch = value; } }
///
/// Gets whether or not the meesage fades out
///
public bool FadesOut { get { return mFadesOut; } }
///
/// Gets the lifetime of the message
///
public float Lifetime { get { return mLifetime; } }
///
/// Sets the scale size of the message
///
public float Scale { set { mScale = value; } }
#endregion
#region Creation
///
/// Displays a string and/or graphic on top of all other graphics
///
/// The content manager used to load/unload graphics content with
/// The string to display
/// The path of the image
/// Which font to use
/// Offset in pixels to draw the message, relative to the screen's center and the message's center
/// The speed and direction of the image and font
/// The color of the image and font
/// How transparent the image and font are
/// Duration to display the message
/// Whether or not to fade in and fade out the message
/// Velocity (in pixels/second) to scroll the text
public Message(ContentManager content, string text, string imagePath, string fontPath, Vector2 offsetFromCenter,
Vector2 velocity, Color color, float opacity, float seconds, bool fade, Viewport Viewport)
: base()
{
mContent = content;
mText = text;
mImagePath = imagePath;
mFontPath = fontPath;
mPosition = new Vector2((Viewport.Width >> 1) + offsetFromCenter.X, (Viewport.Height >> 1) + offsetFromCenter.Y);
mVelocity = velocity;
mTint = color;
mLifetime = seconds;
mFinOpacity = opacity;
mFadesIn = fade;
mFadesOut = fade;
mCurOpacity = fade ? 0f : opacity;
LoadContent();
}
#endregion
#region Management
///
/// Load in necessary graphics content
///
public void LoadContent()
{
if (mImagePath != null)
{
mImage = mContent.Load(mImagePath);
}
if (mText != null && mFontPath != null)
{
mFont = mContent.Load(mFontPath);
// Find the string's dimensions
mWidth = (int)mFont.MeasureString(mText).X;
mHeight = (int)mFont.MeasureString(mText).Y;
}
}
#endregion
#region Update
///
/// Call this during the main game's update cycle
///
public void Update(GameTime gameTime)
{
float dT = (float)gameTime.ElapsedGameTime.TotalSeconds;
// Update lifetime
mLifetime -= dT;
// Alter position
mPosition += mVelocity * dT;
// Alter opacity
if (mFadesIn && mCurOpacity < mFinOpacity)
{
mCurOpacity += dT * FADE_TIME;
if (mCurOpacity >= mFinOpacity)
{
mFadesIn = false;
mCurOpacity = mFinOpacity;
}
}
if (mFadesOut && mLifetime < 0)
{
mCurOpacity -= dT * FADE_TIME;
}
if (mCurOpacity < 0)
{
mCurOpacity = 0f;
}
}
#endregion
#region Render
///
/// Draws all registered text on a new spritebatch
///
public void Draw()
{
int paddingX = 0;
if (mImage != null)
{
paddingX = (int)(mImage.Width * mScale) >> 1;
mSpriteBatch.Draw(mImage, new Rectangle((int)(mPosition.X - (mImage.Width * mScale)), (int)mPosition.Y - (((int)(mImage.Height * mScale)) >> 1), ((int)(mImage.Width * mScale)), ((int)(mImage.Height * mScale))), new Color(mTint.R, mTint.G, mTint.B, (byte)(255 * mCurOpacity)));
}
mSpriteBatch.DrawString(mFont, mText, new Vector2((int)mPosition.X - (mWidth >> 1) + paddingX, (int)mPosition.Y), new Color(mTint.R, mTint.G, mTint.B, (byte)(255 * mCurOpacity)));
}
#endregion
#region Predicates
///
/// Check for and Remove expired messages
///
public static readonly Predicate NotAlive = new Predicate(delegate(Message m)
{
return (m.Lifetime < 0 && !m.FadesOut) || (m.Lifetime + FADE_TIME < 0 && m.FadesOut);
});
#endregion
}
}