More boss fight UI done and a bit of ambient sound working.

master
Zed A. Shaw 1 week ago
parent 64807174c0
commit a0c0308461
  1. BIN
      assets/ambient_1.ogg
  2. 3
      assets/config.json
  3. 42
      boss_fight_ui.cpp
  4. 6
      boss_fight_ui.hpp
  5. 40
      guecs.cpp
  6. 12
      guecs.hpp
  7. 6
      gui_fsm.cpp
  8. 4
      main.cpp
  9. 8
      main_ui.cpp
  10. 43
      overlay_ui.cpp
  11. 3
      sound.cpp
  12. 2
      sound.hpp

Binary file not shown.

@ -5,7 +5,8 @@
"monster_1": "assets/monster-1.ogg", "monster_1": "assets/monster-1.ogg",
"walk": "assets/blank.ogg", "walk": "assets/blank.ogg",
"blank": "assets/blank.ogg", "blank": "assets/blank.ogg",
"pickup": "assets/pickup.ogg" "pickup": "assets/pickup.ogg",
"ambient_1": "assets/ambient_1.ogg"
}, },
"sprites": { "sprites": {
"armored_knight": "assets/armored_knight_1-256.png", "armored_knight": "assets/armored_knight_1-256.png",

@ -2,20 +2,22 @@
#include "easings.hpp" #include "easings.hpp"
namespace gui { namespace gui {
BossFightUI::BossFightUI() { BossFightUI::BossFightUI(GameLevel level)
: $level(level)
{
$status.position(0, 0, 300, SCREEN_HEIGHT); $status.position(0, 0, 300, SCREEN_HEIGHT);
$status.layout( $status.layout(
"[(150)status_1|(150)status_2]" "[main_status]"
"[(150)status_3|(150)status_4]" "[(150)status_3|(150)status_4]"
"[(150)status_5|(150)status_6]" "[(150)status_5|(150)status_6]"
"[(150)status_7|(150)status_8]" "[(150)status_7|(150)status_8]"
); );
$overlay.position(300, 0, SCREEN_WIDTH - 300, SCREEN_HEIGHT); $overlay.position(300, 0, SCREEN_WIDTH - 300, SCREEN_HEIGHT);
$overlay.layout("[overlay_1|overlay_2|overlay_3|overlay_4]" $overlay.layout("[overlay_1|overlay_2|overlay_4]"
"[overlay_5|overlay_6|overlay_7|overlay_8]" "[overlay_5|overlay_6|overlay_8]"
"[overlay_9|overlay_10|overlay_11|overlay_12]" "[overlay_9|overlay_10|overlay_12]"
"[overlay_13|overlay_14|overlay_15|overlay_16]"); "[overlay_13|overlay_14|overlay_16]");
$boss_image = textures::get("boss_fight"); $boss_image = textures::get("boss_fight");
auto bounds = $boss_image.sprite->getLocalBounds(); auto bounds = $boss_image.sprite->getLocalBounds();
@ -32,7 +34,11 @@ namespace gui {
$status.set<Clickable>(button, { $status.set<Clickable>(button, {
[this, name](auto, auto){ fmt::println("STATUS: {}", name); } [this, name](auto, auto){ fmt::println("STATUS: {}", name); }
}); });
$status.set<Label>(button, {name}); if(name == "main_status") {
$status.set<Textual>(button, {fmt::format("HP: {}", $boss_hp)});
} else {
$status.set<Label>(button, {"Attack"});
}
} }
$status.init(); $status.init();
@ -43,15 +49,13 @@ namespace gui {
}); });
} }
auto region = $overlay.entity("overlay_2");
$overlay.set<Label>(region, {"THE RAT KING!"});
$overlay.init(); $overlay.init();
} }
void BossFightUI::bounce_boss(sf::RenderWindow& window) { void BossFightUI::bounce_boss(sf::RenderWindow& window) {
auto time = $clock.getElapsedTime(); auto time = $clock.getElapsedTime();
float tick = ease::in_out_back(ease::sine(time.asSeconds())); float tick = ease::out_bounce(ease::sine(time.asSeconds()));
float scale = std::lerp(1.1, 1.3, tick); float scale = std::lerp(1.0, 1.15, tick);
$boss_image.sprite->setScale({scale, scale}); $boss_image.sprite->setScale({scale, scale});
window.draw(*$boss_image.sprite); window.draw(*$boss_image.sprite);
} }
@ -63,6 +67,11 @@ namespace gui {
window.draw(*$boss_image.sprite); window.draw(*$boss_image.sprite);
} }
if($boss_hp == 0) {
$overlay.show_label("overlay_1", "YOU WON!");
$overlay.show_label("overlay_4", "CLICK TO CONTINUE...");
}
$status.render(window); $status.render(window);
$overlay.render(window); $overlay.render(window);
} }
@ -73,10 +82,19 @@ namespace gui {
} }
if($overlay.mouse(x, y)) { if($overlay.mouse(x, y)) {
fmt::println("OVERLAY");
$boss_hit = !$boss_hit; $boss_hit = !$boss_hit;
$boss_hp--;
} }
return false; return false;
} }
void BossFightUI::update_level(GameLevel &level) {
$level = level;
$boss_hp = 10 * $level.index + 1; // make him stronger
$boss_hit = false;
$overlay.close<Label>("overlay_1");
$overlay.close<Label>("overlay_4");
init();
}
} }

