keyboard controls for start and pause menus

This commit is contained in:
ohsqueezy 2023-12-14 01:12:38 -05:00
parent 9696d3a835
commit 1db0a870d9
4 changed files with 221 additions and 45 deletions

View File

@ -72,7 +72,8 @@
"hue shift frequency": 0.025,
"flash length": 1.1,
"flash darken factor": 2.0,
"fullscreen enabled": true
"fullscreen enabled": true,
"blink frequency": 0.35
},
"configuration":
@ -95,7 +96,7 @@
"input":
{
"suppress any key on mods": true,
"any key ignore commands": ["left", "right", "up", "down"]
"any key ignore commands": ["left", "right", "up", "down", "pause"]
},
"keys":
@ -104,7 +105,12 @@
"skip forward": ["CTRL", "SHIFT", "right"],
"skip backward": ["CTRL", "SHIFT", "left"],
"memory": ["CTRL", "SHIFT", "m"],
"coords": ["CTRL", "SHIFT", "c"]
"coords": ["CTRL", "SHIFT", "c"],
"up": [["up"], ["w"]],
"right": [["right"], ["d"]],
"down": [["down"], ["s"]],
"left": [["left"], ["a"]],
"pause": "escape"
},
"log":
@ -397,15 +403,15 @@
"messages dimensions": [500.0, 48.0],
"messages scale": [0.9, 0.08],
"messages foreground": [255.0, 255.0, 255.0, 255.0],
"end text": "THE END",
"end text": " ",
"unlock mirror": "✩ UNLOCKED MIRROR MODE ✩",
"unlock warped": "✩ UNLOCKED WARPED MODE ✩",
"unlock beef": "✩ UNLOCKED BEEF CAKE ✩",
"unlock buffalo": "✩ UNLOCKED BUFFALO BEEF CAKE ✩",
"unlock jackpot": "✩ UNLOCKED GOLDEN CAKE ✩",
"new best": "✩ NEW BEST TIME ✩",
"thanks": "Thank you for playtesting! @carlosissurreal @snakesandrews @paotato @big__flan @8ude @emilyrakoonce @xed @markkleeb @sortasoft @toddwords @computerlunch @synodai @sleepin @artfail @wondervillenyc @gumbo_nyc",
"thanks translation": [0.36, -0.78],
"thanks": "Thank you playtesters @carlosissurreal @snakesandrews @paotato @big__flan @8ude @emilyrakoonce @xed @markkleeb @sortasoft @toddwords @computerlunch @synodai @sleepin @artfail @wondervillenyc @gumbo_nyc",
"thanks translation": [0.3, -0.78],
"thanks scale": [1.58, 0.13],
"thanks wrap": 1080
}

2
lib/sb

@ -1 +1 @@
Subproject commit 464e69be56299a890ee73b0ee937f2e0c3dce3b0
Subproject commit 8184a62a54feda11ea9543a7e615c4289ee0e593

View File

