Browse Source

Add extras menu. Add menu transition animations

master
C. J. Howard 1 year ago
parent
commit
4e53a20169
18 changed files with 621 additions and 99 deletions
  1. +0
    -1
      CMakeLists.txt
  2. +2
    -0
      src/game/context.hpp
  3. +82
    -2
      src/game/menu.cpp
  4. +11
    -0
      src/game/menu.hpp
  5. +50
    -15
      src/game/states/controls-menu.cpp
  6. +4
    -4
      src/game/states/credits.cpp
  7. +137
    -0
      src/game/states/extras-menu.cpp
  8. +39
    -0
      src/game/states/extras-menu.hpp
  9. +20
    -5
      src/game/states/gamepad-config-menu.cpp
  10. +20
    -5
      src/game/states/graphics-menu.cpp
  11. +20
    -5
      src/game/states/keyboard-config-menu.cpp
  12. +20
    -5
      src/game/states/language-menu.cpp
  13. +1
    -1
      src/game/states/loading.cpp
  14. +106
    -20
      src/game/states/main-menu.cpp
  15. +1
    -1
      src/game/states/main-menu.hpp
  16. +84
    -25
      src/game/states/options-menu.cpp
  17. +20
    -6
      src/game/states/sound-menu.cpp
  18. +4
    -4
      src/game/states/splash.cpp

+ 0
- 1
CMakeLists.txt View File

@ -1,6 +1,5 @@
cmake_minimum_required(VERSION 3.7)
option(VERSION_STRING "Project version string" "0.0.0")
project(antkeeper VERSION ${VERSION_STRING} LANGUAGES CXX)

+ 2
- 0
src/game/context.hpp View File

@ -216,6 +216,8 @@ struct context
std::vector<std::tuple<scene::text*, scene::text*>> menu_item_texts;
std::unordered_map<std::string, int> menu_item_indices;
int* menu_item_index;
animation<float>* menu_fade_animation;
animation<float>* title_fade_animation;
// Surface scene
scene::collection* surface_scene;

+ 82
- 2
src/game/menu.cpp View File

