11 Replies - 1040 Views - Last Post: 16 January 2013 - 07:55 AM

#1 jimac1888  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 17
  • Joined: 12-January 13

Xna 3.1 menu system

Posted 13 January 2013 - 09:26 AM

Ok i posted this before and it got shot down without discussion so i will re try by explaining it a little better,
I am not looking for code, its not homework, i am new to xna and have made a pong clone game. Just started a new project and this time i would like to start off with a menu, so to the question :

I have coded this menu system and can't see any problems with it but it will not do what i want it to do, by this i mean when it loads up i get the menu displayed, its coded with the keys A and S to scroll through the options and when it does the text should be highlighted with black text, but when the key(s) are pressed the options dont change ie the start game text remains highlighted at all times, i think the problem is in my Game1 class update method but unsure thats why i am seeking your wisdom.

{
    /// <summary>
    /// This is the main type for your game
    /// </summary>
    public class Game1 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;
        MenuComponent menuComponent;


        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
        }

        protected override void Initialize()
        {
            // TODO: Add your initialization logic here

            base.Initialize();
        }

        /// <summary>
        /// LoadContent will be called once per game and is the place to load
        /// all of your content.
        /// </summary>
        protected override void LoadContent()
        {

            spriteBatch = new SpriteBatch(GraphicsDevice);
            string[] menuItems = { "Start Game", "High Scores", "End Game" };
            
            menuComponent = new MenuComponent(this,spriteBatch,Content.Load<SpriteFont>("menufont"),menuItems);
            Components.Add(menuComponent);
        }

        /// <summary>
        /// UnloadContent will be called once per game and is the place to unload
        /// all content.
        /// </summary>
        protected override void UnloadContent()
        {
            // TODO: Unload any non ContentManager content here
        }

        /// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Update(GameTime gameTime)
        {


            base.Update(gameTime);
        }


        /// <summary>
        /// This is called when the game should draw itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Draw(GameTime gameTime)
        {

            GraphicsDevice.Clear(Color.CornflowerBlue);

            // TODO: Add your drawing code here
            spriteBatch.Begin(SpriteBlendMode.AlphaBlend);

            base.Draw(gameTime);

            spriteBatch.End();

            
        }
    }
}

and my class

{
    /// <summary>
    /// This is a game component that implements IUpdateable.
    /// </summary>
    public class MenuComponent : Microsoft.Xna.Framework.DrawableGameComponent
    {

        string[] menuItems;
        int selectedIndex;
        Color normal = Color.White;
        Color hilite = Color.Black;
        KeyboardState keyboardState;
        KeyboardState oldKeyboardState;
        SpriteBatch spriteBatch;
        SpriteFont spriteFont;
        Vector2 position;
        float width = 0f;
        float height = 0f;

        public int SelectedIndex
        {
            get { return selectedIndex; }
            set
            {
                selectedIndex = value;
                if (selectedIndex < 0)
                    selectedIndex = 0;
                if (selectedIndex >= menuItems.Length)
                    selectedIndex = menuItems.Length - 1;
            }
        }

        public MenuComponent(Game game,SpriteBatch spriteBatch,SpriteFont spriteFont,string[] menuItems)
            : base(game)
        {
            // TODO: Construct any child components here
            this.spriteBatch = spriteBatch;
            this.spriteFont = spriteFont;
            this.menuItems = menuItems;
            MeasureMenu();
        }

        private void MeasureMenu()
        {
            height = 0;
            width = 0;
            foreach (string item in menuItems)
            {
                Vector2 size = spriteFont.MeasureString(item);
                if (size.X > width)
                    width = size.X;
                height += spriteFont.LineSpacing + 5;
            }
            position = new Vector2(
            (Game.window.ClientBounds.Width - width) / 2,
            (Game.window.ClientBounds.Height - height) / 2);
        }

        public override void Initialize()
        {
            // TODO: Add your initialization code here

            base.Initialize();
        }

        private bool CheckKey(Keys theKey)
        {
            return keyboardState.IsKeyUp(theKey) && oldKeyboardState.IsKeyDown(theKey);
        }

        /// <summary>
        /// Allows the game component to update itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        public override void Update(GameTime gameTime)
        {
            // TODO: Add your update code here
            keyboardState = Keyboard.GetState();

            if (CheckKey(Keys.A))
            {
                selectedIndex++;

                if (selectedIndex == menuItems.Length)
                {
                    selectedIndex = 0;
                }
                if (CheckKey(Keys.S))
                {
                    selectedIndex--;
                }
                if (selectedIndex < 0)
                {
                    selectedIndex = menuItems.Length - 1;
                }

                base.Update(gameTime);

                oldKeyboardState = keyboardState;
            }
        }

        public override void Draw(GameTime gameTime)
        {
            base.Draw(gameTime);
            Vector2 location = position;
            Color tint;

            for (int count = 0; count < menuItems.Length; count++)
            {

                if (count == selectedIndex)
                {
                    tint = hilite;
      
                }
                else
                {
                    tint = normal;
    
                }

                //spriteBatch.DrawString(spriteFont, menuItems[count], location, tint);
                

                location.Y += spriteFont.LineSpacing + 50;
                spriteBatch.DrawString(spriteFont, menuItems[count], location, tint);
            }
            
            
        }
    }
}



