|
@@ -3,14 +3,23 @@
|
|
|
#include "GameStateManager.hxx"
|
|
|
#include "../SDLRenderer.hxx"
|
|
|
|
|
|
+#include <array>
|
|
|
+
|
|
|
void MenuState::on_enter(GameStateManager& gsm)
|
|
|
{
|
|
|
+ active_button_ = 0;
|
|
|
+
|
|
|
game_.reset();
|
|
|
if (auto const parent = gsm.parent(); parent!=nullptr) {
|
|
|
+ continue_button_.set_visible(true);
|
|
|
if (auto const game = dynamic_cast<PlayingState*>(parent); game!=nullptr) {
|
|
|
game_ = game;
|
|
|
+ active_button_ = 1;
|
|
|
}
|
|
|
}
|
|
|
+ else {
|
|
|
+ continue_button_.set_visible(false);
|
|
|
+ }
|
|
|
|
|
|
new_game_button_.set_on_click([&gsm] {
|
|
|
if (gsm.parent()!=nullptr)
|
|
@@ -52,21 +61,83 @@ void MenuState::on_event(GameStateManager& gsm, SDL_Event const& evt)
|
|
|
case SDL_SCANCODE_ESCAPE:
|
|
|
gsm.pop_state();
|
|
|
break;
|
|
|
+ case SDL_SCANCODE_UP:
|
|
|
+ SDL_ShowCursor(SDL_DISABLE);
|
|
|
+ --active_button_;
|
|
|
+ if (active_button_<0)
|
|
|
+ active_button_ = 4;
|
|
|
+ else if (active_button_==1 && !continue_button_.is_visible())
|
|
|
+ active_button_ = 0;
|
|
|
+ break;
|
|
|
+ case SDL_SCANCODE_DOWN:
|
|
|
+ SDL_ShowCursor(SDL_DISABLE);
|
|
|
+ ++active_button_;
|
|
|
+ if (active_button_>4)
|
|
|
+ active_button_ = 0;
|
|
|
+ else if (active_button_==1 && !continue_button_.is_visible())
|
|
|
+ active_button_ = 2;
|
|
|
+ break;
|
|
|
+ case SDL_SCANCODE_RETURN:
|
|
|
+ switch (active_button_) {
|
|
|
+ case 0:
|
|
|
+ new_game_button_.trigger();
|
|
|
+ break;
|
|
|
+ case 1:
|
|
|
+ continue_button_.trigger();
|
|
|
+ break;
|
|
|
+ case 2:
|
|
|
+ high_score_button_.trigger();
|
|
|
+ break;
|
|
|
+ case 3:
|
|
|
+ credits_button_.trigger();
|
|
|
+ break;
|
|
|
+ case 4:
|
|
|
+ quit_button_.trigger();
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else if (evt.type==SDL_MOUSEMOTION) {
|
|
|
+ SDL_ShowCursor(SDL_ENABLE);
|
|
|
+
|
|
|
+ auto const x = evt.motion.x;
|
|
|
+ auto const y = evt.motion.y;
|
|
|
+
|
|
|
+ std::array<Button*, 5> buttons{&new_game_button_, nullptr, &high_score_button_, &credits_button_, &quit_button_};
|
|
|
+ if (continue_button_.is_visible())
|
|
|
+ buttons[1] = &continue_button_;
|
|
|
+
|
|
|
+ for (std::size_t n = 0; n<buttons.size(); ++n) {
|
|
|
+ if (buttons[n]==nullptr)
|
|
|
+ continue;
|
|
|
+
|
|
|
+ auto const box = buttons[n]->get_bounding_box();
|
|
|
+ if (x>=box.x && x<=box.x+box.w && y>=box.y && y<=box.y+box.h) {
|
|
|
+ active_button_ = static_cast<int>(n);
|
|
|
+ break;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-void MenuState::update(GameStateManager& gsm, std::chrono::milliseconds delta_time)
|
|
|
+void MenuState::update(GameStateManager& gsm, std::chrono::milliseconds const delta_time)
|
|
|
{
|
|
|
(void) delta_time;
|
|
|
|
|
|
- continue_button_.set_visible(gsm.parent()!=nullptr);
|
|
|
+ auto adjust_button_size = [this, idx = 0](Button& btn) mutable {
|
|
|
+ if (idx++==active_button_) {
|
|
|
+ btn.resize(BUTTON_WIDTH, BUTTON_HEIGHT);
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ btn.resize(BUTTON_WIDTH-ACTIVE_SIZE_DIFF, BUTTON_HEIGHT-ACTIVE_SIZE_DIFF);
|
|
|
+ }
|
|
|
+ };
|
|
|
|
|
|
- new_game_button_.update();
|
|
|
- continue_button_.update();
|
|
|
- high_score_button_.update();
|
|
|
- credits_button_.update();
|
|
|
- quit_button_.update();
|
|
|
+ for (auto const btn: {&new_game_button_, &continue_button_, &high_score_button_, &credits_button_, &quit_button_}) {
|
|
|
+ adjust_button_size(*btn);
|
|
|
+ btn->update();
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
void MenuState::render(SDLRenderer& renderer)
|
|
@@ -79,13 +150,20 @@ void MenuState::render(SDLRenderer& renderer)
|
|
|
int const x = (screen_w-BUTTON_WIDTH)/2;
|
|
|
int y = (screen_h-(button_count*BUTTON_HEIGHT+(button_count-1)*20))/2;
|
|
|
|
|
|
- new_game_button_.move(x, y);
|
|
|
+ auto const adjust_button_position = [](Button& btn, int x, int y) {
|
|
|
+ auto const box = btn.get_bounding_box();
|
|
|
+ auto const dw = BUTTON_WIDTH-box.w;
|
|
|
+ auto const dh = BUTTON_HEIGHT-box.h;
|
|
|
+ btn.move(x+dw/2, y+dh/2);
|
|
|
+ };
|
|
|
+
|
|
|
+ adjust_button_position(new_game_button_, x, y);
|
|
|
if (continue_button_.is_visible()) {
|
|
|
- continue_button_.move(x, y += BUTTON_HEIGHT+20);
|
|
|
+ adjust_button_position(continue_button_, x, y += BUTTON_HEIGHT+20);
|
|
|
}
|
|
|
- high_score_button_.move(x, y += BUTTON_HEIGHT+20);
|
|
|
- credits_button_.move(x, y += BUTTON_HEIGHT+20);
|
|
|
- quit_button_.move(x, y+BUTTON_HEIGHT+20);
|
|
|
+ adjust_button_position(high_score_button_, x, y += BUTTON_HEIGHT+20);
|
|
|
+ adjust_button_position(credits_button_, x, y += BUTTON_HEIGHT+20);
|
|
|
+ adjust_button_position(quit_button_, x, y+BUTTON_HEIGHT+20);
|
|
|
|
|
|
SDL_SetRenderDrawColor(renderer, 0, 0, 0, SDL_ALPHA_OPAQUE);
|
|
|
SDL_RenderClear(renderer);
|