-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathgame.cpp
More file actions
108 lines (90 loc) · 3.27 KB
/
game.cpp
File metadata and controls
108 lines (90 loc) · 3.27 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
#include "chomper/runtimes/game.hpp"
#include "chomper/im_util.hpp"
#include "chomper/runtimes/entrypoint.hpp"
#include "chomper/world_space.hpp"
#include <le2d/random.hpp>
#include <algorithm>
namespace chomper::runtime {
namespace {
constexpr auto countdownParams_v = le::drawable::Text::Params{
.height = le::TextHeight{60},
};
} // namespace
using ActionValue = le::input::action::Value;
Game::Game(gsl::not_null<Engine*> engine) : m_engine(engine), m_mapping(&engine->getInputRouter()) {
createPlayer();
m_world = std::make_unique<World>(m_engine);
createCollectibles();
m_collectibles->spawn(*m_player);
m_countdownText.set_string(engine->getResources().getMainFont(), "3", countdownParams_v);
}
void Game::tick(kvf::Seconds const dt) {
ImGui::SetNextWindowSize({300.0f, 300.0f}, ImGuiCond_Once);
if (ImGui::Begin("Debug Inspect")) {
debugInspectWindow();
}
ImGui::End();
if (m_countdown.count() > 0) {
m_countdown -= dt;
m_countdownText.set_string(m_engine->getResources().getMainFont(), std::format("{}", static_cast<int>(m_countdown.count() + 1)), countdownParams_v);
return;
}
m_player->tick(dt);
collideCollectibles();
// On death
if (!m_player->getInfo().alive) {
m_engine->setNextRuntime<runtime::Entrypoint>();
}
}
void Game::render(le::IRenderer& renderer) const {
m_world->draw(renderer);
m_collectibles->draw(renderer);
m_player->draw(renderer);
if (m_countdown.count() > 0) {
m_countdownText.draw(renderer);
}
}
void Game::debugInspectWindow() {
auto const inspectItems = std::array{
InspectItem{.inspector = m_player.get(), .label = "Player"},
InspectItem{.inspector = &m_engine->getResources(), .label = "Resources"},
InspectItem{.inspector = m_engine, .label = "Engine"},
};
im_util::inspectAsTabs(inspectItems);
}
void Game::bindActions() {
// goBackKey is separated from PlayerController so that it works regardless of the type of controller in use.
// this implies that all actions must share the same mapping to be active simultaneously.
m_mapping.bind_action(&m_actions.goBackKey, [this](ActionValue const v) {
if (v.get<bool>()) {
onGoBack();
}
});
}
void Game::createPlayer() {
// clear bindings that may point to dangling actions after existing player gets destroyed.
m_mapping.clear_bindings();
// rebind game actions.
bindActions();
// create the player, passing a reference of the logger and a reference of the input mapping to create its PlayerController.
m_player = std::make_unique<Player>(m_mapping, m_engine);
}
void Game::createCollectibles() {
m_collectibleTexture = m_engine->getResources().load<le::ITexture>("images/apple.png");
m_collectibles = std::make_unique<Collectibles>(*m_collectibleTexture);
}
void Game::collideCollectibles() {
auto it = std::ranges::find_if(m_collectibles->getInstances(), [&](auto const& collectible) {
return worldSpace::worldToGrid(collectible.transform.position) == worldSpace::worldToGrid(m_player->getSegments().back().transform.position);
});
if (it == m_collectibles->getInstances().end()) {
return;
}
m_player->grow();
m_collectibles->eraseInstance(static_cast<std::size_t>(std::distance(m_collectibles->getInstances().begin(), it)));
m_collectibles->spawn(*m_player);
}
void Game::onGoBack() {
m_log.debug("execute 'go back' action here");
}
} // namespace chomper::runtime