Thank you for any help, i am stumped it makes sense to me.

This post has been edited by Atli: 13 January 2013 - 10:06 AM
Reason for edit:: Fixed the code. You copied it with all the line numbers and everything. :)


Is This A Good Question/Topic? 0
  • +

Replies To: Xna 3.1 menu system

#2 jimac1888  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 17
  • Joined: 12-January 13

Re: Xna 3.1 menu system

Posted 13 January 2013 - 10:24 AM

Having checked through the tutorials i came across this
My link

I think it is similar to what i have tried to do so i will take a read over it and start again, i would appreciate it though if anyone can give me a hint as to were my code has gone wrong.
Was This Post Helpful? 0
  • +
  • -

#3 anonymous26  Icon User is offline

  • D.I.C Lover

Reputation: 0
  • View blog
  • Posts: 3,638
  • Joined: 26-November 10

Re: Xna 3.1 menu system

Posted 13 January 2013 - 11:17 AM

As I say to so many, you have to learn at least basic debugging skills. The likely reason why something doesn't happen in a game when it's running is either because the functionality is either called once or not at all. You need to check this initially with breakpoints.

This post has been edited by ButchDean: 13 January 2013 - 11:17 AM

Was This Post Helpful? 0
  • +
  • -

#4 jimac1888  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 17
  • Joined: 12-January 13

Re: Xna 3.1 menu system

Posted 13 January 2013 - 11:27 AM

View PostButchDean, on 13 January 2013 - 11:17 AM, said:

As I say to so many, you have to learn at least basic debugging skills. The likely reason why something doesn't happen in a game when it's running is either because the functionality is either called once or not at all. You need to check this initially with breakpoints.


You are right, not used the breakpoints just went with it when i got no errors, i will give it a try but don't think it will help on this occasion as the other text will never highlight maybe i will edit the code to make it automatically scroll through the menu buttons. Thanks for the reply.
Was This Post Helpful? 0
  • +
  • -

#5 anonymous26  Icon User is offline

  • D.I.C Lover

Reputation: 0
  • View blog
  • Posts: 3,638
  • Joined: 26-November 10

Re: Xna 3.1 menu system

Posted 13 January 2013 - 12:44 PM

Never 'just go with it', that's a terrible attitude that has no place in games programming. You verify that code is doing what it's supposed to do every step of the way.

Glad to know you are at least making a better attempt at tracking down what the issue is.
Was This Post Helpful? 0
  • +
  • -

#6 macosxnerd101  Icon User is online

  • Self-Trained Economist
  • member icon




Reputation: 10397
  • View blog
  • Posts: 38,479
  • Joined: 27-December 08

Re: Xna 3.1 menu system

Posted 13 January 2013 - 04:43 PM

Moved to XNA.
Was This Post Helpful? 0
  • +
  • -

#7 Kilorn  Icon User is offline

  • XNArchitect
  • member icon



Reputation: 1356
  • View blog
  • Posts: 3,528
  • Joined: 03-May 10

Re: Xna 3.1 menu system

Posted 15 January 2013 - 05:11 AM

One thing I noticed while quickly taking a look through your code is the following:
if (CheckKey(Keys.A))
            {
                selectedIndex++;

                if (selectedIndex == menuItems.Length)
                {
                    selectedIndex = 0;
                }
                if (CheckKey(Keys.S))
                {
                    selectedIndex--;
                }
                if (selectedIndex < 0)
                {
                    selectedIndex = menuItems.Length - 1;
                }

                base.Update(gameTime);

                oldKeyboardState = keyboardState;
            }