@ -20,6 +20,9 @@
#include "game/menu.hpp"
#include "scene/text.hpp"
#include "application.hpp"
#include "animation/animation.hpp"
#include "animation/animator.hpp"
#include "animation/ease.hpp"
#include <algorithm>
namespace game {
@ -117,14 +120,12 @@ void align_text(game::context* ctx, bool center, bool has_back, float anchor_y)
for (std::size_t i = 0; i < ctx->menu_item_texts.size(); ++i)
{
auto [name, value] = ctx->menu_item_texts[i];
float x = menu_x;
float y = menu_y - ctx->menu_font.get_font_metrics().linespace * i;
if (has_back && i == ctx->menu_item_texts.size() - 1)
y -= ctx->menu_font.get_font_metrics().linespace;
if (center || i == ctx->menu_item_texts.size() - 1)
{
const auto& name_bounds = static_cast<const geom::aabb<float>&>(name->get_local_bounds());
@ -190,6 +191,13 @@ void delete_text(game::context* ctx)
ctx->menu_item_texts.clear();
}
void delete_animations(game::context* ctx)
{
ctx->animator->remove_animation(ctx->menu_fade_animation);
delete ctx->menu_fade_animation;
ctx->menu_fade_animation = nullptr;
}
void clear_callbacks(game::context* ctx)
{
// Clear menu item callbacks
@ -199,6 +207,78 @@ void clear_callbacks(game::context* ctx)
ctx->menu_back_callback = nullptr;
}
void setup_animations(game::context* ctx)
{
ctx->menu_fade_animation = new animation<float>();
animation_channel<float>* opacity_channel = ctx->menu_fade_animation->add_channel(0);
ctx->menu_fade_animation->set_frame_callback
(
[ctx](int channel, const float& opacity)
{
for (std::size_t i = 0; i < ctx->menu_item_texts.size(); ++i)
{
auto [name, value] = ctx->menu_item_texts[i];
float4 color = (i == *ctx->menu_item_index) ? active_color : inactive_color;
color[3] = color[3] * opacity;
if (name)
name->set_color(color);
if (value)
value->set_color(color);
}
}
);
ctx->animator->add_animation(ctx->menu_fade_animation);
}
void fade_in(game::context* ctx, const std::function<void()>& end_callback)
{
ctx->menu_fade_animation->set_interpolator(ease<float>::out_cubic);
animation_channel<float>* opacity_channel = ctx->menu_fade_animation->get_channel(0);
opacity_channel->remove_keyframes();
opacity_channel->insert_keyframe({0.0, 0.0f});
opacity_channel->insert_keyframe({game::menu::fade_in_duration, 1.0f});
ctx->menu_fade_animation->set_end_callback(end_callback);
for (std::size_t i = 0; i < ctx->menu_item_texts.size(); ++i)
{
auto [name, value] = ctx->menu_item_texts[i];
float4 color = (i == *ctx->menu_item_index) ? active_color : inactive_color;
color[3] = 0.0f;
if (name)
{
name->set_color(color);
name->update_tweens();
}
if (value)
{
value->set_color(color);
value->update_tweens();
}
}
ctx->menu_fade_animation->stop();
ctx->menu_fade_animation->play();
}
void fade_out(game::context* ctx, const std::function<void()>& end_callback)
{
ctx->menu_fade_animation->set_interpolator(ease<float>::out_cubic);
animation_channel<float>* opacity_channel = ctx->menu_fade_animation->get_channel(0);
opacity_channel->remove_keyframes();
opacity_channel->insert_keyframe({0.0, 1.0f});
opacity_channel->insert_keyframe({game::menu::fade_out_duration, 0.0f});
ctx->menu_fade_animation->set_end_callback(end_callback);
ctx->menu_fade_animation->stop();
ctx->menu_fade_animation->play();
}
void setup_controls(game::context* ctx)
{
ctx->controls["menu_up"]->set_activated_callback

+ 11
- 0
src/game/menu.hpp View File

@ -37,13 +37,24 @@ static constexpr float4 inactive_color{1.0f, 1.0f, 1.0f, 0.5f};
/// Padding of the mouseover bounds, as a percentage of the font size.
static constexpr float mouseover_padding = 0.1f;
/// Duration of the menu fade in animation
static constexpr float fade_in_duration = 0.25f;
/// Duration of the menu fade out animation
static constexpr float fade_out_duration = 0.25f;
void init_menu_item_index(game::context* ctx, const std::string& menu_name);
void setup_controls(game::context* ctx);
void setup_animations(game::context* ctx);
void clear_controls(game::context* ctx);
void clear_callbacks(game::context* ctx);
void remove_text_from_ui(game::context* ctx);
void delete_text(game::context* ctx);
void delete_animations(game::context* ctx);
void fade_in(game::context* ctx, const std::function<void()>& end_callback);
void fade_out(game::context* ctx, const std::function<void()>& end_callback);
void update_text_color(game::context* ctx);
void update_text_font(game::context* ctx);

+ 50
- 15
src/game/states/controls-menu.cpp View File

@ -59,31 +59,62 @@ void enter(game::context* ctx)
game::menu::align_text(ctx);
game::menu::update_text_tweens(ctx);
game::menu::add_text_to_ui(ctx);
game::menu::setup_animations(ctx);
// Construct menu item callbacks
auto select_keyboard_callback = [ctx]()
{
application::state next_state;
next_state.name = "keyboard_config_menu";
next_state.enter = std::bind(game::state::keyboard_config_menu::enter, ctx);
next_state.exit = std::bind(game::state::keyboard_config_menu::exit, ctx);
ctx->app->change_state(next_state);
// Disable controls
game::menu::clear_controls(ctx);
game::menu::fade_out
(
ctx,
[ctx]()
{
application::state next_state;
next_state.name = "keyboard_config_menu";
next_state.enter = std::bind(game::state::keyboard_config_menu::enter, ctx);
next_state.exit = std::bind(game::state::keyboard_config_menu::exit, ctx);
ctx->app->queue_state(next_state);
}
);
};
auto select_gamepad_callback = [ctx]()
{
application::state next_state;
next_state.name = "gamepad_config_menu";
next_state.enter = std::bind(game::state::gamepad_config_menu::enter, ctx);
next_state.exit = std::bind(game::state::gamepad_config_menu::exit, ctx);
ctx->app->change_state(next_state);
// Disable controls
game::menu::clear_controls(ctx);
game::menu::fade_out
(
ctx,
[ctx]()
{
application::state next_state;
next_state.name = "gamepad_config_menu";
next_state.enter = std::bind(game::state::gamepad_config_menu::enter, ctx);
next_state.exit = std::bind(game::state::gamepad_config_menu::exit, ctx);
ctx->app->queue_state(next_state);
}
);
};
auto select_back_callback = [ctx]()
{
application::state next_state;
next_state.name = "options_menu";
next_state.enter = std::bind(game::state::options_menu::enter, ctx);
next_state.exit = std::bind(game::state::options_menu::exit, ctx);
ctx->app->change_state(next_state);
// Disable controls
game::menu::clear_controls(ctx);
game::menu::fade_out
(
ctx,
[ctx]()
{
application::state next_state;
next_state.name = "options_menu";
next_state.enter = std::bind(game::state::options_menu::enter, ctx);
next_state.exit = std::bind(game::state::options_menu::exit, ctx);
ctx->app->queue_state(next_state);
}
);
};
// Build list of menu select callbacks
@ -108,6 +139,9 @@ void enter(game::context* ctx)
timeline* timeline = ctx->timeline;
float t = timeline->get_position();
timeline->add_sequence({{t + game::menu::input_delay, std::bind(game::menu::setup_controls, ctx)}});
// Fade in menu
game::menu::fade_in(ctx, nullptr);
}
void exit(game::context* ctx)
@ -115,6 +149,7 @@ void exit(game::context* ctx)
// Destruct menu
game::menu::clear_controls(ctx);
game::menu::clear_callbacks(ctx);
game::menu::delete_animations(ctx);
game::menu::remove_text_from_ui(ctx);
game::menu::delete_text(ctx);

+ 4
- 4
src/game/states/credits.cpp View File

@ -18,7 +18,7 @@
*/
#include "game/states/credits.hpp"
#include "game/states/main-menu.hpp"
#include "game/states/extras-menu.hpp"
#include "animation/ease.hpp"
#include "animation/animation.hpp"
#include "animation/animator.hpp"
@ -101,9 +101,9 @@ void enter(game::context* ctx)
// Change state
application::state next_state;
next_state.name = "main_menu";
next_state.enter = std::bind(game::state::main_menu::enter, ctx);
next_state.exit = std::bind(game::state::main_menu::exit, ctx);
next_state.name = "extras_menu";
next_state.enter = std::bind(game::state::extras_menu::enter, ctx);
next_state.exit = std::bind(game::state::extras_menu::exit, ctx);
ctx->app->change_state(next_state);
}
}

