#region File Description
//-----------------------------------------------------------------------------
// ScoreBar.cs
//
// Microsoft XNA Community Game Platform
// Copyright (C) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
#endregion
#region Using Statements
using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
#endregion
namespace HoneycombRush
{
///
/// Used by other components to display their status.
///
public class ScoreBar : DrawableGameComponent
{
#region Enums
///
/// Used to determine the component's orientation.
///
public enum ScoreBarOrientation
{
Vertical,
Horizontal
}
#endregion
#region Fields/Properties
public int MinValue { get; set; }
public int MaxValue { get; set; }
public Vector2 Position { get; set; }
public Color ScoreBarColor { get; set; }
public int CurrentValue
{
get
{
return currentValue;
}
}
ScoreBarOrientation scoreBarOrientation;
int height;
int width;
ScaledSpriteBatch scaledSpriteBatch;
int currentValue;
Texture2D backgroundTexture;
Texture2D redTexture;
Texture2D greenTexture;
Texture2D yellowTexture;
GameplayScreen gameplayScreen;
bool isAppearAtCountDown;
#endregion
#region Initialization
///
/// Creates a new score bar instance.
///
/// The associated game object.
/// The score bar's minimal value.
/// The score bar's maximal value.
/// The score bar's position.
/// The score bar's height.
/// The score bar's width.
/// Color to tint the scorebar's background with.
/// The score bar's orientation.
/// The score bar's initial value.
/// Gameplay screen where the score bar will appear.
/// Whether or not the score bar will appear during the game's initial
/// countdown phase.
public ScoreBar(Game game, int minValue, int maxValue, Vector2 position, int height, int width,
Color scoreBarColor, ScoreBarOrientation scoreBarOrientation, int initialValue, GameplayScreen screen,
bool isAppearAtCountDown)
: base(game)
{
this.MinValue = minValue;
this.MaxValue = maxValue;
this.Position = position;
this.ScoreBarColor = scoreBarColor;
this.scoreBarOrientation = scoreBarOrientation;
this.currentValue = initialValue;
this.width = width;
this.height = height;
this.gameplayScreen = screen;
this.isAppearAtCountDown = isAppearAtCountDown;
scaledSpriteBatch = (ScaledSpriteBatch)Game.Services.GetService(typeof(ScaledSpriteBatch));
GetSpaceFromBorder();
}
///
/// Loads the content that this component will use.
///
protected override void LoadContent()
{
backgroundTexture = Game.Content.Load("Textures/barBlackBorder");
greenTexture = Game.Content.Load("Textures/barGreen");
yellowTexture = Game.Content.Load("Textures/barYellow");
redTexture = Game.Content.Load("Textures/barRed");
base.LoadContent();
}
#endregion
#region Render
///
/// Draws the component.
///
///
public override void Draw(GameTime gameTime)
{
if (!gameplayScreen.IsActive)
{
base.Draw(gameTime);
return;
}
if (!isAppearAtCountDown && !gameplayScreen.IsStarted)
{
base.Draw(gameTime);
return;
}
float rotation;
// Determine the orientation of the component
if (scoreBarOrientation == ScoreBar.ScoreBarOrientation.Horizontal)
{
rotation = 0f;
}
else
{
rotation = 1.57f;
}
scaledSpriteBatch.Begin();
// Draws the background of the score bar
scaledSpriteBatch.Draw(backgroundTexture, new Rectangle((int)Position.X, (int)Position.Y, width, height),
null, ScoreBarColor, rotation, new Vector2(0, 0), SpriteEffects.None, 0);
// Gets the margin from the border
decimal spaceFromBorder = GetSpaceFromBorder();
spaceFromBorder += 4;
Texture2D coloredTexture = GetTextureByCurrentValue(currentValue);
if (scoreBarOrientation == ScoreBarOrientation.Horizontal)
{
scaledSpriteBatch.Draw(coloredTexture, new Rectangle((int)Position.X + 2, (int)Position.Y + 2,
width - (int)spaceFromBorder, height - 4), null, Color.White, rotation, new Vector2(0, 0),
SpriteEffects.None, 0);
}
else
{
scaledSpriteBatch.Draw(coloredTexture, new Rectangle((int)Position.X + 2 - height,
(int)Position.Y + width + -2, width - (int)spaceFromBorder, height - 4), null, ScoreBarColor,
-rotation, new Vector2(0, 0), SpriteEffects.None, 0);
}
scaledSpriteBatch.End();
base.Draw(gameTime);
}
#endregion
#region Public Methods
///
/// Increases the current value of the score bar.
///
/// Number to increase the value by
/// Negative numbers will have no effect.
public void IncreaseCurrentValue(int valueToIncrease)
{
// Make sure that the target value does not exceed the max value
if (valueToIncrease >= 0 && currentValue < MaxValue && currentValue + valueToIncrease <= MaxValue)
{
currentValue += valueToIncrease;
}
// If the target value exceeds the max value, clamp the value to the maximum
else if (currentValue + valueToIncrease > MaxValue)
{
currentValue = MaxValue;
}
}
///
/// Decreases the current value of the score bar.
///
/// Number to decrease the value by.
public void DecreaseCurrentValue(int valueToDecrease)
{
DecreaseCurrentValue(valueToDecrease, false);
}
///
/// Decreases the current value of the score bar.
///
/// Number to decrease the value by.
/// If true, then decreasing by an amount which will cause the bar's value
/// to go under its minimum will set the bar to its minimal value. If false, performing such an operation
/// as just described will leave the bar's value unchanged.
/// The actual amount which was subtracted from the bar's value.
public int DecreaseCurrentValue(int valueToDecrease, bool clampToMinimum)
{
// Make sure that the target value does not exceed the min value
int valueThatWasDecreased = 0;
if (valueToDecrease >= 0 && currentValue > MinValue && currentValue - valueToDecrease >= MinValue)
{
currentValue -= valueToDecrease;
valueThatWasDecreased = valueToDecrease;
}
// If the target value exceeds the min value, clamp the value to the minimum (or do nothing)
else if (currentValue - valueToDecrease < MinValue && clampToMinimum)
{
valueThatWasDecreased = currentValue - MinValue;
currentValue = MinValue;
}
return valueThatWasDecreased;
}
#endregion
#region Private Methods
///
/// Calculate the empty portion of the score bar according to its current value.
///
/// Width of the bar portion which should be empty to represent the bar's current score.
private decimal GetSpaceFromBorder()
{
int textureSize;
textureSize = width;
decimal valuePercent = Decimal.Divide(currentValue, MaxValue) * 100;
return textureSize - ((decimal)textureSize * valuePercent / (decimal)100);
}
///
/// Returns a texture for the score bar's "fill" according to its value.
///
/// Current value of the score bar.
/// A texture the color of which indicates how close to the bar's maximum the value is.
private Texture2D GetTextureByCurrentValue(int value)
{
Texture2D selectedTexture;
decimal valuePercent = Decimal.Divide(currentValue, MaxValue) * 100;
if (valuePercent > 50)
{
selectedTexture = greenTexture;
}
else if (valuePercent > 25)
{
selectedTexture = yellowTexture;
}
else
{
selectedTexture = redTexture;
}
return selectedTexture;
}
#endregion
}
}