I've been working on a GUI for my game. So far I've used code to create objects that look like "forms" (not to be confused with winforms, I'm using monogame). Also I created buttons. But now I'm having difficulty creating a checkbox. So here is my CheckBoxGUI
class:
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
namespace Game1.GUIElements
{
public class CheckBoxGUI
{
Texture2D checkBoxTexEmpty, checkBoxTexSelected;
SoundEffect clickSFX;
public Rectangle CheckBoxRect { get; set; }
public Rectangle CheckBoxTxtRect { get; set; }
public SpriteFont CheckBoxFont { get; set; }
public bool IsHovered { get; set; }
public bool IsDisabled { get; set; }
public bool IsChecked { get; set; }
public Color TxtColor { get; set; }
string CheckBoxTxt { get; set; }
public CheckBoxGUI(bool newDisabledCheck, bool newSelectionCheck, Rectangle newCheckBoxRect, SpriteFont newSpriteFont, Color newTxtColor, string newTxt, ContentManager content)
{
IsDisabled = newDisabledCheck;
IsChecked = newSelectionCheck;
CheckBoxRect = newCheckBoxRect;
CheckBoxFont = newSpriteFont;
TxtColor = newTxtColor;
CheckBoxTxt = newTxt;
CheckBoxTxtRect = new Rectangle(CheckBoxRect.X + 19, CheckBoxRect.Y - 3, (int)CheckBoxFont.MeasureString(CheckBoxTxt).X, (int)CheckBoxFont.MeasureString(CheckBoxTxt).Y);
if (checkBoxTexEmpty == null) checkBoxTexEmpty = content.Load<Texture2D>(Game1.BGObjectsPath + "10") as Texture2D;
if (checkBoxTexSelected == null) checkBoxTexSelected = content.Load<Texture2D>(Game1.BGObjectsPath + "11") as Texture2D;
if (clickSFX == null) clickSFX = content.Load<SoundEffect>(Game1.BGSoundPath + "1") as SoundEffect;
}
public void UnloadContent()
{
if (CheckBoxRect != Rectangle.Empty) CheckBoxRect = Rectangle.Empty;
if (checkBoxTexEmpty != null) checkBoxTexEmpty = null;
if (CheckBoxFont != null) CheckBoxFont = null;
if (clickSFX != null) clickSFX = null;
if (CheckBoxTxt != string.Empty) CheckBoxTxt = string.Empty;
}
public void Update(GameTime gameTime)
{
if (!Game1.IsSoundDisabled)
{
if ((IsHovered) && (!IsDisabled))
if (InputManager.Instance.IsLeftClicked())
{
clickSFX.Play();
IsHovered = false;
}
}
}
public void Draw(SpriteBatch spriteBatch)
{
if ((CheckBoxFont != null) && ((CheckBoxTxt != string.Empty) && (CheckBoxTxt != null)))
{
if (IsChecked) spriteBatch.Draw(checkBoxTexSelected, CheckBoxRect, Color.White);
else if (IsDisabled) spriteBatch.Draw(checkBoxTexEmpty, CheckBoxRect, Color.Gray);
else spriteBatch.Draw(checkBoxTexEmpty, CheckBoxRect, Color.White);
TextOutliner.DrawBorderedText(spriteBatch, CheckBoxFont, CheckBoxTxt, CheckBoxTxtRect.X, CheckBoxTxtRect.Y, TxtColor);
}
}
}
}
My TextOutliner
class used to draw text with borders/outlines:
public static class TextOutliner
{
public static void DrawBorderedText(SpriteBatch spriteBatch, SpriteFont spriteFont, string text, float xPos, float yPos, Color txtColour)
{
spriteBatch.DrawString(spriteFont, text, new Vector2((xPos + 1), (yPos + 1)), Color.Black);
spriteBatch.DrawString(spriteFont, text, new Vector2((xPos + 1), (yPos - 1)), Color.Black);
spriteBatch.DrawString(spriteFont, text, new Vector2((xPos - 1), (yPos + 1)), Color.Black);
spriteBatch.DrawString(spriteFont, text, new Vector2((xPos - 1), (yPos - 1)), Color.Black);
spriteBatch.DrawString(spriteFont, text, new Vector2(xPos, yPos), txtColour);
}
}
And finally, here's how I use the CheckBoxGUI
class in my TitleScreen
:
// Fields
CheckBoxGUI[] checkBoxes;
// LoadContent()
if (checkBoxes == null)
{
checkBoxes = new CheckBoxGUI[1]; // Make it 1, for now
checkBoxes[0] = new CheckBoxGUI(false, false, new Rectangle(800, 200, 16, 16), Game1.GameFontSmall, Color.White, "Close Window", content);
}
// UnloadContent()
foreach (CheckBoxGUI checkBox in checkBoxes) checkBox.UnloadContent();
// Update()
for (int i = 0; i < checkBoxes.Length; i++) CheckBoxInputTS(checkBoxes[i], optionsWindow, gameTime); // optionsWindow is one of the "form" objects I've talked about earlier
Here is my problem (at least that's where I think it is, in the method that handles the checkbox logic):
public void CheckBoxInputTS(CheckBoxGUI checkBox, WindowGUI win, GameTime gameTime)
{
if (!checkBox.IsDisabled)
{
if ((mouseRect.Intersects(checkBox.CheckBoxRect)) || (mouseRect.Intersects(checkBox.CheckBoxTxtRect)))
{
checkBox.IsHovered = true;
checkBox.Update(gameTime);
checkBox.TxtColor = Color.Yellow;
if ((!checkBox.IsChecked) && (InputManager.Instance.IsLeftClicked())) checkBox.IsChecked = true;
else if ((checkBox.IsChecked) && (InputManager.Instance.IsLeftClicked())) checkBox.IsChecked = false;
}
else if ((!mouseRect.Intersects(checkBox.CheckBoxRect)) || (!win.IsOpen))
{
checkBox.IsHovered = false;
checkBox.TxtColor = Color.White;
}
}
else checkBox.TxtColor = Color.Gray;
}
And finally, Draw()
:
if (optionsWindow.IsOpen)
{
checkBoxes[0].Draw(spriteBatch);
}
So the method CheckBoxInputTS
allows me to check/uncheck a CheckBoxGUI item with mouse clicks, but I can't actually attach any functionality to this. For instance I can do the following inside that same method:
if (checkBox == checkBoxes[0])
{
if (checkBox.IsChecked) win.IsOpen = false;
else win.IsOpen = true;
}
Perhaps I'm missing something simple, or I don't understand how to actually make further improvements into the code I already have to make it support different functionalities for the checkBoxes
... However, when I test this, if I open the window and check the box the window closses and won't open again. The IsOpen
member of the WindowGUI
class controls whether the window is visible or not through an if-statement in the class' Draw()
method.
The same thing happens if I try to use other examples for the checkboxes... Once checkBox.IsChecked
has a user-given value I can't change it.
If someone can find what I'm doing wrong and help me clean-up this code, it will be much appreciated. Thanks in advance!
Aucun commentaire:
Enregistrer un commentaire