RSS

b) Main menu

A fully functional, animated UI with very little code!

The main menu AppModule type

Download Part 2 of the project files and see ‘1 - Mainmenu.bmx’

For this we can simply rip the main menu type from the sample #5.  This type already provides code to act upon exit and new game buttons, options, log-in and high score dialogs.   The sample itself provides all the resources it needs such as GUI buttons, fonts and gui window files as well as the music we’ll use.

We’ll look at each part of the main menu type in full and I think for the ammount of functionality, you’ll agree there’s very little code..

The create function:  Makes a new mainmenu object an initialises it..

Function Create ( resFile:String = “” )
  Local mm:mainMenu = New mainMenu
  mm.Initialise( resFile, APP_MAINMENU )
End Function

Most create functions will return the newly created object but since we don’t need to worry about the object we can leave that out.

The Start method

Method Start()
  Super.Start()
  PlayGlobalSong( “title” )
  Delay(1000)
  SetFadeColor( 0,0,0 )
  ShowMouse()
  GuiShowWindow( “menu” )
End Method 
    • First, it begins the music playing. The song called “title” is defined in the main menus resource file.
    • I put a delay in to allow the screen time to be ready before the animated GUI form falls into view.
    • It turns the mouse pointer on since we turn it off before starting a game and this Start function is called every time the module ’starts’ which includes when control returns to it when the game module ends.
    • And it shows a window called “menu”.  This window was loaded by also listing it in the resource file.

    It also does one more thing:  It sets the “fade color” to full black.  But more about fading in a minute.

    The Draw method

    It only has to draw the GUI;

    Method Draw( )
      DrawGUI()
      Super.Draw( )
    End Method 

    The Update method

    This is the main one, where we process all the GUI button actions.

    Method Update( timeMS:Int )
      Super.Update( timeMS )
    
      ’ Handling button hits is as simple as this…
      If ( GuiButtonHit( “exit” ) )
    
       GuiHideWindow( “menu” )
       StartFadeOut()
       FadeOutMusic()
    
      Else If ( GuiButtonHit( “start” ) )
    
       GuiHideWindow( “menu” )
       StartFadeOut()
       FadeOutMusic()
       HideMouse()
       game.Create( “Media/gameResources.txt” )
    
      Else If ( GuiButtonHit( “options” ) )
    

    This isn’t all the method code because it’s pointless reprinting it all here;  it simply continues the else if statements to cover every possible button “hit”.  That’s how the GUI is monitored in your code.  When the user clicks a button it is stored in a hit list and you simply ask if it’s been hit and deal with it as you need.  You may be used to event based GUI’s but this is much simpler with no callbacks or event queues to deal with.

    The button names were defined in the main menus window files.  More on them later.

    Automatic screen fading

    Look at the code above for the actions taken when the “exit” button is hit.  It hides the gui window, “starts” a fade out and fades the music.  Fading the music is obvious; it drops the volume to zero softly so we don’t get abrupt stops, but by starting a “fade out” we’ve kicked another part of the framework into action.

    During the fade out transition the screen is automatically over-drawn with a rect of the color we specified earlier.  The alpha of this rect grows from 0 to 1 over the course of 1 second which fades away the screen behind it.  When the alpha value gets to 1, an overidable AppModule method “FadeOutComplete” is called:

    Method FadeOutComplete()
      EndModule()
    End Method 

    so we use that method to end the module.  As it’s the main menu and there’s no more modules in the application flow chain, the app will exit.

    We can also use a “fade in” that will draw the overlay rect with the alpha value starting at 1 and decreasing to 0.  We can also query if either fade rects are being drawn.  See: IsFading, StartFadeIn and FadeInComplete.

    And that’s it!  That’s the main menu code covered!  There’s just some other tweaks to the rest of source from where we left last time.

    Tweaking the game code

    Previously the game over condition (when the player collided with an enemy or an enemy got past the bottom of the screen) just called EndModule().  We’ll change that to StartFadeOut() and add a FadeOutComplete method that calls EndModule() instead just as the main menu does.

    Some more code we’ll add to our game update method;

    If ( IsFading() ) Return
    
    If ( KeyHit( KEY_ESCAPE ) )
      StartFadeOut()
    End If 

    First, we don’t want the game logic executing if the game is fading, and we’ll give the user a way of returning to the main menu.

    That covers adapting the game to work with the main menu!

    Tweaking the startup code

    Previously the start up code looked like this;

    ‘ we don’t need a mouse pointer
    HideMouse()
    ‘ create the game module
    game.Create( “Media/gameResources.txt” )
    ‘ init and run the app
    InitApp( 800, 600, 32 )
    RunApp()

    but we need to change that to this;

    mainmenu.Create( “Media/mainmenuResources.txt” )
    ‘ init and run the app
    InitApp( 800, 600, 32 )
    LoadGUI( “Media/gui/gui.txt” )
    RunApp()

    We no longer hide the mouse pointer because we’ll need that for accessing the menu.  We don’t create a game object any more, we create a main menu object instead.  And we’ve initialised the GUI system after InitApp.

    The game module is now created during the main menu update, specifically when the “start” button is hit.

    And that’s it!  We’ve got a game that flows from a main menu to a game and back again, with funky glowing buttons, screen transitions and animated GUI form transitions!

    On to the next part: Effects

    Comments are closed.