Skip to content

Commit

Permalink
Persist and show high score. (#42)
Browse files Browse the repository at this point in the history
  • Loading branch information
karnkaul authored May 2, 2024
1 parent 3145c3f commit e37ebf2
Show file tree
Hide file tree
Showing 8 changed files with 109 additions and 9 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@ compile_commands.json

imgui.ini
bave*.log
/spaced
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.1
GIT_TAG v0.5.2
SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ext/bave"
)

Expand Down
33 changes: 33 additions & 0 deletions src/spaced/spaced/game/game_save.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#include <bave/persistor.hpp>
#include <spaced/game/game_save.hpp>
#include <array>
#include <cstddef>
#include <cstring>
#include <span>

namespace spaced {
using bave::App;
using bave::NotNull;
using bave::Persistor;

namespace {
constexpr std::string_view uri_v{"spaced/game_save.bin"};
} // namespace

GameSave::GameSave(NotNull<App const*> app) : m_app(app) {
auto const persistor = Persistor{*m_app};
if (persistor.exists(uri_v)) {
auto const blob_bytes = persistor.read_bytes(uri_v);
std::memcpy(&m_blob, blob_bytes.data(), blob_bytes.size());
}
}

GameSave::~GameSave() { save(); }

auto GameSave::save() -> bool {
auto const persistor = Persistor{*m_app};
auto blob_bytes = std::array<std::byte, sizeof(Blob)>{};
std::memcpy(blob_bytes.data(), &m_blob, sizeof(Blob));
return persistor.write_bytes(uri_v, blob_bytes);
}
} // namespace spaced
37 changes: 37 additions & 0 deletions src/spaced/spaced/game/game_save.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#pragma once
#include <bave/core/not_null.hpp>
#include <cstdint>

namespace bave {
class App;
}

namespace spaced {
class GameSave {
public:
GameSave(GameSave const&) = delete;
GameSave(GameSave&&) = delete;
auto operator=(GameSave const&) = delete;
auto operator=(GameSave&&) = delete;

explicit GameSave(bave::NotNull<bave::App const*> app);
~GameSave();

[[nodiscard]] auto get_hi_score() const -> std::int64_t { return m_blob.hi_score; }
void set_hi_score(std::int64_t const hi_score) { m_blob.hi_score = hi_score; }

auto save() -> bool;

private:
struct Blob {
// struct must remain backwards compatible:
// fields must NEVER be removed / reordered!
// new fields can be added at the bottom.

std::int64_t hi_score{};
};

bave::NotNull<bave::App const*> m_app;
Blob m_blob{};
};
} // namespace spaced
29 changes: 22 additions & 7 deletions src/spaced/spaced/game/hud.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ Hud::Hud(Services const& services) : ui::View(services), m_styles(&services.get<

void Hud::set_score(std::int64_t const score) { m_score->text.set_string(fmt::format("{}", score)); }

void Hud::set_hi_score(std::int64_t const score) { m_hi_score->text.set_string(fmt::format("HI {}", score)); }

void Hud::create_background() {
auto background = std::make_unique<ui::OutlineQuad>();
m_background = background.get();
Expand All @@ -27,16 +29,29 @@ void Hud::create_background() {
void Hud::create_score(Services const& services) {
auto const& rgbas = m_styles->rgbas;

auto text = std::make_unique<ui::Text>(services);
auto make_text = [&] {
auto text = std::make_unique<ui::Text>(services);
text->text.set_height(TextHeight{60});
text->text.transform.position = m_area.centre();
text->text.tint = rgbas["grey"];
return text;
};

auto text = make_text();
m_score = text.get();
text->text.set_height(TextHeight{60});
text->text.set_string("9999999999");
auto const text_bounds = text->text.get_bounds();
auto const text_bounds_size = text_bounds.size();
text->text.transform.position = m_area.centre();
auto const text_bounds_size = text->text.get_bounds().size();
text->text.transform.position.y -= 0.5f * text_bounds_size.y;
set_score(0);

push(std::move(text));

text = make_text();
m_hi_score = text.get();
text->text.transform.position.x = m_area.rb.x - 50.0f;
text->text.transform.position.y -= 0.5f * text_bounds_size.y;
text->text.set_string("0");
text->text.tint = rgbas["grey"];
text->text.set_align(bave::Text::Align::eLeft);
set_hi_score(0);

push(std::move(text));
}
Expand Down
2 changes: 2 additions & 0 deletions src/spaced/spaced/game/hud.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ class Hud : public ui::View {
explicit Hud(Services const& services);

void set_score(std::int64_t score);
void set_hi_score(std::int64_t score);

private:
void create_background();
Expand All @@ -20,5 +21,6 @@ class Hud : public ui::View {

bave::Ptr<ui::OutlineQuad> m_background{};
bave::Ptr<ui::Text> m_score{};
bave::Ptr<ui::Text> m_hi_score{};
};
} // namespace spaced
10 changes: 9 additions & 1 deletion src/spaced/spaced/scenes/game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,12 @@ auto Game::get_manifest() -> AssetManifest {
};
}

Game::Game(App& app, Services const& services) : Scene(app, services, "Game"), m_world(&services, this) {
Game::Game(App& app, Services const& services) : Scene(app, services, "Game"), m_save(&app), m_world(&services, this) {
clear_colour = services.get<Styles>().rgbas["mocha"];

auto hud = std::make_unique<Hud>(services);
m_hud = hud.get();
m_hud->set_hi_score(m_save.get_hi_score());
push_view(std::move(hud));
}

Expand Down Expand Up @@ -71,6 +72,7 @@ void Game::render(Shader& shader) const { m_world.draw(shader); }
void Game::add_score(std::int64_t const score) {
m_score += score;
m_hud->set_score(m_score);
update_hi_score();
}

void Game::on_game_over() {
Expand All @@ -86,6 +88,12 @@ void Game::on_game_over() {
push_view(std::move(dialog));
}

void Game::update_hi_score() {
if (m_score <= m_save.get_hi_score()) { return; }
m_save.set_hi_score(m_score);
m_hud->set_hi_score(m_save.get_hi_score());
}

void Game::inspect(Seconds const dt, Seconds const frame_time) {
if constexpr (bave::imgui_v) {
m_debug.fps.tick(dt);
Expand Down
4 changes: 4 additions & 0 deletions src/spaced/spaced/scenes/game.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#pragma once
#include <spaced/assets/asset_manifest.hpp>
#include <spaced/game/game_save.hpp>
#include <spaced/game/hud.hpp>
#include <spaced/game/scorer.hpp>
#include <spaced/game/target_provider.hpp>
Expand All @@ -26,8 +27,11 @@ class Game : public Scene, public IScorer {
void add_score(std::int64_t score) final;
void on_game_over();

void update_hi_score();

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

GameSave m_save;
World m_world;
std::int64_t m_score{};
bave::Ptr<Hud> m_hud{};
Expand Down

0 comments on commit e37ebf2

Please sign in to comment.