Hello guys! It's been a while that I have been programming with SDL, creating games and such, and all that time, I've been thinking how to create a flexible game menu, that is consistent, and has sub menu's by just passing a set of data that contains the menu items.
What I've created so far is a class, that accepts an array of size n in its constructor, calculate the text positions, and via polymorphism handle the states of the menu.
This is quite flexible, but not if I wanted to implement sub menus.
Here's the prototype of my menu class, which is a based on a state class.
Code:
class SDL_GameState
{
public :
SDL_GameState() : KeyStates(SDL_GetKeyState(NULL)) {}
virtual bool LoadResources(const char *fileName);
virtual bool OnInit() = 0;
virtual void OnCleanUp() = 0;
virtual void OnPause();
virtual void OnResume();
virtual void OnKeyDown(SDL_KeyboardEvent&, SDL_Engine&);
virtual void OnKeyUp(SDL_KeyboardEvent&, SDL_Engine&);
virtual void OnMouseMove(SDL_MouseMotionEvent&, SDL_Engine&);
virtual void OnMouseButtonUp(SDL_MouseButtonEvent&, SDL_Engine&);
virtual void OnMouseButtonDown(SDL_MouseButtonEvent&, SDL_Engine&);
virtual void OnUserEvent(SDL_UserEvent&, SDL_Engine&);
virtual void HandleKeys();
virtual void OnLoop();
virtual void OnRender(SDL_Surface*);
virtual ~SDL_GameState();
protected:
Uint8 *KeyStates;
SDL_ResourceManager<SDL_Resource_Surface> Surf_Man;
SDL_ResourceManager<SDL_Resource_MixChunk> Sound_Man;
SDL_ResourceManager<SDL_Resource_MixMusic> Music_Man;
SDL_ResourceManager<SDL_Resource_TTF> TTF_Man;
SDL_ResourceManager<SDL_Resource_Button> BTN_Man;
};
class cGameMenu : public SDL_GameState {
protected:
std::vector<MenuItem> MenuList;
const char **MenuItems;
int MenuCount;
int Selection;
public:
cGameMenu(const char*[], int);
bool OnInit();
virtual void OnKeyDown(SDL_KeyboardEvent&, SDL_Engine&);
void OnRender(SDL_Surface*);
void OnCleanUp();
~cGameMenu();
};
The menu class constructor is passed an array of string like this.
Code:
const char *InGameMenu[] = {"Resume", "Exit"};
cGameMenu newMenu(InGameMenu, 2);
And here's an example of OnKeyUp function.
Code:
void cInGameMenu::OnKeyDown(SDL_KeyboardEvent& KEvent, SDL_Engine& SEngine) {
switch(KEvent.keysym.sym) {
case SDLK_UP:
Selection = (Selection == 0? MenuList.size() - 1 : Selection - 1);
break;
case SDLK_DOWN:
Selection = (Selection == MenuList.size() - 1? 0 : Selection + 1);
break;
case SDLK_RETURN:
if(MenuList[Selection].MenuLabel == "Resume") {
SEngine.PopState();
}
else if(MenuList[Selection].MenuLabel == "Exit") {
SEngine.Quit();
}
break;
default:
break;
}
}