From ee94aeef69bce3213c61bd4daf02de9e0320a6da Mon Sep 17 00:00:00 2001 From: Alex Frasca Date: Mon, 19 Feb 2024 19:29:03 +0100 Subject: [PATCH 1/4] add player controller. add debug window for testing. --- DogTales/dog/dogtales.cpp | 17 +++++++++++++++++ DogTales/dog/player.cpp | 12 +++++++----- DogTales/dog/player.hpp | 4 ++++ DogTales/dog/player/PlayerController.cpp | 13 +++++++++++++ DogTales/dog/player/PlayerController.hpp | 16 ++++++++++++++++ 5 files changed, 57 insertions(+), 5 deletions(-) create mode 100644 DogTales/dog/player/PlayerController.cpp create mode 100644 DogTales/dog/player/PlayerController.hpp diff --git a/DogTales/dog/dogtales.cpp b/DogTales/dog/dogtales.cpp index 1e86c9a..f563401 100644 --- a/DogTales/dog/dogtales.cpp +++ b/DogTales/dog/dogtales.cpp @@ -1,4 +1,5 @@ #include +#include namespace dog { DogTales::DogTales(bave::App& app) : bave::Driver(app), m_player(app, world_space_v) {} @@ -6,6 +7,22 @@ DogTales::DogTales(bave::App& app) : bave::Driver(app), m_player(app, world_spac void DogTales::tick() { auto const dt = get_app().get_dt(); + //ImGui calls + if constexpr (bave::imgui_v) { + if (ImGui::Begin("Debug")) { + if(ImGui::BeginTabBar("Main")) { + if (ImGui::BeginTabItem("Player")) { + bave::im_text("Controller States"); + ImGui::Separator(); + ImGui::Text("Test (Press 'T'): %.2f", m_player.get_controller_state("test")); + ImGui::EndTabItem(); + } + ImGui::EndTabBar(); + } + } + ImGui::End(); + } + // Update player m_player.tick(dt); } diff --git a/DogTales/dog/player.cpp b/DogTales/dog/player.cpp index e8387ca..63d1893 100644 --- a/DogTales/dog/player.cpp +++ b/DogTales/dog/player.cpp @@ -8,13 +8,9 @@ Player::Player(bave::App& app, glm::vec2 const world_space) : m_app(app), m_worl void Player::tick(bave::Seconds const dt) { m_physics.tick(dt); + m_player_controller.tick(dt, m_app); - auto const& key_state = m_app.get_key_state(); auto direction = glm::vec2{}; - if (key_state.is_pressed(bave::Key::eW) || key_state.is_pressed(bave::Key::eUp)) { direction.y += 1.0f; } - if (key_state.is_pressed(bave::Key::eS) || key_state.is_pressed(bave::Key::eDown)) { direction.y -= 1.0f; } - if (key_state.is_pressed(bave::Key::eA) || key_state.is_pressed(bave::Key::eLeft)) { direction.x -= 1.0f; } - if (key_state.is_pressed(bave::Key::eD) || key_state.is_pressed(bave::Key::eRight)) { direction.x += 1.0f; } if (direction.x != 0.0f || direction.y != 0.0f) { direction = glm::normalize(direction); @@ -27,6 +23,12 @@ void Player::tick(bave::Seconds const dt) { void Player::draw(bave::Shader& shader) const { m_sprite.draw(shader); } +float const Player::get_controller_state(std::string key) { + try { + return m_player_controller.key_map[key]; + } catch (std::out_of_range const& oor) { return -1.f; } +} + void Player::handle_wall_collision() { auto& position = m_physics.position; // bounce_rect represents the play area for the sprite, ie the limits for its centre. diff --git a/DogTales/dog/player.hpp b/DogTales/dog/player.hpp index 07e51a2..8066866 100644 --- a/DogTales/dog/player.hpp +++ b/DogTales/dog/player.hpp @@ -2,6 +2,7 @@ #include #include #include "components/physics.hpp" +#include "player/PlayerController.hpp" namespace dog { class Player { @@ -15,6 +16,7 @@ class Player { bave::Sprite m_sprite{}; component::Physics m_physics{}; + player::PlayerController m_player_controller{}; void handle_wall_collision(); @@ -23,5 +25,7 @@ class Player { void tick(bave::Seconds dt); void draw(bave::Shader& shader) const; + + float const get_controller_state(std::string key); }; } // namespace dog diff --git a/DogTales/dog/player/PlayerController.cpp b/DogTales/dog/player/PlayerController.cpp new file mode 100644 index 0000000..564d5e3 --- /dev/null +++ b/DogTales/dog/player/PlayerController.cpp @@ -0,0 +1,13 @@ +#include "PlayerController.hpp" +#include + +namespace dog::player { + +PlayerController::PlayerController() { key_map.insert(std::make_pair("test", 0.f)); } + +void PlayerController::tick(bave::Seconds dt, const bave::App& app) { + auto const& key_state = app.get_key_state(); + key_map["test"] = key_state.is_pressed(bave::Key::eT) ? 1.f : 0.f; +} + +} // namespace dog::player diff --git a/DogTales/dog/player/PlayerController.hpp b/DogTales/dog/player/PlayerController.hpp new file mode 100644 index 0000000..84642b3 --- /dev/null +++ b/DogTales/dog/player/PlayerController.hpp @@ -0,0 +1,16 @@ +#pragma once +#include + +namespace dog::player { +class PlayerController { + + public: + + PlayerController(); + + void tick(bave::Seconds dt, const bave::App& app); + + std::unordered_map key_map{}; + +}; +} // namespace dog::player From ba0eb548939d4be42ae862d4444a93fe71ade51b Mon Sep 17 00:00:00 2001 From: Alex Frasca Date: Tue, 20 Feb 2024 14:37:00 +0100 Subject: [PATCH 2/4] make key_map access const. fix type errors. remove test key_map and add actual keymaps, and update debug menu accordingly. --- DogTales/dog/dogtales.cpp | 14 ++++++--- DogTales/dog/player.cpp | 11 +++---- DogTales/dog/player.hpp | 6 ++-- DogTales/dog/player/PlayerController.cpp | 40 ++++++++++++++++++++---- DogTales/dog/player/PlayerController.hpp | 14 +++++---- 5 files changed, 61 insertions(+), 24 deletions(-) diff --git a/DogTales/dog/dogtales.cpp b/DogTales/dog/dogtales.cpp index f563401..85d714d 100644 --- a/DogTales/dog/dogtales.cpp +++ b/DogTales/dog/dogtales.cpp @@ -1,5 +1,5 @@ -#include #include +#include namespace dog { DogTales::DogTales(bave::App& app) : bave::Driver(app), m_player(app, world_space_v) {} @@ -7,14 +7,20 @@ DogTales::DogTales(bave::App& app) : bave::Driver(app), m_player(app, world_spac void DogTales::tick() { auto const dt = get_app().get_dt(); - //ImGui calls + // ImGui calls if constexpr (bave::imgui_v) { if (ImGui::Begin("Debug")) { - if(ImGui::BeginTabBar("Main")) { + if (ImGui::BeginTabBar("Main")) { + if (ImGui::BeginTabItem("General")) { + ImGui::Checkbox("Physics", &m_player.physics_enabled); + ImGui::EndTabItem(); + } if (ImGui::BeginTabItem("Player")) { bave::im_text("Controller States"); ImGui::Separator(); - ImGui::Text("Test (Press 'T'): %.2f", m_player.get_controller_state("test")); + bave::im_text("move_x (Press A/D or Left/Right): {:.2f}", m_player.get_controller_state("move_x").value()); + bave::im_text("move_y (Press W/S or Up/Down): {:.2f}", m_player.get_controller_state("move_y").value()); + bave::im_text("Jump (Press 'E'): {:.2f}", m_player.get_controller_state("jump").value()); ImGui::EndTabItem(); } ImGui::EndTabBar(); diff --git a/DogTales/dog/player.cpp b/DogTales/dog/player.cpp index 63d1893..e386531 100644 --- a/DogTales/dog/player.cpp +++ b/DogTales/dog/player.cpp @@ -7,11 +7,14 @@ Player::Player(bave::App& app, glm::vec2 const world_space) : m_app(app), m_worl void Player::tick(bave::Seconds const dt) { - m_physics.tick(dt); + if (physics_enabled) { m_physics.tick(dt); } m_player_controller.tick(dt, m_app); auto direction = glm::vec2{}; + direction.x += m_player_controller.get_controller_state("move_x").value(); + direction.y += m_player_controller.get_controller_state("move_y").value(); + if (direction.x != 0.0f || direction.y != 0.0f) { direction = glm::normalize(direction); auto const displacement = direction * speed_v * dt.count(); @@ -23,11 +26,7 @@ void Player::tick(bave::Seconds const dt) { void Player::draw(bave::Shader& shader) const { m_sprite.draw(shader); } -float const Player::get_controller_state(std::string key) { - try { - return m_player_controller.key_map[key]; - } catch (std::out_of_range const& oor) { return -1.f; } -} +std::optional Player::get_controller_state(std::string_view key) const { return m_player_controller.get_controller_state(key); } void Player::handle_wall_collision() { auto& position = m_physics.position; diff --git a/DogTales/dog/player.hpp b/DogTales/dog/player.hpp index 8066866..9c166b2 100644 --- a/DogTales/dog/player.hpp +++ b/DogTales/dog/player.hpp @@ -16,7 +16,7 @@ class Player { bave::Sprite m_sprite{}; component::Physics m_physics{}; - player::PlayerController m_player_controller{}; + PlayerController m_player_controller{}; void handle_wall_collision(); @@ -26,6 +26,8 @@ class Player { void tick(bave::Seconds dt); void draw(bave::Shader& shader) const; - float const get_controller_state(std::string key); + std::optional get_controller_state(std::string_view key) const; + + bool physics_enabled{}; // for debugging }; } // namespace dog diff --git a/DogTales/dog/player/PlayerController.cpp b/DogTales/dog/player/PlayerController.cpp index 564d5e3..ac315c0 100644 --- a/DogTales/dog/player/PlayerController.cpp +++ b/DogTales/dog/player/PlayerController.cpp @@ -1,13 +1,41 @@ #include "PlayerController.hpp" -#include -namespace dog::player { +namespace dog { -PlayerController::PlayerController() { key_map.insert(std::make_pair("test", 0.f)); } +PlayerController::PlayerController() { + key_map.insert(std::make_pair("move_x", 0.f)); + key_map.insert(std::make_pair("move_y", 0.f)); + key_map.insert(std::make_pair("jump", 0.f)); +} + +void PlayerController::tick(bave::Seconds dt, bave::App const& app) { -void PlayerController::tick(bave::Seconds dt, const bave::App& app) { auto const& key_state = app.get_key_state(); - key_map["test"] = key_state.is_pressed(bave::Key::eT) ? 1.f : 0.f; + + bool left = key_state.is_pressed(bave::Key::eA) || key_state.is_pressed(bave::Key::eLeft); + bool right = key_state.is_pressed(bave::Key::eD) || key_state.is_pressed(bave::Key::eRight); + bool up = key_state.is_pressed(bave::Key::eW) || key_state.is_pressed(bave::Key::eUp); + bool down = key_state.is_pressed(bave::Key::eS) || key_state.is_pressed(bave::Key::eDown); + + key_map["move_x"] = 0.f; + key_map["move_x"] = left && !right ? -1.f : key_map["move_x"]; + key_map["move_x"] = right && !left ? 1.f : key_map["move_x"]; + key_map["move_x"] = right && left ? 0.f : key_map["move_x"]; + + key_map["move_y"] = 0.f; + key_map["move_y"] = down && !up ? -1.f : key_map["move_y"]; + key_map["move_y"] = up && !down ? 1.f : key_map["move_y"]; + key_map["move_y"] = up && down ? 0.f : key_map["move_y"]; + + key_map["jump"] = key_state.is_pressed(bave::Key::eW) || key_state.is_pressed(bave::Key::eUp) ? 1.f : 0.f; +} + +std::optional PlayerController::get_controller_state(std::string_view key) const { + if (auto search = key_map.find(key); search != key_map.end()) { + return search->second; + } else { + return -1.f; + } } -} // namespace dog::player +} // namespace dog diff --git a/DogTales/dog/player/PlayerController.hpp b/DogTales/dog/player/PlayerController.hpp index 84642b3..e3a9d99 100644 --- a/DogTales/dog/player/PlayerController.hpp +++ b/DogTales/dog/player/PlayerController.hpp @@ -1,16 +1,18 @@ #pragma once #include +#include +#include -namespace dog::player { +namespace dog { class PlayerController { public: - PlayerController(); - void tick(bave::Seconds dt, const bave::App& app); - - std::unordered_map key_map{}; + void tick(bave::Seconds dt, bave::App const& app); + std::optional get_controller_state(std::string_view key) const; + private: + std::unordered_map> key_map{}; }; -} // namespace dog::player +} // namespace dog From 69c1e01df5a4e74a918977a2670ebed5952e8473 Mon Sep 17 00:00:00 2001 From: Alex Frasca Date: Tue, 20 Feb 2024 14:38:16 +0100 Subject: [PATCH 3/4] fix formatting --- DogTales/dog/dogtales.cpp | 6 ++++-- DogTales/dog/player.cpp | 4 +++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/DogTales/dog/dogtales.cpp b/DogTales/dog/dogtales.cpp index 85d714d..999e06b 100644 --- a/DogTales/dog/dogtales.cpp +++ b/DogTales/dog/dogtales.cpp @@ -18,8 +18,10 @@ void DogTales::tick() { if (ImGui::BeginTabItem("Player")) { bave::im_text("Controller States"); ImGui::Separator(); - bave::im_text("move_x (Press A/D or Left/Right): {:.2f}", m_player.get_controller_state("move_x").value()); - bave::im_text("move_y (Press W/S or Up/Down): {:.2f}", m_player.get_controller_state("move_y").value()); + bave::im_text("move_x (Press A/D or Left/Right): {:.2f}", + m_player.get_controller_state("move_x").value()); + bave::im_text("move_y (Press W/S or Up/Down): {:.2f}", + m_player.get_controller_state("move_y").value()); bave::im_text("Jump (Press 'E'): {:.2f}", m_player.get_controller_state("jump").value()); ImGui::EndTabItem(); } diff --git a/DogTales/dog/player.cpp b/DogTales/dog/player.cpp index e386531..8308277 100644 --- a/DogTales/dog/player.cpp +++ b/DogTales/dog/player.cpp @@ -26,7 +26,9 @@ void Player::tick(bave::Seconds const dt) { void Player::draw(bave::Shader& shader) const { m_sprite.draw(shader); } -std::optional Player::get_controller_state(std::string_view key) const { return m_player_controller.get_controller_state(key); } +std::optional Player::get_controller_state(std::string_view key) const { + return m_player_controller.get_controller_state(key); +} void Player::handle_wall_collision() { auto& position = m_physics.position; From b08e372463d12413230f8b14c4d773f58d53efb7 Mon Sep 17 00:00:00 2001 From: Karn Kaul Date: Sun, 25 Feb 2024 02:07:32 -0800 Subject: [PATCH 4/4] Refactor `PlayerController`. (#35) --- DogTales/dog/dogtales.cpp | 8 ++-- DogTales/dog/dogtales.hpp | 2 +- DogTales/dog/player/PlayerController.cpp | 41 --------------------- DogTales/dog/player/PlayerController.hpp | 18 --------- DogTales/dog/{ => player}/player.cpp | 17 +++++---- DogTales/dog/{ => player}/player.hpp | 8 ++-- DogTales/dog/player/player_controller.cpp | 45 +++++++++++++++++++++++ DogTales/dog/player/player_controller.hpp | 30 +++++++++++++++ 8 files changed, 93 insertions(+), 76 deletions(-) delete mode 100644 DogTales/dog/player/PlayerController.cpp delete mode 100644 DogTales/dog/player/PlayerController.hpp rename DogTales/dog/{ => player}/player.cpp (70%) rename DogTales/dog/{ => player}/player.hpp (76%) create mode 100644 DogTales/dog/player/player_controller.cpp create mode 100644 DogTales/dog/player/player_controller.hpp diff --git a/DogTales/dog/dogtales.cpp b/DogTales/dog/dogtales.cpp index 999e06b..7868748 100644 --- a/DogTales/dog/dogtales.cpp +++ b/DogTales/dog/dogtales.cpp @@ -18,11 +18,9 @@ void DogTales::tick() { if (ImGui::BeginTabItem("Player")) { bave::im_text("Controller States"); ImGui::Separator(); - bave::im_text("move_x (Press A/D or Left/Right): {:.2f}", - m_player.get_controller_state("move_x").value()); - bave::im_text("move_y (Press W/S or Up/Down): {:.2f}", - m_player.get_controller_state("move_y").value()); - bave::im_text("Jump (Press 'E'): {:.2f}", m_player.get_controller_state("jump").value()); + bave::im_text("move_x (Press A/D or Left/Right): {:.2f}", m_player.get_controller_state("move_x")); + bave::im_text("move_y (Press W/S or Up/Down): {:.2f}", m_player.get_controller_state("move_y")); + bave::im_text("Jump (Press Space): {:.2f}", m_player.get_controller_state("jump")); ImGui::EndTabItem(); } ImGui::EndTabBar(); diff --git a/DogTales/dog/dogtales.hpp b/DogTales/dog/dogtales.hpp index d627f1f..f7aa509 100644 --- a/DogTales/dog/dogtales.hpp +++ b/DogTales/dog/dogtales.hpp @@ -1,6 +1,6 @@ #pragma once #include -#include +#include namespace dog { class DogTales : public bave::Driver { diff --git a/DogTales/dog/player/PlayerController.cpp b/DogTales/dog/player/PlayerController.cpp deleted file mode 100644 index ac315c0..0000000 --- a/DogTales/dog/player/PlayerController.cpp +++ /dev/null @@ -1,41 +0,0 @@ -#include "PlayerController.hpp" - -namespace dog { - -PlayerController::PlayerController() { - key_map.insert(std::make_pair("move_x", 0.f)); - key_map.insert(std::make_pair("move_y", 0.f)); - key_map.insert(std::make_pair("jump", 0.f)); -} - -void PlayerController::tick(bave::Seconds dt, bave::App const& app) { - - auto const& key_state = app.get_key_state(); - - bool left = key_state.is_pressed(bave::Key::eA) || key_state.is_pressed(bave::Key::eLeft); - bool right = key_state.is_pressed(bave::Key::eD) || key_state.is_pressed(bave::Key::eRight); - bool up = key_state.is_pressed(bave::Key::eW) || key_state.is_pressed(bave::Key::eUp); - bool down = key_state.is_pressed(bave::Key::eS) || key_state.is_pressed(bave::Key::eDown); - - key_map["move_x"] = 0.f; - key_map["move_x"] = left && !right ? -1.f : key_map["move_x"]; - key_map["move_x"] = right && !left ? 1.f : key_map["move_x"]; - key_map["move_x"] = right && left ? 0.f : key_map["move_x"]; - - key_map["move_y"] = 0.f; - key_map["move_y"] = down && !up ? -1.f : key_map["move_y"]; - key_map["move_y"] = up && !down ? 1.f : key_map["move_y"]; - key_map["move_y"] = up && down ? 0.f : key_map["move_y"]; - - key_map["jump"] = key_state.is_pressed(bave::Key::eW) || key_state.is_pressed(bave::Key::eUp) ? 1.f : 0.f; -} - -std::optional PlayerController::get_controller_state(std::string_view key) const { - if (auto search = key_map.find(key); search != key_map.end()) { - return search->second; - } else { - return -1.f; - } -} - -} // namespace dog diff --git a/DogTales/dog/player/PlayerController.hpp b/DogTales/dog/player/PlayerController.hpp deleted file mode 100644 index e3a9d99..0000000 --- a/DogTales/dog/player/PlayerController.hpp +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once -#include -#include -#include - -namespace dog { -class PlayerController { - - public: - PlayerController(); - - void tick(bave::Seconds dt, bave::App const& app); - std::optional get_controller_state(std::string_view key) const; - - private: - std::unordered_map> key_map{}; -}; -} // namespace dog diff --git a/DogTales/dog/player.cpp b/DogTales/dog/player/player.cpp similarity index 70% rename from DogTales/dog/player.cpp rename to DogTales/dog/player/player.cpp index 8308277..a75a18d 100644 --- a/DogTales/dog/player.cpp +++ b/DogTales/dog/player/player.cpp @@ -1,19 +1,24 @@ -#include +#include namespace dog { Player::Player(bave::App& app, glm::vec2 const world_space) : m_app(app), m_world_space(world_space) { m_sprite.set_size(size_v); + + m_player_controller.bind_throttle("move_x", {.lo = bave::Key::eLeft, .hi = bave::Key::eRight}); + m_player_controller.bind_throttle("move_x", {.lo = bave::Key::eA, .hi = bave::Key::eD}); + m_player_controller.bind_throttle("move_y", {.lo = bave::Key::eDown, .hi = bave::Key::eUp}); + m_player_controller.bind_throttle("move_y", {.lo = bave::Key::eS, .hi = bave::Key::eW}); + m_player_controller.bind_key("jump", bave::Key::eSpace); } void Player::tick(bave::Seconds const dt) { if (physics_enabled) { m_physics.tick(dt); } - m_player_controller.tick(dt, m_app); auto direction = glm::vec2{}; - direction.x += m_player_controller.get_controller_state("move_x").value(); - direction.y += m_player_controller.get_controller_state("move_y").value(); + direction.x += m_player_controller.get_state("move_x"); + direction.y += m_player_controller.get_state("move_y"); if (direction.x != 0.0f || direction.y != 0.0f) { direction = glm::normalize(direction); @@ -26,9 +31,7 @@ void Player::tick(bave::Seconds const dt) { void Player::draw(bave::Shader& shader) const { m_sprite.draw(shader); } -std::optional Player::get_controller_state(std::string_view key) const { - return m_player_controller.get_controller_state(key); -} +float Player::get_controller_state(std::string_view key) const { return m_player_controller.get_state(key); } void Player::handle_wall_collision() { auto& position = m_physics.position; diff --git a/DogTales/dog/player.hpp b/DogTales/dog/player/player.hpp similarity index 76% rename from DogTales/dog/player.hpp rename to DogTales/dog/player/player.hpp index 9c166b2..344cc34 100644 --- a/DogTales/dog/player.hpp +++ b/DogTales/dog/player/player.hpp @@ -1,8 +1,8 @@ #pragma once #include #include -#include "components/physics.hpp" -#include "player/PlayerController.hpp" +#include +#include namespace dog { class Player { @@ -16,7 +16,7 @@ class Player { bave::Sprite m_sprite{}; component::Physics m_physics{}; - PlayerController m_player_controller{}; + PlayerController m_player_controller{&m_app}; void handle_wall_collision(); @@ -26,7 +26,7 @@ class Player { void tick(bave::Seconds dt); void draw(bave::Shader& shader) const; - std::optional get_controller_state(std::string_view key) const; + float get_controller_state(std::string_view key) const; bool physics_enabled{}; // for debugging }; diff --git a/DogTales/dog/player/player_controller.cpp b/DogTales/dog/player/player_controller.cpp new file mode 100644 index 0000000..1ae1ee4 --- /dev/null +++ b/DogTales/dog/player/player_controller.cpp @@ -0,0 +1,45 @@ +#include +#include +#include + +namespace dog { + +PlayerController::PlayerController(bave::NotNull app) : m_app(app) {} + +void PlayerController::bind_throttle(std::string_view const id, Throttle const throttle) { + if (throttle.hi == bave::Key::eUnknown) { return; } + auto it = m_mappings.find(id); + if (it == m_mappings.end()) { + auto [i, _] = m_mappings.insert_or_assign(std::string{id}, std::vector{}); + it = i; + } + assert(it != m_mappings.end()); + it->second.push_back(throttle); +} + +void PlayerController::bind_key(std::string_view id, bave::Key key) { + // if Throttle::lo is Key::eUnknown it will be ignored in get_state(), so we exploit that here. + bind_throttle(id, Throttle{.hi = key}); +} + +float PlayerController::get_state(std::string_view const id) const { + auto const search = m_mappings.find(id); + if (search == m_mappings.end()) { return 0.0f; } + + auto const& mappings = search->second; + auto const get_throttle_state = [&](Throttle const throttle) { + auto const is_pressed = [this](bave::Key const key) { return m_app->get_key_state().is_pressed(key); }; + if (throttle.lo != bave::Key::eUnknown && is_pressed(throttle.lo)) { return -1.0f; } + if (is_pressed(throttle.hi)) { return 1.0f; } + return 0.0f; + }; + + auto ret = 0.0f; + for (auto const& mapping : mappings) { + // later a visitor will be required here, to handle Throttle vs GamepadAxis vs GamepadButton. + ret += get_throttle_state(mapping); + } + return std::clamp(ret, -1.0f, 1.0f); +} + +} // namespace dog diff --git a/DogTales/dog/player/player_controller.hpp b/DogTales/dog/player/player_controller.hpp new file mode 100644 index 0000000..e97a055 --- /dev/null +++ b/DogTales/dog/player/player_controller.hpp @@ -0,0 +1,30 @@ +#pragma once +#include +#include +#include +#include + +namespace dog { +class PlayerController { + + public: + struct Throttle { + bave::Key lo{}; // -1 + bave::Key hi{}; // +1 + }; + + explicit PlayerController(bave::NotNull app); + + void bind_throttle(std::string_view id, Throttle throttle); + void bind_key(std::string_view id, bave::Key key); + + float get_state(std::string_view id) const; + + private: + bave::NotNull m_app; + + using Mapping = Throttle; // later to be a variant of Throttle / GamepadAxis / GamepadButton. + + std::unordered_map, bave::StringHash, std::equal_to<>> m_mappings{}; +}; +} // namespace dog