@ -19,16 +19,20 @@ namespace gui {
class BossFightUI { class BossFightUI {
public: public:
sf::Clock $clock; sf::Clock $clock;
int $boss_hp = 10;
bool $boss_hit = false; bool $boss_hit = false;
GameLevel $level;
guecs::UI $status; guecs::UI $status;
guecs::UI $overlay; guecs::UI $overlay;
textures::SpriteTexture $boss_image; textures::SpriteTexture $boss_image;
BossFightUI(); BossFightUI(GameLevel level);
void init(); void init();
void render(sf::RenderWindow& window); void render(sf::RenderWindow& window);
bool mouse(float x, float y); bool mouse(float x, float y);
void bounce_boss(sf::RenderWindow& window); void bounce_boss(sf::RenderWindow& window);
bool boss_dead() { return $boss_hp < 0; }
void update_level(GameLevel& level);
}; };
} }

@ -118,10 +118,50 @@ namespace guecs {
return action_count > 0; return action_count > 0;
} }
void UI::show_sprite(string region, string sprite_name) {
auto ent = entity(region);
if(!has<Sprite>(ent)) {
Sprite to_show{sprite_name};
auto& cell = cell_for(ent);
to_show.init(cell);
set<guecs::Sprite>(ent, to_show);
}
}
void UI::show_text(string region, string content) {
auto ent = entity(region);
if(auto text = get_if<Textual>(ent)) {
text->text->setString(content);
} else {
auto &cell = cell_for(ent);
Textual to_set{content, 20};
to_set.init(cell, $font);
to_set.text->setFillColor(ColorValue::LIGHT_MID);
set<Textual>(ent, to_set);
}
}
void UI::show_label(string region, string content) {
auto ent = entity(region);
if(auto text = get_if<Label>(ent)) {
text->text->setString(content);
} else {
auto &cell = cell_for(ent);
Label to_set{content, 20};
to_set.init(cell, $font);
to_set.text->setFillColor(ColorValue::LIGHT_MID);
set<Label>(ent, to_set);
}
}
Clickable make_action(DinkyECS::World& target, Events::GUI event) { Clickable make_action(DinkyECS::World& target, Events::GUI event) {
return {[&, event](auto ent, auto data){ return {[&, event](auto ent, auto data){
// remember that ent is passed in from the UI::mouse handler // remember that ent is passed in from the UI::mouse handler
target.send<Events::GUI>(event, ent, data); target.send<Events::GUI>(event, ent, data);
}}; }};
} }
} }

