//---------------------------------------------------------------------------------------------------------------------------------------------------
//
// Copyright (C)2007 DarkWynter Studios. All rights reserved.
//
//---------------------------------------------------------------------------------------------------------------------------------------------------
// {License Information: Creative Commons}
//---------------------------------------------------------------------------------------------------------------------------------------------------
namespace ElementalGame
{
#region Using Statements
using System;
using System.Collections.Generic;
using System.Collections;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Storage;
#endregion
// Class which allows us to draw our Heads-up-display
public class HeadsUpDisplay
{
// Attributes:
// Screen dead zone percentage
private const float SIDES_DEAD_ZONE_PERCENT = 0.05f;
private const float TOP_BOTTOM_DEAD_ZONE_PERCENT = 0.03f;
private int playerIndex = 0;
public Viewport parentViewport;
// List of Text Displays
private List textDisplays = new List();
// List of Value Displays
private List valueDisplays = new List();
// List of Image Displays
private List imageDisplays = new List();
private List imageSpinners = new List();
public enum DisplayType
{
TEXT,
VALUE,
IMAGE,
BASE
};
// Base class for all types
public class HUDDisplay
{
public string text;
public Vector2 position = new Vector2();
public int width;
public int height;
public Color color;
public DisplayType type = DisplayType.BASE;
public bool visible = true;
};
// Used to display Text
private class TextDisplay : HUDDisplay
{
public TextDisplay()
{
type = DisplayType.TEXT;
}
}
// Used to display Values
private class ValueDisplay : HUDDisplay
{
public float value;
public ValueDisplay()
{
type = DisplayType.VALUE;
}
}
// Used to display Images
public class ImageDisplay : HUDDisplay
{
public Texture2D image;
public float xScale;
public float yScale;
public ImageDisplay()
{
xScale = 1.0f;
yScale = 1.0f;
type = DisplayType.IMAGE;
}
}
public class ImageSpinner : HUDDisplay
{
public ImageDisplay[] images;
public int activeIndex;
public ImageSpinner(int size)
{
this.activeIndex = 0;
this.images = new ImageDisplay[size];
}
public void addImage(ImageDisplay val, int slot)
{
images[slot] = val;
}
public void next()
{
if (this.images.Length <= this.activeIndex + 1)
{
this.activeIndex = 0;
}
else
{
this.activeIndex++;
}
}
public void prev()
{
if (this.activeIndex == 0)
{
this.activeIndex = this.images.Length - 1;
}
else
{
this.activeIndex--;
}
}
}
// Constructor
public HeadsUpDisplay()
{
playerIndex = 0;
}
public HeadsUpDisplay(int index, Viewport viewport)
{
playerIndex = index;
parentViewport = viewport;
}
// Methods:
//*******************************************************************************************
// Still buggy.. I need to come back to it later
// Check for edges of the screen if playing on Xbox360
private void AdjustForDeadZone(HUDDisplay element)
{
#if false//XBOX360
float deadZoneX = ElementalGame.GAME_WINDOW_WIDTH * SIDES_DEAD_ZONE_PERCENT;
float deadZoneY = ElementalGame.GAME_WINDOW_HEIGHT * TOP_BOTTOM_DEAD_ZONE_PERCENT;
Vector2 absolutePosition = Vector2.Zero + element.position;
// Player 1 always in absolute coordinates
// Check Player 2:
if (playerIndex == 1)
{
if (ElementalGame.TOTAL_PLAYERS_PLAYING == 2)
{
absolutePosition += new Vector2(0, parentViewport.Height);
}
else
{
absolutePosition += new Vector2(parentViewport.Width, 0);
}
}
else if (playerIndex == 2)
{
absolutePosition += new Vector2(0, parentViewport.Height);
}
else if (playerIndex == 3)
{
absolutePosition += new Vector2(parentViewport.Width, parentViewport.Height);
}
// First check for the left side dead zone
// If its on the left side
if (absolutePosition.X < ElementalGame.GAME_WINDOW_WIDTH * 0.5f)
{
if (playerIndex == 0 || (playerIndex == 1 && ElementalGame.TOTAL_PLAYERS_PLAYING == 2) ||
(playerIndex == 2 && ElementalGame.TOTAL_PLAYERS_PLAYING > 2))
{
element.position.X += deadZoneX;
}
}
// else.. check for right side
else if (absolutePosition.X > ElementalGame.GAME_WINDOW_WIDTH * 0.5f)
{
if (playerIndex == 1 || (playerIndex == 0 && ElementalGame.TOTAL_PLAYERS_PLAYING <= 2) ||
playerIndex == 3)
{
element.position.X -= deadZoneX;
}
}
// Then check upper side
if (absolutePosition.Y < ElementalGame.GAME_WINDOW_HEIGHT * 0.5f)
{
if (playerIndex == 0 || (playerIndex == 1 && ElementalGame.TOTAL_PLAYERS_PLAYING > 2))
{
element.position.Y += deadZoneY;
}
}
else if (absolutePosition.Y > ElementalGame.GAME_WINDOW_HEIGHT * 0.5f)
{
if (playerIndex == 2 || playerIndex == 3 || (playerIndex == 0 && ElementalGame.TOTAL_PLAYERS_PLAYING == 1) ||
(playerIndex == 1 && ElementalGame.TOTAL_PLAYERS_PLAYING == 2))
{
element.position.Y -= deadZoneY;
}
}
#endif
}
// Add a Text display to our TextDisplay list
public int AddTextDisplay(string text, Vector2 position, Color color)
{
TextDisplay temp = new TextDisplay();
temp.text = text;
Vector2 size = FontWriter.Arial.MeasureString(text);
temp.width = (int)(size.X);
temp.height = (int)(size.Y);
temp.position = position;
AdjustForDeadZone(temp);
temp.color = color;
textDisplays.Add(temp);
return textDisplays.Count - 1;
}
// Add a Value display to our ValueDisplay list
public int AddValueDisplay(string text, float value, Vector2 position, int width, int height, Color color)
{
ValueDisplay temp = new ValueDisplay();
temp.text = text;
temp.value = value;
temp.width = width;
temp.height = height;
temp.position = position;
AdjustForDeadZone(temp);
temp.color = color;
valueDisplays.Add(temp);
return valueDisplays.Count - 1;
}
// Add an Image display to our ImageDisplay list
public int AddImageDisplay(Texture2D image, Vector2 position, int width, int height, Color color, bool draw)
{
ImageDisplay temp = new ImageDisplay();
temp.image = image;
temp.width = width;
temp.height = height;
temp.position = position;
AdjustForDeadZone(temp);
temp.color = color;
temp.visible = draw;
imageDisplays.Add(temp);
return imageDisplays.Count - 1;
}
public int AddImageSpinner(ImageSpinner val)
{
this.imageSpinners.Add(val);
return imageSpinners.Count - 1;
}
public void SpinnerNext(int index)
{
if (index < 0 || index >= this.imageSpinners.Count)
{
// Invalid index
return;
}
else
{
ImageSpinner temp = this.imageSpinners[index];
temp.next();
this.imageSpinners[index] = temp;
}
}
public void SpinnerBack(int index)
{
if (index < 0 || index >= this.imageSpinners.Count)
{
// Invalid index
return;
}
else
{
ImageSpinner temp = this.imageSpinners[index];
temp.prev();
this.imageSpinners[index] = temp;
}
}
public void SpinnerSet(int index, int val)
{
if (index < 0 || index >= this.imageSpinners.Count)
{
// Invalid index
return;
}
ImageSpinner temp = this.imageSpinners[index];
if (val < 0 || temp.images.Length <= val)
{
return;
}
else
{
temp.activeIndex = val;
this.imageSpinners[index] = temp;
}
}
// Method which allows us to change the text in a TextDisplay
public void UpdateText(int index, string newText)
{
if (index < 0 || index >= textDisplays.Count)
{
// Invalid index
return;
}
else
{
// Change the text
textDisplays[index].text = newText;
}
}
public void UpdateTextVis(int index, string newText, bool vis)
{
if (index < 0 || index >= textDisplays.Count)
{
// Invalid index
return;
}
else
{
// Change the text
textDisplays[index].text = newText;
textDisplays[index].visible = vis;
}
}
// Method which allows us to change the Value in a ValueDisplay
public void UpdateValue(int index, float newValue)
{
if (index < 0 || index >= valueDisplays.Count)
{
// Invalid index
return;
}
else
{
// Change the value
valueDisplays[index].value = newValue;
}
}
public void UpdateImageScale(int index, float xScale, float yScale)
{
if (index < 0 || index >= this.imageDisplays.Count)
{
// Invalid index
return;
}
else
{
this.imageDisplays[index].xScale = xScale;
this.imageDisplays[index].yScale = yScale;
}
}
public void UpdateImageHeight(int index, int amount)
{
if (index < 0 || index >= this.imageDisplays.Count)
{
// Invalid index
return;
}
else
{
this.imageDisplays[index].height = amount;
}
}
public void UpdateImagePosition(int index, Vector2 newPosition)
{
if (index < 0 || index >= this.imageDisplays.Count)
{
// Invalid index
return;
}
else
{
this.imageDisplays[index].position = newPosition;
}
}
public void UpdateImageDraw(int index, bool value)
{
if (index < 0 || index >= this.imageDisplays.Count)
{
// Invalid index
return;
}
else
{
this.imageDisplays[index].visible = value;
}
}
// Method that sets a text display as visible or invisible
public void UpdateTextVisible(int index, bool visible)
{
if (index < 0 || index >= textDisplays.Count)
{
// Invalid index
return;
}
else
{
// Change the value
textDisplays[index].visible = visible;
}
}
// Method which allows us to change the color of a TextDisplay
public void UpdateTextColor(int index, Color color)
{
if (index < 0 || index >= textDisplays.Count)
{
// Invalid index
return;
}
else
{
// Change the value
textDisplays[index].color = color;
}
}
// Default Draw function
public void Draw()
{
Draw(0, 0);
}
// Draw function for drawing our displays at a certain offset position
public void Draw(int xoffset, int yoffset)
{
//assume the spritebatch has already been started.. so we have to end it
//spriteBatch.End();
// spriteBatch.Begin(SpriteBlendMode.AlphaBlend);
foreach (TextDisplay element in textDisplays)
{
if (element.visible)
{
ElementalGame.spriteBatch.DrawString(FontWriter.Arial, element.text, element.position, element.color);
}
//FontWriter.MeadBold16.Draw(element.position.X + xoffset,
// element.position.Y + yoffset,
// element.text,
// Alignment.Left,
// element.color,
// spriteBatch);
}
//foreach (ValueDisplay element in valueDisplays)
//{
// FontWriter.Ogilvie24.Draw(element.position.X + xoffset,
// element.position.Y + yoffset,
// element.text,
// Alignment.Left,
// element.color,
// spriteBatch);
// int titleWidth = FontWriter.Ogilvie24.TextWidth(element.text);
// FontWriter.MeadBold16.Draw(element.position.X + titleWidth + xoffset,
// element.position.Y + yoffset,
// "" + element.value,
// Alignment.Left,
// element.color,
// spriteBatch);
//}
foreach (ImageDisplay element in imageDisplays)
{
if (element.visible == true)
{
ElementalGame.spriteBatch.Draw(element.image,
new Rectangle((int)element.position.X + xoffset,
(int)element.position.Y + yoffset,
element.width,
element.height),
new Rectangle(0, 0, (int)(element.image.Width * element.xScale), (int)(element.image.Height * element.yScale)),
element.color);
}
}
foreach (ImageSpinner elementBig in imageSpinners)
{
if (elementBig.visible == true)
{
ImageDisplay element = elementBig.images[elementBig.activeIndex];
ElementalGame.spriteBatch.Draw(element.image,
new Rectangle((int)element.position.X + xoffset,
(int)element.position.Y + yoffset,
element.width,
element.height),
new Rectangle(0, 0, (int)(element.image.Width * element.xScale), (int)(element.image.Height * element.yScale)),
element.color);
}
}
}
}
}