Skip to content

Add game over dialog. #36

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
May 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ include(FetchContent)
FetchContent_Declare(
bave
GIT_REPOSITORY https://github.com/karnkaul/bave
GIT_TAG v0.5.0
GIT_TAG v0.5.1
SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ext/bave"
)

Expand Down
14 changes: 13 additions & 1 deletion assets/styles.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"grey": "#535151ff",
"mocha": "#6f5a48ff",
"milk": "#e5cdaeff",
"ice": "#0xd6dbe1e1",
"ice": "#d6dbe1e1",
"orange": "#f75c03ff",
"gun_beam": "#bc96e6ff"
},
Expand Down Expand Up @@ -43,6 +43,18 @@
"padding": 5
}
},
"dialogs": {
"default": {
"footer_padding": [
20.000000,
10.000000
],
"corner_ratio": 0.25,
"background_tint": "#e5cdaeff",
"outline_tint": "#231d2aff",
"content_text_tint": "#231d2aff"
}
},
"loading_screen": {
"background_tint": "#231d2aff",
"spinner": {
Expand Down
1 change: 0 additions & 1 deletion src/spaced/spaced/game/enemy.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
#include <bave/graphics/shape.hpp>
#include <bave/platform.hpp>
#include <spaced/game/damageable.hpp>
#include <spaced/game/enemy_death.hpp>
#include <spaced/game/health.hpp>
#include <spaced/services/layout.hpp>
#include <spaced/services/services.hpp>
Expand Down
16 changes: 0 additions & 16 deletions src/spaced/spaced/game/enemy_death.hpp

This file was deleted.

5 changes: 3 additions & 2 deletions src/spaced/spaced/game/player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ void Player::tick(State const& state, Seconds const dt) {

for (auto const& target : state.targets) {
if (is_intersecting(target->get_bounds(), ship.get_bounds())) {
on_death();
on_death(dt);
target->force_death();
return;
}
Expand Down Expand Up @@ -92,10 +92,11 @@ void Player::set_controller(std::unique_ptr<IController> controller) {
m_controller = std::move(controller);
}

void Player::on_death() {
void Player::on_death(Seconds const dt) {
health = 0.0f;
m_death = m_death_source;
m_death->set_position(ship.transform.position);
m_death->tick(dt);
}

void Player::do_inspect() {
Expand Down
4 changes: 2 additions & 2 deletions src/spaced/spaced/game/player.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ class Player : public bave::IDrawable {

void set_special_weapon(std::unique_ptr<Weapon> weapon) { m_arsenal.set_special(std::move(weapon)); }

void on_death(bave::Seconds dt);

void inspect() {
if constexpr (bave::debug_v) { do_inspect(); }
}
Expand All @@ -43,8 +45,6 @@ class Player : public bave::IDrawable {
Health health{};

private:
void on_death();

void do_inspect();

bave::Logger m_log{"Player"};
Expand Down
8 changes: 0 additions & 8 deletions src/spaced/spaced/game/world.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,6 @@ World::World(bave::NotNull<Services const*> services, bave::NotNull<IScorer*> sc
m_enemy_factories["CreepFactory"] = std::make_unique<CreepFactory>(services);
}

void World::on_death(EnemyDeath const& death) {
m_scorer->add_score(death.points);

// temp
if (random_in_range(0, 10) < 3) { debug_spawn_powerup(death.position); }
// temp
}

void World::tick(Seconds const dt) {
bool const in_play = !player.health.is_dead();

Expand Down
6 changes: 2 additions & 4 deletions src/spaced/spaced/game/world.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,14 @@
#include <spaced/game/target_provider.hpp>

namespace spaced {
class Resources;
struct Resources;

class World : public ITargetProvider, public IEnemyDeathListener {
class World : public ITargetProvider {
public:
explicit World(bave::NotNull<Services const*> services, bave::NotNull<IScorer*> scorer);

[[nodiscard]] auto get_targets() const -> std::span<bave::NotNull<IDamageable*> const> final { return m_targets; }

void on_death(EnemyDeath const& death) final;

void tick(bave::Seconds dt);
void draw(bave::Shader& shader) const;

Expand Down
19 changes: 19 additions & 0 deletions src/spaced/spaced/scenes/game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
#include <spaced/scenes/home.hpp>
#include <spaced/services/scene_switcher.hpp>
#include <spaced/services/styles.hpp>
#include <spaced/ui/button.hpp>
#include <spaced/ui/dialog.hpp>

namespace spaced {
using bave::Action;
Expand Down Expand Up @@ -59,6 +61,7 @@ void Game::tick(Seconds const dt) {
auto ft = bave::DeltaTime{};

m_world.tick(dt);
if (m_world.player.health.is_dead() && !m_game_over_dialog_pushed) { on_game_over(); }

if constexpr (bave::debug_v) { inspect(dt, ft.update()); }
}
Expand All @@ -70,6 +73,19 @@ void Game::add_score(std::int64_t const score) {
m_hud->set_score(m_score);
}

void Game::on_game_over() {
auto dci = ui::DialogCreateInfo{
.size = {600.0f, 200.0f},
.content_text = "GAME OVER",
.main_button = {.text = "RESTART", .callback = [this] { get_services().get<ISceneSwitcher>().switch_to<Game>(); }},
.second_button = {.text = "QUIT", .callback = [this] { get_app().shutdown(); }},
};

auto dialog = std::make_unique<ui::Dialog>(get_services(), std::move(dci));
m_game_over_dialog_pushed = true;
push_view(std::move(dialog));
}

void Game::inspect(Seconds const dt, Seconds const frame_time) {
if constexpr (bave::imgui_v) {
m_debug.fps.tick(dt);
Expand All @@ -83,6 +99,9 @@ void Game::inspect(Seconds const dt, Seconds const frame_time) {
ImGui::Separator();
im_text("score: {}", get_score());

ImGui::Separator();
if (ImGui::Button("end game")) { m_world.player.on_death({}); }

ImGui::Separator();
im_text("dt: {:05.2f}", std::chrono::duration<float, std::milli>(dt).count());
im_text("fps: {}", m_debug.fps.fps);
Expand Down
2 changes: 2 additions & 0 deletions src/spaced/spaced/scenes/game.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,14 @@ class Game : public Scene, public IScorer {

[[nodiscard]] auto get_score() const -> std::int64_t final { return m_score; }
void add_score(std::int64_t score) final;
void on_game_over();

void inspect(bave::Seconds dt, bave::Seconds frame_time);

World m_world;
std::int64_t m_score{};
bave::Ptr<Hud> m_hud{};
bool m_game_over_dialog_pushed{};

struct {
struct {
Expand Down
3 changes: 2 additions & 1 deletion src/spaced/spaced/scenes/home.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <spaced/services/resources.hpp>
#include <spaced/services/scene_switcher.hpp>
#include <spaced/ui/button.hpp>
#include <spaced/ui/dialog.hpp>
#include <spaced/ui/text.hpp>
#include <spaced/util.hpp>

Expand All @@ -12,7 +13,7 @@ using bave::App;
using bave::Seconds;
using bave::TextHeight;

auto Home::get_text_heights() -> std::vector<TextHeight> { return {TextHeight{100}, TextHeight{60}}; }
auto Home::get_text_heights() -> std::vector<TextHeight> { return {TextHeight{100}, TextHeight{60}, ui::Dialog::text_height_v}; }

Home::Home(App& app, Services const& services) : Scene(app, services, "Home") { create_ui(); }

Expand Down
2 changes: 2 additions & 0 deletions src/spaced/spaced/services/styles.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ auto Styles::load(dj::Json const& json) -> Styles {
load_styles(ret.rgbas, json["rgbas"]);
load_styles(ret.buttons, json["buttons"]);
load_styles(ret.progress_bars, json["progress_bars"]);
load_styles(ret.dialogs, json["dialogs"]);
if (auto const& loading_screen = json["loading_screen"]) { from_json(loading_screen, ret.loading_screen); }
return ret;
}
Expand All @@ -44,6 +45,7 @@ auto Styles::save() const -> dj::Json {
save_styles(rgbas, ret, "rgbas");
save_styles(buttons, ret, "buttons");
save_styles(progress_bars, ret, "progress_bars");
save_styles(dialogs, ret, "dialogs");
to_json(ret["loading_screen"], loading_screen);
return ret;
}
Expand Down
1 change: 1 addition & 0 deletions src/spaced/spaced/services/styles.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ struct Styles : IService {
StringMap<bave::Rgba> rgbas{};
StringMap<ui::ButtonStyle> buttons{};
StringMap<ui::ProgressBarStyle> progress_bars{};
StringMap<ui::DialogStyle> dialogs{};
ui::LoadingScreenStyle loading_screen{};

static auto load(dj::Json const& json) -> Styles;
Expand Down
48 changes: 48 additions & 0 deletions src/spaced/spaced/ui/dialog.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#include <spaced/services/styles.hpp>
#include <spaced/ui/dialog.hpp>

namespace spaced::ui {
Dialog::Dialog(Services const& services, CreateInfo create_info) : View(services), m_style(services.get<Styles>().dialogs["default"]) {
auto main_button = std::make_unique<Button>(services);
auto const footer_height = main_button->get_size().y + m_style.footer_padding.y;
auto const footer_position = glm::vec2{0.0f, -0.5f * (create_info.size.y - footer_height)};

auto background = std::make_unique<OutlineQuad>();
background->set_size({create_info.size.x, create_info.size.y + footer_height});
background->set_tint(m_style.background_tint);
background->set_outline_tint(m_style.outline_tint);
background->set_corner_ratio(0.25f);
push(std::move(background));

auto content_text = std::make_unique<Text>(services);
content_text->text.set_string(std::move(create_info.content_text));
content_text->text.set_height(text_height_v);
content_text->text.tint = m_style.content_text_tint;
push(std::move(content_text));

main_button->set_text(std::move(create_info.main_button.text));
main_button->callback = [this, f = std::move(create_info.main_button.callback)] {
if (f) { f(); }
set_destroyed();
};
if (create_info.second_button.text.empty()) {
main_button->set_position(footer_position);
} else {
auto const x_offset = -0.5f * (create_info.size.x - main_button->get_size().x) + m_style.footer_padding.x;
main_button->set_position({footer_position.x + x_offset, footer_position.y});
}
push(std::move(main_button));

if (!create_info.second_button.text.empty()) {
auto second_button = std::make_unique<Button>(services);
second_button->set_text(std::move(create_info.second_button.text));
second_button->callback = [this, f = std::move(create_info.second_button.callback)] {
if (f) { f(); }
set_destroyed();
};
auto const x_offset = 0.5f * (create_info.size.x - second_button->get_size().x) - m_style.footer_padding.x;
second_button->set_position({footer_position.x + x_offset, footer_position.y});
push(std::move(second_button));
}
}
} // namespace spaced::ui
35 changes: 35 additions & 0 deletions src/spaced/spaced/ui/dialog.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#pragma once
#include <spaced/ui/button.hpp>
#include <spaced/ui/outline_quad.hpp>
#include <spaced/ui/text.hpp>
#include <spaced/ui/view.hpp>

namespace spaced::ui {
struct DialogCreateInfo {
struct ButtonInfo {
std::string text{};
std::function<void()> callback{};
};

glm::vec2 size{500.0f, 200.0f};
std::string content_text{"Content text."};
ButtonInfo main_button{.text = "OK"};
ButtonInfo second_button{};
};

class Dialog : public ui::View {
public:
using CreateInfo = DialogCreateInfo;

static constexpr auto text_height_v = bave::TextHeight{static_cast<int>(bave::TextHeight::eDefault) + 16};

explicit Dialog(Services const& services, CreateInfo create_info = {});

protected:
DialogStyle m_style{};

bave::Ptr<OutlineQuad> m_background{};
bave::Ptr<Text> m_content_text{};
std::array<bave::Ptr<ui::Button>, 2> m_footer_buttons{};
};
} // namespace spaced::ui
8 changes: 8 additions & 0 deletions src/spaced/spaced/ui/style.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,12 @@ struct ProgressBarStyle {
float corner_ratio{0.5f};
float padding{10.0f};
};

struct DialogStyle {
glm::vec2 footer_padding{20.0f, 10.0f};
float corner_ratio{0.25f};
bave::Rgba background_tint{bave::yellow_v};
bave::Rgba outline_tint{bave::cyan_v};
bave::Rgba content_text_tint{bave::black_v};
};
} // namespace spaced::ui
18 changes: 18 additions & 0 deletions src/spaced/spaced/util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,24 @@ void util::from_json(dj::Json const& json, ui::ProgressBarStyle& out) {
out.padding = json["padding"].as<float>(out.padding);
}

void util::to_json(dj::Json& out, ui::DialogStyle const& dialog_style) {
using bave::to_json;
to_json(out["footer_padding"], dialog_style.footer_padding);
to_json(out["corner_ratio"], dialog_style.corner_ratio);
to_json(out["background_tint"], dialog_style.background_tint);
to_json(out["outline_tint"], dialog_style.outline_tint);
to_json(out["content_text_tint"], dialog_style.content_text_tint);
}

void util::from_json(dj::Json const& json, ui::DialogStyle& out) {
using bave::from_json;
from_json(json["footer_padding"], out.footer_padding);
from_json(json["corner_ratio"], out.corner_ratio);
from_json(json["background_tint"], out.background_tint);
from_json(json["outline_tint"], out.outline_tint);
from_json(json["content_text_tint"], out.content_text_tint);
}

auto util::create_font_atlas_task(std::shared_ptr<bave::Font> font, std::vector<bave::TextHeight> heights) -> std::function<void()> {
if (!font || heights.empty()) { return {}; }
return [font = std::move(font), heights = std::move(heights)] {
Expand Down
3 changes: 3 additions & 0 deletions src/spaced/spaced/util.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,8 @@ void from_json(dj::Json const& json, ui::ButtonStyle& out);
void to_json(dj::Json& out, ui::ProgressBarStyle const& progress_bar_style);
void from_json(dj::Json const& json, ui::ProgressBarStyle& out);

void to_json(dj::Json& out, ui::DialogStyle const& dialog_style);
void from_json(dj::Json const& json, ui::DialogStyle& out);

auto create_font_atlas_task(std::shared_ptr<bave::Font> font, std::vector<bave::TextHeight> heights) -> std::function<void()>;
} // namespace spaced::util