It is currently Wed Jun 28, 2017 9:07 am

All times are UTC - 5 hours




 Page 1 of 1 [ 7 posts ] 
Author Message
 Post subject: GameDev VMK 38 - GUI & Game Flow
PostPosted: Fri Aug 17, 2007 9:37 pm 
Site Admin

Joined: Sun Feb 11, 2007 8:59 am
Posts: 1094
Location: Ontario Canada
VMK38A starts off by showing you a flow chart of the game that we are working on. All the GUI elements that we will be building are demonstrated so you can get a feel for how they are going to work once this mini-series is complete.

VMK38B shows you how to setup the base class that all GUI controls will inherit from.

VMK38C in not really related to the GUI & Game Flow but it shows you how to fix the build if you are having problems compiling your code.

VMK38D/E/F introduces the GUIButton class and shows you how to use it to create a button on the screen that toggles and highlights when you interact with it.
NOTE: there is a one-pixel offset in the texture mapping of this control which I didn't discover until I started work on the Ghost Toast VMK series. This VMK shows you how to fix this offset.

VMK38G/H The next GUI element we create is the Radio Button Group. This class allows you to add GUI Buttons to it that work together as a radio set.

VMK38I/J This VMK shows you how to implement the GUISlider class used to create sliders. The sliders can be continous or notched and range over any values that you would like. At the end of VMK38J I show you how to fix the game engine's return value.

VMK38K/L covers the GUIText class. This class is used to show text on the screen. A number of code fixes to our existing code are also shown in VMK38K.
NOTE: when calculating the size of our text, I forgot to take into consideration the scaling. To correct this, add these two lines of code after you call getTextSize inside GUIText::setText

//correct size for any scaling applied
m_v2Size.m_fx = m_v2Size.m_fx * m_fScaleFactor;
m_v2Size.m_fy = m_v2Size.m_fy * m_fScaleFactor;


Last edited by Marek on Fri May 02, 2008 7:06 am, edited 2 times in total.

Offline
 Profile  
 
 Post subject: A typo detected: 1 != 0 __________ :O)
PostPosted: Wed Sep 23, 2009 1:24 am 

Joined: Wed Aug 06, 2008 7:53 pm
Posts: 182
Location: Russia
Member-function GUIRadio::getButton() should obviously return 0 in its last statement (voice-over is correct). :roll:

File: GameDev-VMK038G-GUIRadioBtn.rar\ GUIRadioBtn-1.swf
Position (time): aprox. 04:00.

Image


Offline
 Profile  
 
 Post subject:
PostPosted: Wed Sep 23, 2009 5:52 am 
Site Admin

Joined: Sun Feb 11, 2007 8:59 am
Posts: 1094
Location: Ontario Canada
The function returns 1 which points to the "first" button in the radio list since it is 1-based. The first button should exist since it was added in the constructor. I should have written a comment here that says, "If the desired button is not found, then the first one is returned."


Offline
 Profile  
 
 Post subject: Postmortems From Game Developers 2003
PostPosted: Wed Sep 23, 2009 1:16 pm 

Joined: Wed Aug 06, 2008 7:53 pm
Posts: 182
Location: Russia
What is then the point to make the radio list’s indexation 1-based? Initially I thought of making it 0-based but then decided that it might be useful to reserve index 0 as an error condition (the same approach as in texture container etc) or as an indicator that all buttons are unpressed, which is however slightly inconsistent with radio list ideology (to have one and only one button pressed at any time).

Btw, to ensure that 1 & only 1 button is pressed we can add following code:
1) when the 1st button is added (originally in ctor), set it be pressed: setPressed( true );
2) when other buttons are added (in AddButton()), set them to be unpressed: setPressed( false );


Offline
 Profile  
 
 Post subject:
PostPosted: Sun Sep 27, 2009 5:53 am 
Site Admin

Joined: Sun Feb 11, 2007 8:59 am
Posts: 1094
Location: Ontario Canada
you are correct, zero is reserved for an error state. I guess it boils down to taste, returning 0 or 1 can be seen as "correct", depending on what behaviour you are going after.

If you do decide to return 0, make sure you handle it properly where ever you call this function or you'll be trying to access an invalid button otherwise.

If return 1 is used, you will be guarenteed to return a valid button, it just may not be the one that you requested.


Offline
 Profile  
 
 Post subject: Events system, CaptureMouse()/ReleaseMouse() and even more
PostPosted: Sat Oct 10, 2009 4:00 pm 

Joined: Wed Aug 06, 2008 7:53 pm
Posts: 182
Location: Russia
A couple words about the stuff discussed in VMK 18J (Slider class).


• The standard names for mouse events used in some RAD systems (i.e. Borland/CodeGear/Embarcadero Delph/C++Builder) are OnMouseDown, OnMouseUp, OnMouseMove (maybe without On- prefix) - still little better than homegrown “StopPressingâ€


