Jump to content
  • Advertisement
Sign in to follow this  
DominicBridge

Event based Menu System

This topic is 493 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

     Hey guys,

 

First of all I'm using MonoGame (I miss you XNA).

 

I've always done menus quite badly, but for my new game that require a lot of menus I'd like it to be a bit better.

 

So its still fairly skeleton at the moment. but it looks like this

public class Menu
    {
        List<MenuItem> MenuItems;

        private SpriteFont Font;
        private string FontName;
        private Vector2 Position;

        private int SelectedMenuItem = 0;

        public Menu(ContentManager content, Vector2 Position, string fontName = "Arial36")
        {
            MenuItems = new List<MenuItem>();
            
            FontName = fontName;
            this.Position = Position;
            this.LoadContent(content);
        }

        private void LoadContent(ContentManager content)
        {
            Font = content.Load<SpriteFont>("Fonts/" + FontName);
        }

        public void AddItems(MenuItem menuItem)
        {
            MenuItems.Add(menuItem);
        }

        public void Update(GameTime gameTime, KeyboardState KS, KeyboardState OldKS)
        {
            if(OldKS.IsKeyDown(Keys.Up) && KS.IsKeyUp(Keys.Up))
            {
                SelectedMenuItem--;
            }


            if (OldKS.IsKeyDown(Keys.Down) && KS.IsKeyUp(Keys.Down))
            {
                SelectedMenuItem++;
            }

            foreach (MenuItem menuItem in MenuItems)
                menuItem.Update(KS, OldKS);

            if (SelectedMenuItem <= -1)
                SelectedMenuItem = MenuItems.Count - 1;
            else if (SelectedMenuItem >= MenuItems.Count)
                SelectedMenuItem = 0;
        }

And MenuItems

 public class MenuItem
    {
        public string Text { get; set; }

        public delegate void OnChose();
        public event OnChose ButtonChosen;
        
        public MenuItem(string text)
        {
            this.Text = text;
        }
    
        public void Update(KeyboardState KS, KeyboardState OldKS)
        {


            if (OldKS.IsKeyDown(Keys.Enter) && KS.IsKeyUp(Keys.Enter))
            {
                ButtonChosen();
            }

        }

    }

Now finally to use this code I use

            MenuItem LoadGame = new MenuItem("Load Game");
            LoadGame.ButtonChosen += LoadGame_ButtonChosen;
            MainMenu.AddItems(LoadGame);

            MenuItem NewGame = new MenuItem("NewGame");
            NewGame.ButtonChosen += NewGame_ButtonChosen; ;

            MainMenu.AddItems(NewGame);
     
        private void NewGame_ButtonChosen()
        {
            throw new NotImplementedException();
        }
 
        private void LoadGame_ButtonChosen()
        {
            throw new NotImplementedException();
        }
 

 

However, even when New Game is selected, LoadGame_ButtonChosen() Is always selected.

 

Can't quite work out where to go from here. Any advice would be fantastic

 

Share this post


Link to post
Share on other sites
Advertisement

You call Update on every MenuItem. Every MenuItem checks to see if Enter got pressed, so every MenuItem will call ButtonChosen when it is, regardless of whether that was the chosen item or not.

Move the key-checking code into the Menu object. If Enter is pressed, call ButtonChosen on MenuItems[SelectedMenuItem].

Share this post


Link to post
Share on other sites

You call Update on every MenuItem. Every MenuItem checks to see if Enter got pressed, so every MenuItem will call ButtonChosen when it is, regardless of whether that was the chosen item or not.

Move the key-checking code into the Menu object. If Enter is pressed, call ButtonChosen on MenuItems[

I only read your first sentence and immediately released. Sometime it just takes a a fresh set off eyes!

 

I changed the menu.cs to

 for (int i = 0; i < MenuItems.Count; i++)
            {
                if(i == SelectedMenuItem)
                    MenuItems[i].Update(KS, OldKS);
            }

All works now. Thank you kindly sir!

Share this post


Link to post
Share on other sites

That will work fine until you decide you want to do more than just check for input in the Update function.

And there's no need for a loop there.

Share this post


Link to post
Share on other sites

That will work fine until you decide you want to do more than just check for input in the Update function.

And there's no need for a loop there.

Aye you're correct

I have this now

Menu.cs

   if (OldKS.IsKeyDown(Keys.Enter) && KS.IsKeyUp(Keys.Enter))
            {
                MenuItems[SelectedMenuItem].ButtonChose();
            }

MenuItem.cs

public void ButtonChose()
        {
            this.ButtonChosen();
        }

I can't call menuItems[SelectedMenuItem].ButtonChosen(); Directly from another class, but this works.

 

Thank you very much for the help and pointers :)

Share this post


Link to post
Share on other sites

public void ButtonChose()
        {
            this.ButtonChosen();
        }
I can't call menuItems[SelectedMenuItem].ButtonChosen(); Directly from another class, but this works.


Just make ButtonChosen public and remove the redundancy, unless you have a very good reason to keep ButtonChosen non-public.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!