+ 137
- 0
src/game/states/extras-menu.cpp View File

@ -0,0 +1,137 @@
/*
* Copyright (C) 2021 Christopher J. Howard
*
* This file is part of Antkeeper source code.
*
* Antkeeper source code is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Antkeeper source code is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>.
*/
#include "game/states/extras-menu.hpp"
#include "game/states/main-menu.hpp"
#include "game/states/credits.hpp"
#include "application.hpp"
#include "scene/text.hpp"
#include "render/passes/clear-pass.hpp"
#include "debug/logger.hpp"
#include "game/fonts.hpp"
#include "game/menu.hpp"
#include "animation/timeline.hpp"
namespace game {
namespace state {
namespace extras_menu {
void enter(game::context* ctx)
{
ctx->ui_clear_pass->set_cleared_buffers(true, true, false);
// Construct menu item texts
scene::text* credits_text = new scene::text();
scene::text* back_text = new scene::text();
// Build list of menu item texts
ctx->menu_item_texts.push_back({credits_text, nullptr});
ctx->menu_item_texts.push_back({back_text, nullptr});
// Set content of menu item texts
credits_text->set_content((*ctx->strings)["extras_menu_credits"]);
back_text->set_content((*ctx->strings)["back"]);
// Init menu item index
game::menu::init_menu_item_index(ctx, "extras");
game::menu::update_text_color(ctx);
game::menu::update_text_font(ctx);
game::menu::align_text(ctx);
game::menu::update_text_tweens(ctx);
game::menu::add_text_to_ui(ctx);
game::menu::setup_animations(ctx);
// Construct menu item callbacks
auto select_credits_callback = [ctx]()
{
// Disable controls
game::menu::clear_controls(ctx);
game::menu::fade_out
(
ctx,
[ctx]()
{
application::state next_state;
next_state.name = "credits";
next_state.enter = std::bind(game::state::credits::enter, ctx);
next_state.exit = std::bind(game::state::credits::exit, ctx);
ctx->app->queue_state(next_state);
}
);
};
auto select_back_callback = [ctx]()
{
// Disable controls
game::menu::clear_controls(ctx);
game::menu::fade_out
(
ctx,
[ctx]()
{
application::state next_state;
next_state.name = "main_menu";
next_state.enter = std::bind(game::state::main_menu::enter, ctx, false);
next_state.exit = std::bind(game::state::main_menu::exit, ctx);
ctx->app->queue_state(next_state);
}
);
};
// Build list of menu select callbacks
ctx->menu_select_callbacks.push_back(select_credits_callback);
ctx->menu_select_callbacks.push_back(select_back_callback);
// Build list of menu left callbacks
ctx->menu_left_callbacks.push_back(nullptr);
ctx->menu_left_callbacks.push_back(nullptr);
// Build list of menu right callbacks
ctx->menu_right_callbacks.push_back(nullptr);
ctx->menu_right_callbacks.push_back(nullptr);
// Set menu back callback
ctx->menu_back_callback = select_back_callback;
// Schedule menu control setup
timeline* timeline = ctx->timeline;
float t = timeline->get_position();
timeline->add_sequence({{t + game::menu::input_delay, std::bind(game::menu::setup_controls, ctx)}});
// Fade in menu
game::menu::fade_in(ctx, nullptr);
}
void exit(game::context* ctx)
{
// Destruct menu
game::menu::clear_controls(ctx);
game::menu::clear_callbacks(ctx);
game::menu::delete_animations(ctx);
game::menu::remove_text_from_ui(ctx);
game::menu::delete_text(ctx);
ctx->ui_clear_pass->set_cleared_buffers(false, true, false);
}
} // namespace extras_menu
} // namespace state
} // namespace game

+ 39
- 0
src/game/states/extras-menu.hpp View File

