|
This week has been a bit hectic. Lots to do and little time to do it. We’ve had some big features that feel absolutely necessary to implement for the final version of the game. One of those was a main menu from where the player can start the game and look at highscores, credits, and the control scheme. (And quit the application of course. This was a bit of a hassle to achieve, and the solution isn’t even very pretty. More about that later. Actually, probably not.) The different buttons in the menu are instances of the same class, GUIButton, separated by an Enum parameter. Their features include:
- Clicked using the mouse, which triggers different functions depending on the kind of button
- Changing the image when the cursor is on top of the button
- Hiding the button and making it non-clickable if the player is currently in a sub menu where the button is not supposed to be shown
Since there are only two layers in the menu: the main screen, and the other screens, all that’s needed to navigate back to the main screen is a back button which always sends the player back to the main screen, regardless of which sub menu it’s in.
The system seems simple enough, but the getting all the logic right took me some time. The worst part is the clicking, because since we haven’t used a clever way to manage inputs, all we know is whether the mouse button is pressed or not. Only getting the code to perform only one menu button click when the mouse button is held means we need another member variable to store a boolean whether the button has been let go of or not between ticks. The system as it turned out is not perfect, with the main issue being that a button is clicked if the cursor is moved to the GUI button while the mouse button is held. But I figured it’s not big enough a problem to spend more time on the code. Included below is the complete Update() method from the MenuState class. I think it’s rather self-explanatory, and I included some comments to possibly clarify some things. The Draw() function is not very interesting, it basically just checks what sub menu the player is in, and draws different backgrounds, and then it checks which buttons are visible and draws those. I was going to add a screenshot of the menu, but for some reason my screenshots have started to capture Visual Studio and the Console window instead of the game screen; so here’s a picture of a fish instead. He is not amused.
Since made by one of our artists as a placeholder for the highscore screen, it’s actually perfectly related to the rest of the post.
bool MenuState::Update(float deltatime)
{
// This stuff is to make the mouse button perform only one click when held
if (!sf::Mouse::isButtonPressed(sf::Mouse::Left))
m_mousePressed = false;
// Set button border to NOT show
for (int i = 0; i SetHover(false);
}
for (int i = 0; i GetPosition().x;
int buttonY = m_buttons[i]->GetPosition().y;
int buttonWidth = m_buttons[i]->GetWidth();
int buttonHeight = m_buttons[i]->GetHeight();
int mouseX = sf::Mouse::getPosition().x;
int mouseY = sf::Mouse::getPosition().y;
ETYPE buttonType = m_buttons[i]->GetType();
if (!m_buttons[i]->GetHidden())
{
if (mouseX >= buttonX && mouseX = buttonY && mouseY SetHover(true);
if (sf::Mouse::isButtonPressed(sf::Mouse::Left) == true && m_mousePressed == false)
{
if (buttonType == START)
{
m_mousePressed = true;
return false; // Go to next State, which is the GameState
}
else if (buttonType == HIGHSCORE)
{
m_subMenu = HIGHSCORE_SCREEN;
for (int i = 0; i SetHidden(true);
}
m_buttons[4]->SetHidden(false);
m_mousePressed = true;
return true;
}
else if (buttonType == CREDITS)
{
m_subMenu = CREDITS_SCREEN;
for (int i = 0; i SetHidden(true);
}
m_buttons[4]->SetHidden(false);
m_mousePressed = true;
return true;
}
else if (buttonType == QUIT)
{
m_shutdown = true; // Will break the game loop in Engine
}
else if (buttonType == BACK)
{
m_subMenu = MAIN_SCREEN;
for (int i = 0; i SetHidden(false);
}
m_buttons[4]->SetHidden(true);
m_mousePressed = true;
return true;
}
}
return true;
}
}
}
return true;
}

About Johan Öhman
2014 Programming
|