Offline
 Profile  
 
 Post subject: Re: GameDev VMK 38 - GUI & Game Flow
PostPosted: Thu Oct 20, 2011 11:24 am 

Joined: Sat Aug 16, 2008 7:58 am
Posts: 447
I added an overload function in the GUIRadio class.... as well as the fuctions used to return values for the GUIButton, most of the functions I added are simply get functions within GUIControl and they return a Vertex2, later this will be changed to a Vector2 once I remove all Vertex's from the engine. The goal is to simplify code inside of the scene's Initialize. We create our first button, then we create our Radio button, push the pointer to radio onto our stack, then create a second button and call AddButton( *pButton ); and repeat the last process of another button and calling AddButton( *pButton ); until we created our buttons for the radio. What I am trying to do Is have the Radio Class Automate this process, I am passing values from our first button using the pointer to create a new button inside of the Radio Class... This is the overloaded functions prototype.
GUIRadio::AddButton( GUIButton *pButton, GUI_ID buttonID, unsigned int uiTextureID, Vertex2 v2BL[4], Vertex2 v2TR[4], unsigned int uiMaxSize );

We pass in the pButton, a unique ID for our menus, our textureID and uiMaxSize from the scene class where we will call this function. We also have to pass in 2 sets of Vertex2 arrays of size 4. We need to set our texture coordinates from with in scene intialize first and store them in our temp arrays. The way the AssignTexture() function is designed in GUIButton, will not allow us to retrive the BL and TR arrays and reuse them because the initial values are overwritten. When I was trying to implement this automated process, this was the little bug that took me quite a time to find, and fix. If you look at the new overloaded function it is very simple.

void GUIRadio::AddButton( GUIButton *pButton, GUI_ID buttonID, unsigned int uiTextureID, Vertex2 v2BL[4], Vertex2 v2TR[4], unsigned int uiMaxSize ) {
   
   // Create A New Button Dynamically For Each Number Of Buttons
   GUIButton *pNewButton;
   pNewButton = new GUIButton( buttonID, pButton->GetPosition(), pButton->GetSize(), pButton->GetHotOffset(), pButton->GetHotSize() );
   if ( !pNewButton ) {      
      _pErrorHandler->SetError( EC_NOT_ENOUGH_MEMORY, "Can not create a new GUIButton." );
      _pErrorHandler->ShowErrorMessage();
      _pErrorHandler->SetError( EC_NO_ERROR, "No Error" );
   } else {
      if ( !pNewButton->AssignTexture( uiTextureID, v2BL[0]._f2, v2TR[0]._f2, uiMaxSize, GUITEX_NOT_PRESSED, false ) ) {
         _pErrorHandler->SetError( EC_ERROR, "Can not assign GUITEX_NOT_PRESSED texture to GUI Button. Check function parameters for validity." );
         _pErrorHandler->ShowErrorMessage();
         _pErrorHandler->SetError( EC_NO_ERROR, "No Error" );
      }
      if ( !pNewButton->AssignTexture( uiTextureID, v2BL[1]._f2, v2TR[1]._f2, uiMaxSize, GUITEX_HOVER_NOT_PRESSED, false ) ) {
         _pErrorHandler->SetError( EC_ERROR, "Can not assign GUITEX_NOT_PRESSED texture to GUI Button. Check function parameters for validity." );
         _pErrorHandler->ShowErrorMessage();
         _pErrorHandler->SetError( EC_NO_ERROR, "No Error" );
      }
      if ( !pNewButton->AssignTexture( uiTextureID, v2BL[2]._f2, v2TR[2]._f2, uiMaxSize, GUITEX_HOVER_PRESSED, false ) ) {
         _pErrorHandler->SetError( EC_ERROR, "Can not assign GUITEX_NOT_PRESSED texture to GUI Button. Check function parameters for validity." );
         _pErrorHandler->ShowErrorMessage();
         _pErrorHandler->SetError( EC_NO_ERROR, "No Error" );
      }
      if ( !pNewButton->AssignTexture( uiTextureID, v2BL[3]._f2, v2TR[3]._f2, uiMaxSize, GUITEX_PRESSED, false ) ) {
         _pErrorHandler->SetError( EC_ERROR, "Can not assign GUITEX_NOT_PRESSED texture to GUI Button. Check function parameters for validity." );
         _pErrorHandler->ShowErrorMessage();
         _pErrorHandler->SetError( EC_NO_ERROR, "No Error" );
      }

      AddButton( pNewButton );
   }
}


Now if we look at the scene class this is what it looks like if you use the overloaded AddButton() function. Remember This Function will only duplicate The new button. As the position, size, hotoffset and hotsize are all pulled from our pointer.
But you still have the capability of calling different texture coordinates. So you can make the image even change to a different picture if you wanted to. This is what my scene's initialize now looks like where we create our radio button.

