#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 } }