Table of contents
- Introduction
- Dialog source code and Layout
- DialogBuild.layout
- DialogBuild.h
- DialogBuild.cpp
- DialogBuild::DialogBuild
- DialogBuild::~DialogBuild
- DialogBuild::HandleKeyDownEvents
- DialogBuild::FrameStarted(Real timeElapsed)
- DialogBuild::preRenderTargetUpdate
- DialogBuild::postRenderTargetUpdate
- DialogBuild::handleScrollChanged
- DialogBuild::handleButtonCancel
- DialogBuild::handleButtonStructures
- DialogBuild::handleButtonBioUnits
- DialogBuild::handleButtonMechs
- DialogBuild::handleButtonVehicles
- DialogBuild::handleButton00 - DialogBuild::handleButton05
- DialogBuild::InitializeForItemType
- DialogBuild::PopulateButtons
- DialogBuild::show
- DialogBuild::hide
Introduction
- The code presented here will create a CEGUI dialog box with multiple pushbuttons, each displaying a single rotating 3D mesh, as shown in the following image
- When the user clicks on one of these buttons, the dialog box gets hidden and a game action may be executed.
IMPORTANT
- The code in this dialog box is highly game-specific, and WILL need to be changed to run in your environment.
- This code will not even compile without the game framework I am using, due to missing class definitions and structures.
- However, it should not be a major ordeal to make these changes. I hope the code is generic enough to make it useful.
Dialog source code and Layout
- Here are the complete source code and layout files for this dialog box.
- Please refer to them as they are discussed.
DialogBuild.layout
Section "Build/Cancel"
- Defines the Cancel button at the bottom
Sections "Build/Structures", "Build/BioUnits", "Build/Mechs", and "Build/Vehicles"
- Defines the four buttons at the bottom for switching itemTypes.
Section "Build/Scrollbar"
- Defines the scrollbar at the right
Sections "Build/Button00" - "Build/Button21"
- These are the actual Entity buttons, displaying the 3D meshes. They are numbered by Row/Column.
Sections "Build/ButtonLabel00" - "Build/ButtonLabel21"
- These are read-only edit boxes at the bottom of each Entity button, used to provide a label for each button.
Sections "Build/ButtonText00" - "Build/ButtonText21"
- These are read-only multi-line edit boxes to the right of each Entity button, used to provide a more detailed description for each button.
DialogBuild.h
- The first thing in this file that may need to be changed are two #defines
- DIALOG_BUTTON_COLUMNS and DIALOG_BUTTON_ROWS.
- These should be set to the number of EntityButtons defined in DialogBuild.layout.
- Next are the IDs for the itemType buttons
- buttonStructuresID, buttonBioUnitsID, buttonMechsID, and buttonVehiclesID.
- These are game-specific and hard-coded, so you will probably want to change the names and labels of these buttons.
- If you do change these, the event handlers will also need to be changed/added
- handleButtonStructures, handleButtonBioUnits...
- And finally, the last thing that may require changing are the EntityButton handlers, handleButton00 - handleButton05.
- If you keep the number of EntityButtons at six, then these won't have to change.
- However, if you add or subtract buttons, you will have to add or subtract the appropriate number of handlers.
DialogBuild.cpp
- The follow include files are game specific and are not included in this sample.
- They will have to be changed to match your environment.
Copy to clipboard
#include "InputHandler.h" #include "PlayState.h" #include "Common/StaticEntity.h" #include "Common/EntityMgr.h"
- Next are all the ID definitions for the layout.
- If you change the layout file, make sure these IDs still match the layout.
- The definition for RTT_WINDOW_SIZE essentially determines the resolution displayed in each EntityButton.
- The line
Copy to clipboard
#define INITIAL_ITEM_TYPE ItemType_Building
- is also game specific and will have to be changed to match some definition in your environment.
- It is used to determine what Entities are displayed on the buttons,
- so you will have to have some sort of identifier to distinguish between different types of Entities (Structures, Vehicles, Characters...).
DialogBuild::DialogBuild
- Probably the only thing needing changing here are the itemType button event handlers
Copy to clipboard
rootWindow->getChild(buttonStructuresID)->subscribeEvent(PushButton::EventClicked, Event::Subscriber(&DialogBuild::handleButtonStructures, this)); rootWindow->getChild(buttonBioUnitsID)->subscribeEvent(PushButton::EventClicked, Event::Subscriber(&DialogBuild::handleButtonBioUnits, this)); rootWindow->getChild(buttonMechsID)->subscribeEvent(PushButton::EventClicked, Event::Subscriber(&DialogBuild::handleButtonMechs, this)); rootWindow->getChild(buttonVehiclesID)->subscribeEvent(PushButton::EventClicked, Event::Subscriber(&DialogBuild::handleButtonVehicles, this));
- If you change the number of buttons on the dialog, then the handlers for those will also need changing accordingly
Copy to clipboard
rootWindow->getChild(buttonID[0])->subscribeEvent(PushButton::EventClicked, Event::Subscriber(&DialogBuild::handleButton00, this)); rootWindow->getChild(buttonID[1])->subscribeEvent(PushButton::EventClicked, Event::Subscriber(&DialogBuild::handleButton01, this)); rootWindow->getChild(buttonID[2])->subscribeEvent(PushButton::EventClicked, Event::Subscriber(&DialogBuild::handleButton02, this)); rootWindow->getChild(buttonID[3])->subscribeEvent(PushButton::EventClicked, Event::Subscriber(&DialogBuild::handleButton03, this)); rootWindow->getChild(buttonID[4])->subscribeEvent(PushButton::EventClicked, Event::Subscriber(&DialogBuild::handleButton04, this)); rootWindow->getChild(buttonID[5])->subscribeEvent(PushButton::EventClicked, Event::Subscriber(&DialogBuild::handleButton05, this));
DialogBuild::~DialogBuild
- Very generic. Nothing to see here.
DialogBuild::HandleKeyDownEvents
- This is used to capture the ESC key being hit, to close the dialog box.
- It uses SDL and my own InputHandler class, so you will have to change this to work with your input system.
DialogBuild::FrameStarted(Real timeElapsed)
- This should be called every frame to rotate each of the Entities.
- Pass in the time since the previous frame.
DialogBuild::preRenderTargetUpdate
- This is an event handler, called by Ogre just before the RTTs are rendered.
- Here we disable drawing everything but our Entities via the SpecialCaseRenderQueue functions, including the skybox and terrain.
- Also in this function is more game-specific code
Copy to clipboard
global->rootNode->setVisible(false);
- The idea behind this is that every "normal" sceneNode is derived from global->rootNode.
- Therefore, when this node is hidden, everything in the world attached to that node is hidden, and therefore NOT drawn on the EntityButtons.
DialogBuild::postRenderTargetUpdate
- Similar to DialogBuild
- :preRenderTargetUpdate, but here we turn on normal rendering to display everything once again.
DialogBuild::handleScrollChanged
- The event handler for the scrollbar.
DialogBuild::handleButtonCancel
- Closes the dialog box without taking any other actions.
DialogBuild::handleButtonStructures
- Event handler for the Structures button.
- Changes the item type displayed on the dialog box to ItemType_Building (a game-specific enum).
- The buttons will be re-initialized to display these.
DialogBuild::handleButtonBioUnits
- Event handler for the BioUnits button.
- Changes the item type displayed on the dialog box to ItemType_Character(a game-specific enum).
- The buttons will be re-initialized to display these.
DialogBuild::handleButtonMechs
- Event handler for the Mechs button.
- Changes the item type displayed on the dialog box to ItemType_Mech(a game-specific enum).
- The buttons will be re-initialized to display these.
DialogBuild::handleButtonVehicles
- Event handler for the Vehicles button.
- Changes the item type displayed on the dialog box to ItemType_Vehicle(a game-specific enum).
- The buttons will be re-initialized to display these.
DialogBuild::handleButton00 - DialogBuild::handleButton05
- Event handlers for each of the EntityButtons.
- Each handler hides the dialog box, then calls the game-specific code
- global->playState->SetPlaceEntityType(displayedEntityType0);
- Change this function call to do something useful in your code.
- The variable displayedEntityType indicates what type of Entity was selected by the user,
- and is initialized in the function DialogBuild
- :PopulateButtons().
DialogBuild::InitializeForItemType
- Changes the itemType to be displayed on the dialog box.
- Also updates the scrollbar according to how many different Entities will be available.
- EntityTemplate is a game-specific class which contains information about each Entity type.
- global->entityMgr->GetEntityTemplateCount() returns the number of EntityTemplates available (the count).
- The following section of code in this function will have to be changed to work with your game framework
Copy to clipboard
EntityTemplate * entityTemplate; // Count the total number of Entities eligible to be displayed in the Build dialog. entityCount = 0; for (entityIndex = 0; entityIndex < global->entityMgr->GetEntityTemplateCount(); entityIndex++) { entityTemplate = global->entityMgr->GetEntityTemplateFromIndex(entityIndex); if (entityTemplate && (entityTemplate->itemType == itemTypeToDisplay)) entityCount += 1; }
DialogBuild::PopulateButtons
- Initializes the Ogre Entities, Cameras, and RTTs for each of the EntityButtons.
- Called from the show() function, as well as when the user scrolls the scrollbar, or changes the type of item via one of the buttons.
- This function also uses the EntityTemplate class, which will have to be changed.
- Entities are not destroyed when removing them from a button.
- Rather, they are moved to a hidden sceneNode, hideObjectsNode, where they may be reused when needed.
DialogBuild::show
- Shows the dialog box.
DialogBuild::hide
- Hides the dialog box.