// Create All GUI Elements
   // Main Menu ---------------------------------------------------------
   GUIButton *pButton;
   GUIRadio  *pRadio;

   unsigned int uiMaxSize = _vpTextures[_uiGUI_TextureID-1]->GetSize();

   // First Button In Radio
   // Create Two Arrays Of Vertex2 For Texture Coords
   Vertex2 v2BL[4], v2TR[4];

   v2BL[0] = Vertex2( 939, 250 ); v2TR[0] = Vertex2( 959, 230 );
   v2BL[1] = Vertex2( 969, 250 ); v2TR[1] = Vertex2( 989, 230 );
   v2BL[2] = Vertex2( 879, 250 ); v2TR[2] = Vertex2( 899, 230 );
   v2BL[3] = Vertex2( 909, 250 ); v2TR[3] = Vertex2( 929, 230 );

   pButton = new GUIButton( GUID_OPTIONS_BTN_800x600, Vertex2(  410, 516 ), Vertex2( 20, 20 ), Vertex2(), Vertex2( 20, 20 ) );
   if ( !pButton ) {
      _pErrorHandler->SetError( EC_NOT_ENOUGH_MEMORY, "Can not create a new GUIButton." );
      _pErrorHandler->ShowErrorMessage();
      _pErrorHandler->SetError( EC_NO_ERROR, "No Error" );
   } else {
      if ( !pButton->AssignTexture( _uiGUI_TextureID, v2BL[0], v2TR[0], uiMaxSize, GUITEX_NOT_PRESSED, false ) ) {
         _pErrorHandler->SetError( EC_ERROR, "Can not assign GUITEX_NOT_PRESSED texture to GUI Button. Check function parameters for validity." );
         _pErrorHandler->ShowErrorMessage();
         _pErrorHandler->SetError( EC_NO_ERROR, "No Error" );
      }
      if ( !pButton->AssignTexture( _uiGUI_TextureID, v2BL[1], v2TR[1], uiMaxSize, GUITEX_HOVER_NOT_PRESSED, false ) ) {
         _pErrorHandler->SetError( EC_ERROR, "Can not assign GUITEX_NOT_PRESSED texture to GUI Button. Check function parameters for validity." );
         _pErrorHandler->ShowErrorMessage();
         _pErrorHandler->SetError( EC_NO_ERROR, "No Error" );
      }
      if ( !pButton->AssignTexture( _uiGUI_TextureID, v2BL[2], v2TR[2], uiMaxSize, GUITEX_HOVER_PRESSED, false ) ) {
         _pErrorHandler->SetError( EC_ERROR, "Can not assign GUITEX_NOT_PRESSED texture to GUI Button. Check function parameters for validity." );
         _pErrorHandler->ShowErrorMessage();
         _pErrorHandler->SetError( EC_NO_ERROR, "No Error" );
      }
      if ( !pButton->AssignTexture( _uiGUI_TextureID, v2BL[3], v2TR[3], uiMaxSize, GUITEX_PRESSED, false ) ) {
         _pErrorHandler->SetError( EC_ERROR, "Can not assign GUITEX_NOT_PRESSED texture to GUI Button. Check function parameters for validity." );
         _pErrorHandler->ShowErrorMessage();
         _pErrorHandler->SetError( EC_NO_ERROR, "No Error" );
      }

      //_GUIControl[GS_MENU].vControl.push_back( pButton );
   }

   pRadio = new GUIRadio( GUID_OPTIONS_RADIO_RESOLUTION, pButton, false, 25 );
   if ( !pRadio ) {
      _pErrorHandler->SetError( EC_NOT_ENOUGH_MEMORY, "Can not create a new GUIRadio." );
      _pErrorHandler->ShowErrorMessage();
      _pErrorHandler->SetError( EC_NO_ERROR, "No Error" );

      delete pButton;
   } else {
      // Add Button To Container
      _GUIControl[GS_MENU].vControl.push_back( pRadio );

      pRadio->AddButton( pButton, GUID_OPTIONS_BTN_1024x768, _uiGUI_TextureID, v2BL, v2TR, uiMaxSize );
      pRadio->AddButton( pButton, GUID_OPTIONS_BTN_1280x1024, _uiGUI_TextureID, v2BL, v2TR, uiMaxSize );
      
   }




The code compiles, builds and runs fine. And to add another button to the Radio button list is as simple as calling this..
pRadio->AddButton( pButton, GUID_SOME_DIFFERENT_OPTION, _uiGUI_TextureID, v2BL, v2TR, uiMaxSize );

and a new button will automatically be added. Remember you have to define what v2BL and v2TR is Like I did at the beginning before I created the first GUIButton. I hope this helps anyone, and I would love to see your replies about this.


Offline
 Profile  
 
Display posts from previous:  Sort by  
 Page 1 of 1 [ 7 posts ] 

All times are UTC - 5 hours


Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Jump to:  

cron