This is the first if check in the update method. The problem with this code is that it will only execute if Keys.A is pressed in the previous state and released in the current state. That's fine and dandy and usually how you check for key presses, but the thing that is wrong with this is that you've got code to check for another keypress inside it as well as the code that calls the base.Update(gameTime) method, AND the line that sets the old state as the current state. The fact that his has been done incorrectly also seems to have caused some confusion on the following if checks and how they should be laid out. The check for selectedIndex < 0 isn't inside the code block belonging to the check for Key.S being pressed and released, where it should be. I'd highly recommend rewriting this method to something like the following:
        public override void Update(GameTime gameTime)
        {
            oldKeyboardState = keyboardState();
            keyboardState = Keyboard.GetState();

            if (CheckKey(Keys.A))
            {
                selectedIndex++;

                if (selectedIndex == menuItems.Length)
                {
                    selectedIndex = 0;
                }
            }

            if (CheckKey(Keys.S))
            {
                selectedIndex--;

                if (selectedIndex < 0)
                {
                    selectedIndex = menuItems.Length - 1;
                }
            }

            base.Update(gameTime);
        }



Try this change and let me know if it resolves your issue.

This post has been edited by Kilorn: 15 January 2013 - 05:13 AM

Was This Post Helpful? 1
  • +
  • -

#8 jimac1888  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 17
  • Joined: 12-January 13

Re: Xna 3.1 menu system

Posted 15 January 2013 - 09:35 AM

View PostKilorn, on 15 January 2013 - 12:11 PM, said:

One thing I noticed while quickly taking a look through your code is the following:



This is the first if check in the update method. The problem with this code is that it will only execute if Keys.A is pressed in the previous state and released in the current state. That's fine and dandy and usually how you check for key presses, but the thing that is wrong with this is that you've got code to check for another keypress inside it as well as the code that calls the base.Update(gameTime) method, AND the line that sets the old state as the current state. The fact that his has been done incorrectly also seems to have caused some confusion on the following if checks and how they should be laid out. The check for selectedIndex < 0 isn't inside the code block belonging to the check for Key.S being pressed and released, where it should be. I'd highly recommend rewriting this method to something like the following:


Try this change and let me know if it resolves your issue.


It was right in front of me thank you, i think i sat starring at it for too long, you sir are a BOSS!
Was This Post Helpful? 0
  • +
  • -

#9 Kilorn  Icon User is offline

  • XNArchitect
  • member icon



Reputation: 1356
  • View blog
  • Posts: 3,528
  • Joined: 03-May 10

Re: Xna 3.1 menu system

Posted 15 January 2013 - 09:37 AM

Yea, staring at a problem for too long can cause even more problems because you'll think to yourself "I've been looking at this for so long, it must be a very complicated solution." Walking away from it for a bit can give you a fresh set of eyes and makes finding issues much easier. I suggest taking at least a 15 minute break every 3 hours, less if you run into a problem that you can't quite pin down quickly enough. Getting flustered while debugging is a cause for a lot of people to get frustrated and give up on their projects. Believe me, I've been there. Glad I could help.
Was This Post Helpful? 1
  • +
  • -

#10 bonyjoe  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 175
  • View blog
  • Posts: 548
  • Joined: 08-September 10

Re: Xna 3.1 menu system

Posted 15 January 2013 - 01:29 PM

Why are you still using XNA 3.1?
Was This Post Helpful? 0
  • +
  • -

#11 jimac1888  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 17
  • Joined: 12-January 13

Re: Xna 3.1 menu system

Posted 16 January 2013 - 01:01 AM

View Postbonyjoe, on 15 January 2013 - 08:29 PM, said:

Why are you still using XNA 3.1?


Very good question with a simple answer, my college only has 3.1 so i use it at home so i can transfer my work with me.
Was This Post Helpful? 0
  • +
  • -

#12 bonyjoe  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 175
  • View blog
  • Posts: 548
  • Joined: 08-September 10

Re: Xna 3.1 menu system

Posted 16 January 2013 - 07:55 AM

Damn colleges love being 2 years behind everyone else!
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1