Tuesday 17 April 2012

Main Menu

It's been a while since we've seen anything new in our app, so let's put that right by adding the main menu.

Initially, we are going to have only two options.
  • New Game
  • Exit
These will be created using text objects when the program first runs.

But rather than just appear on screen, they will fade in over a period of time.  Since we wont know how that looks until we try it, we use a constant to set what that period is.
#constant MENU_FADE   5.0
This sets the time to be 5 seconds. As with all our constants, we can change this later by simply changing the value and recompiling the project.

Please note that this post is just the positioning phase, I will add the fade in the next post to keep it simple.

We will also need the program to know how many options the menu has - even if it's only two we still need a value for it.  So again we have a constant.
#constant MENU_ITEMS   2
Since we are using Text Objects, we will need text strings for what they will display and these are initially read into a string array.

At the end of the Initialise() function, we add the following line.
dim menuString[ 5 ] as string = [ "" , "Start Game" , "Exit", "Option 3" , "Option 4" , "Option 5" ]
This is an advanced form of the dim() command, which not only defines the array as a string - reserving the space, but it also fills the array with the strings we want to use.

Each string is enclosed in quotes as normal, and separated by commas.  Then the whole lot are wrapped in square brackets.  There are two things to notice about the strings I have used here.
  • The first is empty
  • There are more strings than we need
AGK starts it's arrays at index zero, however we are going to use index 1 upwards so that when it comes to choosing an option, option zero means none.

The empty string is the one we are not going to use, which will go into slot zero in the array.

The additional strings, allow us to test the menu with more options - up to 5, without having to coming back and add strings for them.  This is the only hard coded value we will use.

Next we reserve another array for the text object references and perform a loop to create the text objects.
dim menuText[ MENU_ITEMS ]
   for i=1 to MENU_ITEMS
      menuText[ i ] = createText( menuString[i] )
      setTextVisible( menuText[ i ] , 0 )
   next i
This time, we use the constant MENU_ITEMS to set the maximum for both the array and the loop to create the objects.

The objects are created and then hidden.  Their sizes and positions are not set at this point.

Back at the top of the program, we add another depth constants with the others.
#constant DEPTH_MENU    10
And we also add two more with the menu constants.
#constant MENU_DIVTOP 0.25
#constant MENU_DIVSIZE 0.10
These set the position of the top of the menu and the size of the menu text.

I have used the DIV part of the name to indicate that they are calculated based on the screen height, that way if the screen height later changes, the menu text will automatically be resize accordingly.

The initial values are guesses, until we see what it looks like.

Now the block of code for the menu within the select structure. is changed to.
case STATE_MENU
   // Menu Code
   if getTextVisible( menuText[ 1 ]) = 0
      thisX# = VirtWidth() / 2.0
      thisY# = VirtHeight() * MENU_DIVTOP
      thisSize# = VirtHeight() * MENU_DIVSIZE
      for i=1 to MENU_ITEMS
         setTextSize( menuText[ i ] , thisSize# )
         setTextAlignment( menuText[ i ] , 1 )
         setTextDepth( menuText[ i ] , DEPTH_MENU )
         setTextPosition( menuText[ i ] , thisX# , thisY# )
         setTextVisible( menuText[ i ] , 1 )
         thisY# = thisY# + getTextTotalHeight( menuText[ i ] ) * 2.0
      next i
   endif
endcase
This checks if the first item of the menu is not visible using the getTextVisible() command.

If the value returned is zero, the text is not visible, so this must be the first time the menu code has been run.

It calculates the start position for the first line of text and the size of each line, and then performs a loop, setting for each item; the size, alignment (centred), depth and position. It then makes the item visible.

Before the next loop runs, it adds twice the total height of the text object to the Y position, so that there will be a blank line before the next item.  It then continues for the next item.

On the next main loop of the program, the first item will be visible, so this code will not be run again.

To see the menu, change the line in the //Setup code block to.
setGameState( STATE_MENU )
So that the menu state is called rather than the game running state.
The menu shows, but  - as you might expect - the panel no longer responds.

No comments:

Post a Comment