Menu drawing
I have been able to get a menu to draw now. It opens with the A button and closes with the X button from the GamePad.
I tried to have left on the Dpad select the magic icon but I right now the game is taking input over the menu screen so I will need to manage inputs for the game screens.
I also don't have any sort of state tracking for Gamepad or Keyboard so when I had A set to open and A to close, the A button would quickly flash the menu but close it again.
The way this was done was I created an interface:
public interface IScreen {
void Update(GameTime gameTime);
void Draw(GameTime gameTime);
void Initialize();
void LoadContent();
void UnloadContent();
bool IsClosed { get; set; }
bool IsModal { get; }
}
Then I created a MenuScreen class which inherits from that interface:
public class MenuScreen : IScreen
{
public MenuScreen(Game game) {
_game = game;
}
private Game _game;
private SpriteBatch _spriteBatch;
private SpriteFont _titleFont;
private bool _isClosed;
private Texture2D _menuTexture;
private Texture2D _menuLeftTexture;
private Vector2 _menuPosition;
/// <summary>
/// Allows the game component to perform any initialization it needs to before starting
/// to run. This is where it can query for any required services and load content.
/// </summary>
public void Initialize()
{
// TODO: Add your initialization code here
}
/// <summary>
/// Allows the game component to update itself.
/// </summary>
/// <param name="gameTime">Provides a snapshot of timing values.</param>
public void Update(GameTime gameTime)
{
// TODO: Add your update code here
if (GamePad.GetState(PlayerIndex.One).Buttons.A == ButtonState.Pressed)
_isClosed = true;
if (GamePad.GetState(PlayerIndex.One).DPad.Left == ButtonState.Pressed)
DrawLeft(gameTime);
}
public void Draw(GameTime gameTime) {
_spriteBatch.Begin();
_spriteBatch.Draw(_menuTexture, _menuPosition, null, Color.White, 0f, Vector2.Zero, 2f, SpriteEffects.None, 0f);
_spriteBatch.End();
}
public void DrawLeft(GameTime gameTime) {
_spriteBatch.Begin();
_spriteBatch.Draw(_menuLeftTexture, _menuPosition, null, Color.White, 0f, Vector2.Zero, 2f, SpriteEffects.None, 0f);
_spriteBatch.End();
}
public void LoadContent() {
_spriteBatch = new SpriteBatch(_game.GraphicsDevice);
_menuPosition = new Vector2(375, 500);
_titleFont = _game.Content.Load<SpriteFont>("Fonts\\MenuTitle");
_menuTexture = _game.Content.Load<Texture2D>("Menu\\shfo2_battlemenu_default");
_menuLeftTexture = _game.Content.Load<Texture2D>("Menu\\shfo2_battlemenu_magic");
}
public void UnloadContent() {
}
public bool IsClosed {
get { return _isClosed; }
set { _isClosed = value; }
}
public bool IsModal { get { return true; } }
}
I also did a GameScreen class:
public class GameScreen : IScreen {
public GameScreen(Game game) {
_game = game;
}
private Game _game;
private SpriteBatch _spriteBatch;
private SpriteFont _titleFont;
private string _text;
public void Initialize() {
// TODO: Add your initialization code here
}
public void Update (GameTime gameTime) {
IScreen overlay = ( ( IScreenNotify )_game ).OverlayScreen;
if (null != overlay) {
if (overlay.IsModal) {
_text = "Game (paused - modal overlay)";
return;
}
_text = "Game (active - modeless overlay)";
}
else {
_text = "Game (active)";
}
if (GamePad.GetState(PlayerIndex.One).Buttons.X == ButtonState.Pressed)
( ( IScreenNotify )_game ).SetOverlayType(typeof( MenuScreen ));
}
public void Draw (GameTime gameTime) {
_spriteBatch.Begin();
_spriteBatch.DrawString(_titleFont, _text, Vector2.Zero, Color.Black);
_spriteBatch.End();
}
public void LoadContent() {
_spriteBatch = new SpriteBatch(_game.GraphicsDevice);
_titleFont = _game.Content.Load<SpriteFont>("Fonts\\MenuTitle");
}
public void UnloadContent() {
}
public bool IsClosed {
get { return false; }
set {}
}
public bool IsModal { get { return true; } }
}
I also created an IScreenNotify inteface:
interface IScreenNotify {
void SetOverlayType(Type screen);
IScreen OverlayScreen { get; }
}
Then on the main Game class implemented them:
private IScreen _overlayScreen;
private IScreen _gameScreen;
private readonly Dictionary<Type, IScreen> _screens = new Dictionary<Type,IScreen>();
In the initialize method of the Game class:
_gameScreen = new GameScreen(this);
_gameScreen.Initialize();
loadOverlay(typeof( MenuScreen ));
In the load content method of the Game class:
spriteBatch = new SpriteBatch(GraphicsDevice);
_gameScreen.LoadContent();
In the Update method of the Game class:
_gameScreen.Update(gameTime);
if (null != _overlayScreen) {
if (_overlayScreen.IsClosed) {
_overlayScreen.IsClosed = false;
_overlayScreen = null;
}
else {
_overlayScreen.Update(gameTime);
}
}
Next in the Draw method of the Game class:
_gameScreen.Draw(gameTime);
if (_overlayScreen != null)
_overlayScreen.Draw(gameTime);
Finally I had to create a few extra methods in the Game class:
public void SetOverlayType(Type screen)
{
loadOverlay(screen);
}
public IScreen OverlayScreen
{
get { return _overlayScreen; }
}
private void loadOverlay(Type screen) {
IScreen newScreen;
if (!_screens.TryGetValue(screen, out newScreen)) {
ConstructorInfo ci = screen.GetConstructor(new[] { typeof( Game ) });
newScreen = ( IScreen )ci.Invoke(new object[] { this });
newScreen.Initialize();
newScreen.LoadContent();
_screens.Add(screen, newScreen);
}
_overlayScreen = newScreen;
}
Now is by no means believe this is the best way to do this but it was something I had tried out with a buddy while making another game and wanted to try it here.
Until next day of Thor.
Comments
Post a Comment