@ -194,6 +194,18 @@ namespace guecs {
void remove(DinkyECS::Entity ent) { void remove(DinkyECS::Entity ent) {
$world.remove<Comp>(ent); $world.remove<Comp>(ent);
} }
template <typename Comp>
void close(string region) {
auto ent = entity(region);
remove<Comp>(ent);
}
void show_sprite(string region, string sprite_name);
void show_text(string region, string content);
void update_text(string region, string content);
void update_label(string region, string content);
void show_label(string region, string content);
}; };
Clickable make_action(DinkyECS::World& target, Events::GUI event); Clickable make_action(DinkyECS::World& target, Events::GUI event);

@ -20,6 +20,7 @@ namespace gui {
$map_ui($level), $map_ui($level),
$combat_ui($level), $combat_ui($level),
$status_ui($level), $status_ui($level),
$boss_fight_ui($level),
$font{FONT_FILE_NAME} $font{FONT_FILE_NAME}
{ {
} }
@ -246,6 +247,10 @@ namespace gui {
sf::Vector2f pos = $window.mapPixelToCoords(mouse->position); sf::Vector2f pos = $window.mapPixelToCoords(mouse->position);
if(in_state(State::NEXT_LEVEL)) { if(in_state(State::NEXT_LEVEL)) {
$boss_fight_ui.mouse(pos.x, pos.y); $boss_fight_ui.mouse(pos.x, pos.y);
if($boss_fight_ui.boss_dead()) {
event(Event::STAIRS_DOWN);
}
} else { } else {
$combat_ui.$gui.mouse(pos.x, pos.y); $combat_ui.$gui.mouse(pos.x, pos.y);
$status_ui.$gui.mouse(pos.x, pos.y); $status_ui.$gui.mouse(pos.x, pos.y);
@ -415,6 +420,7 @@ namespace gui {
$combat_ui.update_level($level); $combat_ui.update_level($level);
$map_ui.update_level($level); $map_ui.update_level($level);
$main_ui.update_level($level); $main_ui.update_level($level);
$boss_fight_ui.update_level($level);
run_systems(); run_systems();
} }

@ -6,11 +6,13 @@
int main(int argc, char* argv[]) { int main(int argc, char* argv[]) {
textures::init(); textures::init();
sound::init(); sound::init();
sound::mute(true); sound::mute(false);
gui::FSM main; gui::FSM main;
main.event(gui::Event::STARTED); main.event(gui::Event::STARTED);
Autowalker walker(main); Autowalker walker(main);
sound::play("ambient_1", true);
if(argc > 1 && argv[1][0] == 't') { if(argc > 1 && argv[1][0] == 't') {
walker.start_autowalk(); walker.start_autowalk();
} }

@ -55,7 +55,7 @@ namespace gui {
$rayview.$dir_x, $rayview.$dir_y, $rayview.$dir_x, $rayview.$dir_y,
VSYNC, FRAME_LIMIT, DEBUG_BUILD); VSYNC, FRAME_LIMIT, DEBUG_BUILD);
$overlay_ui.update_text("top_left", stats); $overlay_ui.show_text("top_left", stats);
} }
void MainUI::draw_blood() { void MainUI::draw_blood() {
@ -115,7 +115,7 @@ namespace gui {
auto debug = $level.world->get_the<Debug>(); auto debug = $level.world->get_the<Debug>();
if(debug.FPS) draw_stats(); if(debug.FPS) draw_stats();
draw_blood(); // draw_blood();
} }
bool MainUI::play_rotate() { bool MainUI::play_rotate() {
@ -140,7 +140,7 @@ namespace gui {
void MainUI::plan_rotate(int dir) { void MainUI::plan_rotate(int dir) {
// -1 is left, 1 is right // -1 is left, 1 is right
$compass_dir = ($compass_dir + dir) % $compass.size(); $compass_dir = ($compass_dir + dir) % $compass.size();
$overlay_ui.update_label("top", $compass[$compass_dir]); $overlay_ui.show_label("top", $compass[$compass_dir]);
$camera.plan_rotate($rayview, dir); $camera.plan_rotate($rayview, dir);
} }
@ -166,7 +166,7 @@ namespace gui {
$rayview.position_camera(player.x + 0.5, player.y + 0.5); $rayview.position_camera(player.x + 0.5, player.y + 0.5);
$compass_dir = 0; $compass_dir = 0;
$overlay_ui.update_label("top", $compass[$compass_dir]); $overlay_ui.show_label("top", $compass[$compass_dir]);
dirty(); dirty();
} }

@ -28,57 +28,26 @@ namespace gui {
} }
void OverlayUI::show_sprite(string region, string sprite_name) { void OverlayUI::show_sprite(string region, string sprite_name) {
auto ent = $gui.entity(region); $gui.show_sprite(region, sprite_name);
Sprite blood{sprite_name};
auto& cell = $gui.cell_for(ent);
blood.init(cell);
$gui.set<guecs::Sprite>(ent, blood);
} }
void OverlayUI::close_sprite(string region) { void OverlayUI::close_sprite(string region) {
auto ent = $gui.entity(region); $gui.close<Sprite>(region);
$gui.remove<guecs::Sprite>(ent);
} }
void OverlayUI::show_text(string region, string content) { void OverlayUI::show_text(string region, string content) {
auto ent = $gui.entity(region); $gui.show_text(region, content);
auto &cell = $gui.cell_for(ent);
Textual text{content, 20};
text.init(cell, $gui.$font);
text.text->setFillColor(ColorValue::LIGHT_MID);
$gui.set<Textual>(ent, text);
}
void OverlayUI::update_text(string region, string content) {
auto ent = $gui.entity(region);
if(auto text = $gui.get_if<Textual>(ent)) {
text->text->setString(content);
}
}
void OverlayUI::update_label(string region, string content) {
auto ent = $gui.entity(region);
if(auto text = $gui.get_if<Label>(ent)) {
text->text->setString(content);
}
} }
void OverlayUI::close_text(string region) { void OverlayUI::close_text(string region) {
auto ent = $gui.entity(region); $gui.close<Textual>(region);
$gui.remove<Textual>(ent);
} }
void OverlayUI::show_label(string region, string content) { void OverlayUI::show_label(string region, string content) {
auto ent = $gui.entity(region); $gui.show_label(region, content);
auto &cell = $gui.cell_for(ent);
Label text{content, 20};
text.init(cell, $gui.$font);
text.text->setFillColor(ColorValue::LIGHT_MID);
$gui.set<Label>(ent, text);
} }
void OverlayUI::close_label(string region) { void OverlayUI::close_label(string region) {
auto ent = $gui.entity(region); $gui.close<Label>(region);
$gui.remove<Label>(ent);
} }
} }

@ -37,13 +37,14 @@ namespace sound {
SMGR.sounds.try_emplace(name, buffer, sound); SMGR.sounds.try_emplace(name, buffer, sound);
} }
void play(const std::string name) { void play(const std::string name, bool loop) {
dbc::check(initialized, "You need to call sound::init() first"); dbc::check(initialized, "You need to call sound::init() first");
if(muted) return; if(muted) return;
if(SMGR.sounds.contains(name)) { if(SMGR.sounds.contains(name)) {
// get the sound from the sound map // get the sound from the sound map
auto pair = SMGR.sounds.at(name); auto pair = SMGR.sounds.at(name);
pair.sound->setLooping(loop);
// play it // play it
pair.sound->play(); pair.sound->play();
} else { } else {

@ -17,7 +17,7 @@ namespace sound {
void init(); void init();
void load(const std::string name, const std::string path); void load(const std::string name, const std::string path);
void play(const std::string name); void play(const std::string name, bool loop=false);
void play_at(const std::string name, float x, float y, float z); void play_at(const std::string name, float x, float y, float z);
void mute(bool setting); void mute(bool setting);
} }

Loading…
Cancel
Save