Skip to content

Persist and show high score. #42

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 1 commit into from
May 2, 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
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