@ -0,0 +1,39 @@
/*
* Copyright (C) 2021 Christopher J. Howard
*
* This file is part of Antkeeper source code.
*
* Antkeeper source code is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Antkeeper source code is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef ANTKEEPER_GAME_STATE_EXTRAS_MENU_HPP
#define ANTKEEPER_GAME_STATE_EXTRAS_MENU_HPP
#include "game/context.hpp"
namespace game {
namespace state {
/// Extras menu screen game state functions.
namespace extras_menu {
void enter(game::context* ctx);
void exit(game::context* ctx);
} // namespace extras_menu
} // namespace state
} // namespace game
#endif // ANTKEEPER_GAME_STATE_EXTRAS_MENU_HPP

+ 20
- 5
src/game/states/gamepad-config-menu.cpp View File

@ -310,15 +310,26 @@ void enter(game::context* ctx)
game::menu::align_text(ctx);
game::menu::update_text_tweens(ctx);
game::menu::add_text_to_ui(ctx);
game::menu::setup_animations(ctx);
// Construct menu item callbacks
auto select_back_callback = [ctx]()
{
application::state next_state;
next_state.name = "controls_menu";
next_state.enter = std::bind(game::state::controls_menu::enter, ctx);
next_state.exit = std::bind(game::state::controls_menu::exit, ctx);
ctx->app->change_state(next_state);
// Disable controls
game::menu::clear_controls(ctx);
game::menu::fade_out
(
ctx,
[ctx]()
{
application::state next_state;
next_state.name = "controls_menu";
next_state.enter = std::bind(game::state::controls_menu::enter, ctx);
next_state.exit = std::bind(game::state::controls_menu::exit, ctx);
ctx->app->queue_state(next_state);
}
);
};
// Build list of menu select callbacks
@ -337,6 +348,9 @@ void enter(game::context* ctx)
timeline* timeline = ctx->timeline;
float t = timeline->get_position();
timeline->add_sequence({{t + game::menu::input_delay, std::bind(game::menu::setup_controls, ctx)}});
// Fade in menu
game::menu::fade_in(ctx, nullptr);
}
void exit(game::context* ctx)
@ -344,6 +358,7 @@ void exit(game::context* ctx)
// Destruct menu
game::menu::clear_controls(ctx);
game::menu::clear_callbacks(ctx);
game::menu::delete_animations(ctx);
game::menu::remove_text_from_ui(ctx);
game::menu::delete_text(ctx);

+ 20
- 5
src/game/states/graphics-menu.cpp View File

@ -91,6 +91,7 @@ void enter(game::context* ctx)
game::menu::align_text(ctx);
game::menu::update_text_tweens(ctx);
game::menu::add_text_to_ui(ctx);
game::menu::setup_animations(ctx);
// Construct menu item callbacks
auto toggle_fullscreen_callback = [ctx]()
@ -271,11 +272,21 @@ void enter(game::context* ctx)
};
auto select_back_callback = [ctx]()
{
application::state next_state;
next_state.name = "options_menu";
next_state.enter = std::bind(game::state::options_menu::enter, ctx);
next_state.exit = std::bind(game::state::options_menu::exit, ctx);
ctx->app->change_state(next_state);
// Disable controls
game::menu::clear_controls(ctx);
game::menu::fade_out
(
ctx,
[ctx]()
{
application::state next_state;
next_state.name = "options_menu";
next_state.enter = std::bind(game::state::options_menu::enter, ctx);
next_state.exit = std::bind(game::state::options_menu::exit, ctx);
ctx->app->queue_state(next_state);
}
);
};
// Build list of menu select callbacks
@ -309,6 +320,9 @@ void enter(game::context* ctx)
timeline* timeline = ctx->timeline;
float t = timeline->get_position();
timeline->add_sequence({{t + game::menu::input_delay, std::bind(game::menu::setup_controls, ctx)}});
// Fade in menu
game::menu::fade_in(ctx, nullptr);
}
void exit(game::context* ctx)
@ -316,6 +330,7 @@ void exit(game::context* ctx)
// Destruct menu
game::menu::clear_controls(ctx);
game::menu::clear_callbacks(ctx);
game::menu::delete_animations(ctx);
game::menu::remove_text_from_ui(ctx);
game::menu::delete_text(ctx);

+ 20
- 5
src/game/states/keyboard-config-menu.cpp View File

@ -265,15 +265,26 @@ void enter(game::context* ctx)
game::menu::align_text(ctx);
game::menu::update_text_tweens(ctx);
game::menu::add_text_to_ui(ctx);
game::menu::setup_animations(ctx);
// Construct menu item callbacks
auto select_back_callback = [ctx]()
{
application::state next_state;
next_state.name = "controls_menu";
next_state.enter = std::bind(game::state::controls_menu::enter, ctx);
next_state.exit = std::bind(game::state::controls_menu::exit, ctx);
ctx->app->change_state(next_state);
// Disable controls
game::menu::clear_controls(ctx);
game::menu::fade_out
(
ctx,
[ctx]()
{
application::state next_state;
next_state.name = "controls_menu";
next_state.enter = std::bind(game::state::controls_menu::enter, ctx);
next_state.exit = std::bind(game::state::controls_menu::exit, ctx);
ctx->app->queue_state(next_state);
}
);
};
// Build list of menu select callbacks
@ -292,6 +303,9 @@ void enter(game::context* ctx)
timeline* timeline = ctx->timeline;
float t = timeline->get_position();
timeline->add_sequence({{t + game::menu::input_delay, std::bind(game::menu::setup_controls, ctx)}});
// Fade in menu
game::menu::fade_in(ctx, nullptr);
}
void exit(game::context* ctx)
@ -299,6 +313,7 @@ void exit(game::context* ctx)
// Destruct menu
game::menu::clear_controls(ctx);
game::menu::clear_callbacks(ctx);
game::menu::delete_animations(ctx);
game::menu::remove_text_from_ui(ctx);
game::menu::delete_text(ctx);

+ 20
- 5
src/game/states/language-menu.cpp View File

@ -65,6 +65,7 @@ void enter(game::context* ctx)
game::menu::align_text(ctx);
game::menu::update_text_tweens(ctx);
game::menu::add_text_to_ui(ctx);
game::menu::setup_animations(ctx);
// Construct menu item callbacks
auto next_language_callback = [ctx]()
@ -137,11 +138,21 @@ void enter(game::context* ctx)
};
auto select_back_callback = [ctx]()
{
application::state next_state;
next_state.name = "options_menu";
next_state.enter = std::bind(game::state::options_menu::enter, ctx);
next_state.exit = std::bind(game::state::options_menu::exit, ctx);
ctx->app->change_state(next_state);
// Disable controls
game::menu::clear_controls(ctx);
game::menu::fade_out
(
ctx,
[ctx]()
{
application::state next_state;
next_state.name = "options_menu";
next_state.enter = std::bind(game::state::options_menu::enter, ctx);
next_state.exit = std::bind(game::state::options_menu::exit, ctx);
ctx->app->queue_state(next_state);
}
);
};
// Build list of menu select callbacks
@ -163,6 +174,9 @@ void enter(game::context* ctx)
timeline* timeline = ctx->timeline;
float t = timeline->get_position();
timeline->add_sequence({{t + game::menu::input_delay, std::bind(game::menu::setup_controls, ctx)}});
// Fade in menu
game::menu::fade_in(ctx, nullptr);
}
void exit(game::context* ctx)
@ -170,6 +184,7 @@ void exit(game::context* ctx)
// Destruct menu
game::menu::clear_controls(ctx);
game::menu::clear_callbacks(ctx);
game::menu::delete_animations(ctx);
game::menu::remove_text_from_ui(ctx);
game::menu::delete_text(ctx);

+ 1
- 1
src/game/states/loading.cpp View File

@ -130,7 +130,7 @@ void enter(game::context* ctx)
if (ctx->option_quick_start.has_value())
{
next_state.name = "main_menu";
next_state.enter = std::bind(game::state::main_menu::enter, ctx);
next_state.enter = std::bind(game::state::main_menu::enter, ctx, true);
next_state.exit = std::bind(game::state::main_menu::exit, ctx);
}
else

+ 106
- 20
src/game/states/main-menu.cpp View File

@ -19,9 +19,9 @@
#include "game/states/main-menu.hpp"
#include "game/states/options-menu.hpp"
#include "game/states/extras-menu.hpp"
#include "game/states/forage.hpp"
#include "game/states/nuptial-flight.hpp"
#include "game/states/credits.hpp"
#include "game/menu.hpp"
#include "render/passes/clear-pass.hpp"
#include "resources/resource-manager.hpp"
@ -38,7 +38,29 @@ namespace game {
namespace state {
namespace main_menu {
void enter(game::context* ctx)
static void fade_in_title(game::context* ctx)
{
ctx->title_fade_animation->set_interpolator(ease<float>::out_cubic);
animation_channel<float>* opacity_channel = ctx->title_fade_animation->get_channel(0);
opacity_channel->remove_keyframes();
opacity_channel->insert_keyframe({0.0, 0.0f});
opacity_channel->insert_keyframe({game::menu::fade_in_duration, 1.0f});
ctx->title_fade_animation->stop();
ctx->title_fade_animation->play();
}
static void fade_out_title(game::context* ctx)
{
ctx->title_fade_animation->set_interpolator(ease<float>::out_cubic);
animation_channel<float>* opacity_channel = ctx->title_fade_animation->get_channel(0);
opacity_channel->remove_keyframes();
opacity_channel->insert_keyframe({0.0, 1.0f});
opacity_channel->insert_keyframe({game::menu::fade_out_duration, 0.0f});
ctx->title_fade_animation->stop();
ctx->title_fade_animation->play();
}
void enter(game::context* ctx, bool fade_in)
{
ctx->ui_clear_pass->set_cleared_buffers(true, true, false);
@ -54,27 +76,42 @@ void enter(game::context* ctx)
float title_w = title_aabb.max_point.x - title_aabb.min_point.x;
float title_h = title_aabb.max_point.y - title_aabb.min_point.y;
ctx->title_text->set_translation({std::round(-title_w * 0.5f), std::round(-title_h * 0.5f + (std::get<1>(ctx->app->get_viewport_dimensions()) / 3.0f) / 2.0f), 0.0f});
ctx->title_text->update_tweens();
// Add title text to UI
ctx->ui_scene->add_object(ctx->title_text);
ctx->title_text->update_tweens();
// Construct title fade animation
ctx->title_fade_animation = new animation<float>();
animation_channel<float>* opacity_channel = ctx->title_fade_animation->add_channel(0);
ctx->title_fade_animation->set_frame_callback
(
[ctx](int channel, const float& opacity)
{
float4 color = ctx->title_text->get_color();
color[3] = opacity;
ctx->title_text->set_color(color);
}
);
ctx->animator->add_animation(ctx->title_fade_animation);
// Construct menu item texts
scene::text* start_text = new scene::text();
scene::text* options_text = new scene::text();
scene::text* credits_text = new scene::text();
scene::text* extras_text = new scene::text();
scene::text* quit_text = new scene::text();
// Build list of menu item texts
ctx->menu_item_texts.push_back({start_text, nullptr});
ctx->menu_item_texts.push_back({options_text, nullptr});
ctx->menu_item_texts.push_back({credits_text, nullptr});
ctx->menu_item_texts.push_back({extras_text, nullptr});
ctx->menu_item_texts.push_back({quit_text, nullptr});
// Set content of menu item texts
start_text->set_content((*ctx->strings)["main_menu_start"]);
options_text->set_content((*ctx->strings)["main_menu_options"]);
credits_text->set_content((*ctx->strings)["main_menu_credits"]);
extras_text->set_content((*ctx->strings)["main_menu_extras"]);
quit_text->set_content((*ctx->strings)["main_menu_quit"]);
// Init menu item index
@ -85,6 +122,7 @@ void enter(game::context* ctx)
game::menu::align_text(ctx, true, false, (-std::get<1>(ctx->app->get_viewport_dimensions()) / 3.0f) / 2.0f);
game::menu::update_text_tweens(ctx);
game::menu::add_text_to_ui(ctx);
game::menu::setup_animations(ctx);
auto select_start_callback = [ctx]()
{
@ -112,23 +150,50 @@ void enter(game::context* ctx)
// Start fade out to white
ctx->fade_transition_color->set_value({1, 1, 1});
ctx->fade_transition->transition(fade_out_duration, false, ease<float>::out_quad, false);
ctx->fade_transition->transition(fade_out_duration, false, ease<float>::out_cubic, false);
};
auto select_options_callback = [ctx]()
{
application::state next_state;
next_state.name = "options_menu";
next_state.enter = std::bind(game::state::options_menu::enter, ctx);
next_state.exit = std::bind(game::state::options_menu::exit, ctx);
ctx->app->change_state(next_state);
game::menu::clear_controls(ctx);
// Fade out title
fade_out_title(ctx);
// Fade out menu
game::menu::fade_out
(
ctx,
[ctx]()
{
application::state next_state;
next_state.name = "options_menu";
next_state.enter = std::bind(game::state::options_menu::enter, ctx);
next_state.exit = std::bind(game::state::options_menu::exit, ctx);
ctx->app->queue_state(next_state);
}
);
};
auto select_credits_callback = [ctx]()
auto select_extras_callback = [ctx]()
{
application::state next_state;
next_state.name = "credits";
next_state.enter = std::bind(game::state::credits::enter, ctx);
next_state.exit = std::bind(game::state::credits::exit, ctx);
ctx->app->change_state(next_state);
// Disable controls
game::menu::clear_controls(ctx);
// Fade out title
fade_out_title(ctx);
// Fade out menu
game::menu::fade_out
(
ctx,
[ctx]()
{
application::state next_state;
next_state.name = "extras_menu";
next_state.enter = std::bind(game::state::extras_menu::enter, ctx);
next_state.exit = std::bind(game::state::extras_menu::exit, ctx);
ctx->app->queue_state(next_state);
}
);
};
auto select_quit_callback = [ctx]()
{
@ -138,7 +203,7 @@ void enter(game::context* ctx)
// Build list of menu select callbacks
ctx->menu_select_callbacks.push_back(select_start_callback);
ctx->menu_select_callbacks.push_back(select_options_callback);
ctx->menu_select_callbacks.push_back(select_credits_callback);
ctx->menu_select_callbacks.push_back(select_extras_callback);
ctx->menu_select_callbacks.push_back(select_quit_callback);
// Build list of menu left callbacks
@ -160,16 +225,37 @@ void enter(game::context* ctx)
timeline* timeline = ctx->timeline;
float t = timeline->get_position();
timeline->add_sequence({{t + game::menu::input_delay, std::bind(game::menu::setup_controls, ctx)}});
if (fade_in)
{
ctx->fade_transition->transition(0.5f, true, ease<float>::out_cubic);
}
else
{
// Fade in title
ctx->title_text->set_color({1.0f, 1.0f, 1.0f, 0.0f});
ctx->title_text->update_tweens();
fade_in_title(ctx);
// Fade in menu
game::menu::fade_in(ctx, nullptr);
}
}
void exit(game::context* ctx)
{
{
// Destruct menu
game::menu::clear_controls(ctx);
game::menu::clear_callbacks(ctx);
game::menu::delete_animations(ctx);
game::menu::remove_text_from_ui(ctx);
game::menu::delete_text(ctx);
// Destruct title animation
ctx->animator->remove_animation(ctx->title_fade_animation);
delete ctx->title_fade_animation;
ctx->title_fade_animation = nullptr;
// Destruct title text
ctx->ui_scene->remove_object(ctx->title_text);
delete ctx->title_text;

+ 1
- 1
src/game/states/main-menu.hpp View File

@ -28,7 +28,7 @@ namespace state {
/// Main menu screen game state functions.
namespace main_menu {
void enter(game::context* ctx);
void enter(game::context* ctx, bool fade_in);
void exit(game::context* ctx);
} // namespace main_menu

+ 84
- 25
src/game/states/options-menu.cpp View File

@ -70,51 +70,106 @@ void enter(game::context* ctx)
game::menu::align_text(ctx, true);
game::menu::update_text_tweens(ctx);
game::menu::add_text_to_ui(ctx);
game::menu::setup_animations(ctx);
// Construct menu item callbacks
auto select_controls_callback = [ctx]()
{
application::state next_state;
next_state.name = "controls_menu";
next_state.enter = std::bind(game::state::controls_menu::enter, ctx);
next_state.exit = std::bind(game::state::controls_menu::exit, ctx);
ctx->app->change_state(next_state);
// Disable controls
game::menu::clear_controls(ctx);
// Return to main menu
game::menu::fade_out
(
ctx,
[ctx]()
{
application::state next_state;
next_state.name = "controls_menu";
next_state.enter = std::bind(game::state::controls_menu::enter, ctx);
next_state.exit = std::bind(game::state::controls_menu::exit, ctx);
ctx->app->queue_state(next_state);
}
);
};
auto select_graphics_callback = [ctx]()
{
application::state next_state;
next_state.name = "graphics_menu";
next_state.enter = std::bind(game::state::graphics_menu::enter, ctx);
next_state.exit = std::bind(game::state::graphics_menu::exit, ctx);
ctx->app->change_state(next_state);
// Disable controls
game::menu::clear_controls(ctx);
// Return to main menu
game::menu::fade_out
(
ctx,
[ctx]()
{
application::state next_state;
next_state.name = "graphics_menu";
next_state.enter = std::bind(game::state::graphics_menu::enter, ctx);
next_state.exit = std::bind(game::state::graphics_menu::exit, ctx);
ctx->app->queue_state(next_state);
}
);
};
auto select_sound_callback = [ctx]()
{
application::state next_state;
next_state.name = "sound_menu";
next_state.enter = std::bind(game::state::sound_menu::enter, ctx);
next_state.exit = std::bind(game::state::sound_menu::exit, ctx);
ctx->app->change_state(next_state);
// Disable controls
game::menu::clear_controls(ctx);
// Return to main menu
game::menu::fade_out
(
ctx,
[ctx]()
{
application::state next_state;
next_state.name = "sound_menu";
next_state.enter = std::bind(game::state::sound_menu::enter, ctx);
next_state.exit = std::bind(game::state::sound_menu::exit, ctx);
ctx->app->queue_state(next_state);
}
);
};
auto select_language_callback = [ctx]()
{
application::state next_state;
next_state.name = "language_menu";
next_state.enter = std::bind(game::state::language_menu::enter, ctx);
next_state.exit = std::bind(game::state::language_menu::exit, ctx);
ctx->app->change_state(next_state);
// Disable controls
game::menu::clear_controls(ctx);
// Return to main menu
game::menu::fade_out
(
ctx,
[ctx]()
{
application::state next_state;
next_state.name = "language_menu";
next_state.enter = std::bind(game::state::language_menu::enter, ctx);
next_state.exit = std::bind(game::state::language_menu::exit, ctx);
ctx->app->queue_state(next_state);
}
);
};
auto select_back_callback = [ctx]()
{
// Disable controls
game::menu::clear_controls(ctx);
// Save config
game::save_config(ctx);
// Return to main menu
application::state next_state;
next_state.name = "main_menu";
next_state.enter = std::bind(game::state::main_menu::enter, ctx);
next_state.exit = std::bind(game::state::main_menu::exit, ctx);
ctx->app->change_state(next_state);
game::menu::fade_out
(
ctx,
[ctx]()
{
application::state next_state;
next_state.name = "main_menu";
next_state.enter = std::bind(game::state::main_menu::enter, ctx, false);
next_state.exit = std::bind(game::state::main_menu::exit, ctx);
ctx->app->queue_state(next_state);
}
);
};
// Build list of menu select callbacks
@ -137,6 +192,9 @@ void enter(game::context* ctx)
timeline* timeline = ctx->timeline;
float t = timeline->get_position();
timeline->add_sequence({{t + game::menu::input_delay, std::bind(game::menu::setup_controls, ctx)}});
// Fade in menu
game::menu::fade_in(ctx, nullptr);
}
void exit(game::context* ctx)
@ -144,6 +202,7 @@ void exit(game::context* ctx)
// Destruct menu
game::menu::clear_controls(ctx);
game::menu::clear_callbacks(ctx);
game::menu::delete_animations(ctx);
game::menu::remove_text_from_ui(ctx);
game::menu::delete_text(ctx);

+ 20
- 6
src/game/states/sound-menu.cpp View File

@ -89,7 +89,7 @@ void enter(game::context* ctx)
game::menu::align_text(ctx);
game::menu::update_text_tweens(ctx);
game::menu::add_text_to_ui(ctx);
game::menu::setup_animations(ctx);
// Construct menu item callbacks
auto increase_volume_callback = [ctx](float* volume)
@ -178,11 +178,21 @@ void enter(game::context* ctx)
};
auto select_back_callback = [ctx]()
{
application::state next_state;
next_state.name = "options_menu";
next_state.enter = std::bind(game::state::options_menu::enter, ctx);
next_state.exit = std::bind(game::state::options_menu::exit, ctx);
ctx->app->change_state(next_state);
// Disable controls
game::menu::clear_controls(ctx);
game::menu::fade_out
(
ctx,
[ctx]()
{
application::state next_state;
next_state.name = "options_menu";
next_state.enter = std::bind(game::state::options_menu::enter, ctx);
next_state.exit = std::bind(game::state::options_menu::exit, ctx);
ctx->app->queue_state(next_state);
}
);
};
// Build list of menu select callbacks
@ -219,6 +229,9 @@ void enter(game::context* ctx)
timeline* timeline = ctx->timeline;
float t = timeline->get_position();
timeline->add_sequence({{t + game::menu::input_delay, std::bind(game::menu::setup_controls, ctx)}});
// Fade in menu
game::menu::fade_in(ctx, nullptr);
}
void exit(game::context* ctx)
@ -226,6 +239,7 @@ void exit(game::context* ctx)
// Destruct menu
game::menu::clear_controls(ctx);
game::menu::clear_callbacks(ctx);
game::menu::delete_animations(ctx);
game::menu::remove_text_from_ui(ctx);
game::menu::delete_text(ctx);

+ 4
- 4
src/game/states/splash.cpp View File

@ -49,7 +49,7 @@ void enter(game::context* ctx)
// Build splash fade in animation
ctx->splash_fade_in_animation = new animation<float>();
animation_channel<float>* splash_fade_in_opacity_channel = ctx->splash_fade_in_animation->add_channel(0);
ctx->splash_fade_in_animation->set_interpolator(ease<float>::in_quad);
ctx->splash_fade_in_animation->set_interpolator(ease<float>::out_cubic);
splash_fade_in_opacity_channel->insert_keyframe({0.0, 0.0f});
splash_fade_in_opacity_channel->insert_keyframe({splash_fade_in_duration, 1.0f});
splash_fade_in_opacity_channel->insert_keyframe({splash_fade_in_duration + splash_duration, 1.0f});
@ -57,7 +57,7 @@ void enter(game::context* ctx)
// Build splash fade out animation
ctx->splash_fade_out_animation = new animation<float>();
animation_channel<float>* splash_fade_out_opacity_channel = ctx->splash_fade_out_animation->add_channel(0);
ctx->splash_fade_out_animation->set_interpolator(ease<float>::out_quad);
ctx->splash_fade_out_animation->set_interpolator(ease<float>::out_cubic);
splash_fade_out_opacity_channel->insert_keyframe({0.0, 1.0f});
splash_fade_out_opacity_channel->insert_keyframe({splash_fade_out_duration, 0.0f});
@ -95,7 +95,7 @@ void enter(game::context* ctx)
{
application::state next_state;
next_state.name = "main_menu";
next_state.enter = std::bind(game::state::main_menu::enter, ctx);
next_state.enter = std::bind(game::state::main_menu::enter, ctx, true);
next_state.exit = std::bind(game::state::main_menu::exit, ctx);
ctx->app->queue_state(next_state);
}
@ -124,7 +124,7 @@ void enter(game::context* ctx)
// Change state
application::state next_state;
next_state.name = "main_menu";
next_state.enter = std::bind(game::state::main_menu::enter, ctx);
next_state.enter = std::bind(game::state::main_menu::enter, ctx, true);
next_state.exit = std::bind(game::state::main_menu::exit, ctx);
ctx->app->change_state(next_state);
}

Loading…
Cancel
Save