@ -161,6 +161,9 @@ Cakefoot::Cakefoot()
shift_hue_animation.frame_length(configuration()("display", "hue shift frequency"));
shift_hue_animation.play();
/* Start blink animation */
blink_animation.play();
if (!use_play_button)
{
/* Load title screen */
@ -386,22 +389,7 @@ void Cakefoot::set_up_buttons()
load_level(level_select_index);
});
button.at("resume").on_state_change([&](bool state){
unpaused_timer.on();
run_timer.on();
/* Transition between menu theme and main theme */
if (audio.at("menu").playing())
{
audio.at("menu").pause();
}
if (audio.at("main").paused())
{
audio.at("main").resume();
}
else if (audio.at("main").fading() || !audio.at("main").playing())
{
audio.at("main").play();
}
sb::Delegate::post("resume", false);
});
button.at("reset").on_state_change([&](bool state){
sb::Delegate::post(reset_command_name, false);
@ -914,6 +902,9 @@ Curve& Cakefoot::curve()
void Cakefoot::load_level(int index)
{
/* Cancel selection */
selected.reset();
/* Wrap the index if it is out of range. */
index = glm::mod(index, static_cast<int>(configuration()("levels").size()));
@ -1600,6 +1591,11 @@ void Cakefoot::shift_hue()
rotating_hue.shift_hue(configuration()("display", "hue shift").get<float>());
}
void Cakefoot::blink()
{
blinking_visible = !blinking_visible;
}
std::string Cakefoot::format_clock(float amount)
{
int minutes = int(amount) / 60;
@ -1638,17 +1634,120 @@ void Cakefoot::respond(SDL_Event& event)
/* Custom keys for the title screen */
if (level_index == 0)
{
if (!shift_pressed && sb::Delegate::compare(event, "left"))
bool challenge_enabled = button.at("challenge decrement").enabled();
bool level_enabled = button.at("level decrement").enabled();
bool profile_enabled = button.at("profile decrement").enabled();
bool view_enabled = button.at("view decrement").enabled();
if (sb::Delegate::compare(event, "down"))
{
button.at("level decrement").press();
if (selected == "start")
{
if (challenge_enabled) selected = "challenge decrement";
else if (level_enabled) selected = "level decrement";
else if (profile_enabled) selected = "profile decrement";
else if (view_enabled) selected = "view decrement";
}
else if (selected == "challenge decrement")
{
selected = "challenge increment";
}
else if (selected == "challenge increment")
{
if (level_enabled) selected = "level decrement";
else if (profile_enabled) selected = "profile decrement";
else if (view_enabled) selected = "view decrement";
else selected = "start";
}
else if (selected == "level decrement")
{
selected = "level increment";
}
else if (selected == "level increment")
{
if (profile_enabled) selected = "profile decrement";
else if (view_enabled) selected = "view decrement";
else selected = "start";
}
else if (selected == "profile decrement")
{
selected = "profile increment";
}
else if (selected == "profile increment")
{
if (view_enabled) selected = "view decrement";
else selected = "start";
}
else if (selected == "view decrement")
{
selected = "view increment";
}
else
{
selected = "start";
}
}
else if (!shift_pressed && sb::Delegate::compare(event, "right"))
else if (sb::Delegate::compare(event, "up"))
{
button.at("level increment").press();
if (selected == "start")
{
if (view_enabled) selected = "view increment";
else if (profile_enabled) selected = "profile increment";
else if (level_enabled) selected = "level increment";
else if (challenge_enabled) selected = "challenge increment";
}
else if (selected == "challenge increment")
{
selected = "challenge decrement";
}
else if (selected == "challenge decrement")
{
selected = "start";
}
else if (selected == "level increment")
{
selected = "level decrement";
}
else if (selected == "level decrement")
{
if (challenge_enabled) selected = "challenge increment";
else selected = "start";
}
else if (selected == "profile increment")
{
selected = "profile decrement";
}
else if (selected == "profile decrement")
{
if (level_enabled) selected = "level increment";
else if (challenge_enabled) selected = "challenge increment";
else selected = "start";
}
else if (selected == "view increment")
{
selected = "view decrement";
}
else if (selected == "view decrement")
{
if (profile_enabled) selected = "profile increment";
else if (level_enabled) selected = "level increment";
else if (challenge_enabled) selected = "challenge increment";
else selected = "start";
}
else
{
selected = "start";
}
}
else if (sb::Delegate::compare(event, "any"))
{
button.at("start").press();
if (!selected.has_value())
{
button.at("start").press();
}
else
{
button.at(selected.value()).press();
}
}
}
@ -1673,6 +1772,26 @@ void Cakefoot::respond(SDL_Event& event)
}
}
/* Custom keys for pause menu */
else if (!unpaused_timer)
{
if (sb::Delegate::compare(event, "up") || sb::Delegate::compare(event, "down"))
{
if (selected == "resume")
{
selected = "reset";
}
else
{
selected = "resume";
}
}
else if (selected.has_value() && sb::Delegate::compare(event, "any"))
{
button.at(selected.value()).press();
}
}
/* Perspective and view modifications */
if (event.type == SDL_MOUSEWHEEL && shift_pressed)
{
@ -1812,21 +1931,53 @@ void Cakefoot::respond(SDL_Event& event)
else if (sb::Delegate::compare(event, "pause") && level_index > 0 && static_cast<std::size_t>(level_index) <= configuration()("levels").size() - 2)
{
unpaused_timer.off();
run_timer.off();
if (!unpaused_timer)
{
sb::Delegate::post("resume", false);
}
else
{
/* Pause */
unpaused_timer.off();
run_timer.off();
/* Transition between main theme and menu theme */
if (audio.at("main").playing())
{
audio.at("main").pause();
/* Transition between main theme and menu theme */
if (audio.at("main").playing())
{
audio.at("main").pause();
}
if (audio.at("menu").paused())
{
audio.at("menu").resume();
}
else if (audio.at("menu").fading() || !audio.at("menu").playing())
{
audio.at("menu").play();
}
}
if (audio.at("menu").paused())
}
else if (sb::Delegate::compare(event, "resume") && !unpaused_timer &&
level_index > 0 && static_cast<std::size_t>(level_index) <= configuration()("levels").size() - 2)
{
selected.reset();
/* Unpause */
unpaused_timer.on();
run_timer.on();
/* Transition between menu theme and main theme */
if (audio.at("menu").playing())
{
audio.at("menu").resume();
audio.at("menu").pause();
}
else if (audio.at("menu").fading() || !audio.at("menu").playing())
if (audio.at("main").paused())
{
audio.at("menu").play();
audio.at("main").resume();
}
else if (audio.at("main").fading() || !audio.at("main").playing())
{
audio.at("main").play();
}
}
@ -1973,6 +2124,7 @@ void Cakefoot::update(float timestamp)
submit_score_animation.update(timestamp);
shift_hue_animation.update(timestamp);
flash_animation.update(timestamp);
blink_animation.update(timestamp);
/* Transformation for looking at the center of the field of play from the camera position. */
view = glm::lookAt(camera_position, {0.0f, 0.0f, 0.0f}, glm::vec3{0.0f, 1.0f, 0.0f});
@ -2276,7 +2428,10 @@ void Cakefoot::update(float timestamp)
{
glUniform4fv(uniform.at("color addition"), 1, &rotating_hue.normal()[0]);
}
button.at("start").draw(uniform["mvp"], view, projection, uniform["texture enabled"]);
if (selected != "start" || blinking_visible)
{
button.at("start").draw(uniform["mvp"], view, projection, uniform["texture enabled"]);
}
if (!flash_animation.playing())
{
glUniform4fv(uniform.at("color addition"), 1, &glm::vec4(0)[0]);
@ -2291,7 +2446,10 @@ void Cakefoot::update(float timestamp)
"view decrement", "view increment"
})
{
button.at(name).draw(uniform.at("mvp"), view, projection, uniform.at("texture enabled"));
if (selected != name || blinking_visible)
{
button.at(name).draw(uniform.at("mvp"), view, projection, uniform.at("texture enabled"));
}
}
/* Draw spinner labels */
@ -2318,7 +2476,10 @@ void Cakefoot::update(float timestamp)
{
for (std::string name : {"resume", "reset"})
{
button.at(name).draw(uniform["mvp"], view, projection, uniform["texture enabled"]);
if (selected != name || blinking_visible)
{
button.at(name).draw(uniform["mvp"], view, projection, uniform["texture enabled"]);
}
}
/* Draw playtester thanks */

View File

@ -254,7 +254,7 @@ private:
glm::vec4 world_color {0.2f, 0.2f, 0.2f, 1.0f};
std::map<std::string, sb::audio::Chunk> audio;
Character character {_configuration, audio};
bool use_play_button = false, coin_collected = false;
bool use_play_button = false, coin_collected = false, blinking_visible = true;
ArcadeScores arcade_scores;
ArcadeScores::Score arcade_score;
std::string name_entry = "AAA";
@ -262,6 +262,7 @@ private:
std::vector<Flame> ending_coins;
sb::Color rotating_hue {128, 0, 0, 0};
std::vector<sb::Text> ending_messages;
std::optional<std::string> selected;
/*!
* Load sound effects and music into objects that can be used by the SDL mixer library. Use chunk objects for background music instead of
@ -417,7 +418,7 @@ private:
/* This animation can be used to end the game over state after the time limit is reached. Play once with a delay to let the game over screen
* display temporarily before being ended by this animation. */
Animation game_over_animation {sb::Animation(std::bind(&Cakefoot::end_game_over_display, this))};
Animation game_over_animation {std::bind(&Cakefoot::end_game_over_display, this)};
/*!
* Write score, refresh scoreboard, and load the title screen
@ -425,7 +426,7 @@ private:
void submit_score();
/* Can be used to time out the name entry screen */
Animation submit_score_animation {sb::Animation(std::bind(&Cakefoot::submit_score, this))};
Animation submit_score_animation {std::bind(&Cakefoot::submit_score, this)};
/*!
*/
@ -437,11 +438,19 @@ private:
void shift_hue();
/* Shift the hue by the configured amount once per configured amount of seconds */
Animation shift_hue_animation {sb::Animation(std::bind(&Cakefoot::shift_hue, this))};
Animation shift_hue_animation {std::bind(&Cakefoot::shift_hue, this)};
/* Flash the screen */
Animation flash_animation;
/*!
* Toggle visibility of the flag used by the blink animation.
*/
void blink();
/* Toggle visibility flag every interval */
Animation blink_animation {std::bind(&Cakefoot::blink, this), configuration()("display", "blink frequency")};
/*!
* Get the arcade time as the amount of time remaining before the limit is reached.
*