Skip to content

Commit b50fc93

Browse files
committed
Refactor PlayerController.
1 parent 69c1e01 commit b50fc93

8 files changed

+93
-76
lines changed

DogTales/dog/dogtales.cpp

+3-5
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,9 @@ void DogTales::tick() {
1818
if (ImGui::BeginTabItem("Player")) {
1919
bave::im_text("Controller States");
2020
ImGui::Separator();
21-
bave::im_text("move_x (Press A/D or Left/Right): {:.2f}",
22-
m_player.get_controller_state("move_x").value());
23-
bave::im_text("move_y (Press W/S or Up/Down): {:.2f}",
24-
m_player.get_controller_state("move_y").value());
25-
bave::im_text("Jump (Press 'E'): {:.2f}", m_player.get_controller_state("jump").value());
21+
bave::im_text("move_x (Press A/D or Left/Right): {:.2f}", m_player.get_controller_state("move_x"));
22+
bave::im_text("move_y (Press W/S or Up/Down): {:.2f}", m_player.get_controller_state("move_y"));
23+
bave::im_text("Jump (Press Space): {:.2f}", m_player.get_controller_state("jump"));
2624
ImGui::EndTabItem();
2725
}
2826
ImGui::EndTabBar();

DogTales/dog/dogtales.hpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#pragma once
22
#include <bave/driver.hpp>
3-
#include <dog/player.hpp>
3+
#include <dog/player/player.hpp>
44

55
namespace dog {
66
class DogTales : public bave::Driver {

DogTales/dog/player/PlayerController.cpp

-41
This file was deleted.

DogTales/dog/player/PlayerController.hpp

-18
This file was deleted.

DogTales/dog/player.cpp DogTales/dog/player/player.cpp

+10-7
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,24 @@
1-
#include <dog/player.hpp>
1+
#include <dog/player/player.hpp>
22

33
namespace dog {
44
Player::Player(bave::App& app, glm::vec2 const world_space) : m_app(app), m_world_space(world_space) {
55
m_sprite.set_size(size_v);
6+
7+
m_player_controller.bind_throttle("move_x", {.lo = bave::Key::eLeft, .hi = bave::Key::eRight});
8+
m_player_controller.bind_throttle("move_x", {.lo = bave::Key::eA, .hi = bave::Key::eD});
9+
m_player_controller.bind_throttle("move_y", {.lo = bave::Key::eDown, .hi = bave::Key::eUp});
10+
m_player_controller.bind_throttle("move_y", {.lo = bave::Key::eS, .hi = bave::Key::eW});
11+
m_player_controller.bind_key("jump", bave::Key::eSpace);
612
}
713

814
void Player::tick(bave::Seconds const dt) {
915

1016
if (physics_enabled) { m_physics.tick(dt); }
11-
m_player_controller.tick(dt, m_app);
1217

1318
auto direction = glm::vec2{};
1419

15-
direction.x += m_player_controller.get_controller_state("move_x").value();
16-
direction.y += m_player_controller.get_controller_state("move_y").value();
20+
direction.x += m_player_controller.get_state("move_x");
21+
direction.y += m_player_controller.get_state("move_y");
1722

1823
if (direction.x != 0.0f || direction.y != 0.0f) {
1924
direction = glm::normalize(direction);
@@ -26,9 +31,7 @@ void Player::tick(bave::Seconds const dt) {
2631

2732
void Player::draw(bave::Shader& shader) const { m_sprite.draw(shader); }
2833

29-
std::optional<float> Player::get_controller_state(std::string_view key) const {
30-
return m_player_controller.get_controller_state(key);
31-
}
34+
float Player::get_controller_state(std::string_view key) const { return m_player_controller.get_state(key); }
3235

3336
void Player::handle_wall_collision() {
3437
auto& position = m_physics.position;

DogTales/dog/player.hpp DogTales/dog/player/player.hpp

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
#pragma once
22
#include <bave/app.hpp>
33
#include <bave/graphics/sprite.hpp>
4-
#include "components/physics.hpp"
5-
#include "player/PlayerController.hpp"
4+
#include <dog/components/physics.hpp>
5+
#include <dog/player/player_controller.hpp>
66

77
namespace dog {
88
class Player {
@@ -16,7 +16,7 @@ class Player {
1616
bave::Sprite m_sprite{};
1717

1818
component::Physics m_physics{};
19-
PlayerController m_player_controller{};
19+
PlayerController m_player_controller{&m_app};
2020

2121
void handle_wall_collision();
2222

@@ -26,7 +26,7 @@ class Player {
2626
void tick(bave::Seconds dt);
2727
void draw(bave::Shader& shader) const;
2828

29-
std::optional<float> get_controller_state(std::string_view key) const;
29+
float get_controller_state(std::string_view key) const;
3030

3131
bool physics_enabled{}; // for debugging
3232
};
+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
#include <dog/player/player_controller.hpp>
2+
#include <algorithm>
3+
#include <cassert>
4+
5+
namespace dog {
6+
7+
PlayerController::PlayerController(bave::NotNull<bave::App const*> app) : m_app(app) {}
8+
9+
void PlayerController::bind_throttle(std::string_view const id, Throttle const throttle) {
10+
if (throttle.hi == bave::Key::eUnknown) { return; }
11+
auto it = m_mappings.find(id);
12+
if (it == m_mappings.end()) {
13+
auto [i, _] = m_mappings.insert_or_assign(std::string{id}, std::vector<Mapping>{});
14+
it = i;
15+
}
16+
assert(it != m_mappings.end());
17+
it->second.push_back(throttle);
18+
}
19+
20+
void PlayerController::bind_key(std::string_view id, bave::Key key) {
21+
// if Throttle::lo is Key::eUnknown it will be ignored in get_state(), so we exploit that here.
22+
bind_throttle(id, Throttle{.hi = key});
23+
}
24+
25+
float PlayerController::get_state(std::string_view const id) const {
26+
auto const search = m_mappings.find(id);
27+
if (search == m_mappings.end()) { return 0.0f; }
28+
29+
auto const& mappings = search->second;
30+
auto const get_throttle_state = [&](Throttle const throttle) {
31+
auto const is_pressed = [this](bave::Key const key) { return m_app->get_key_state().is_pressed(key); };
32+
if (throttle.lo != bave::Key::eUnknown && is_pressed(throttle.lo)) { return -1.0f; }
33+
if (is_pressed(throttle.hi)) { return 1.0f; }
34+
return 0.0f;
35+
};
36+
37+
auto ret = 0.0f;
38+
for (auto const& mapping : mappings) {
39+
// later a visitor will be required here, to handle Throttle vs GamepadAxis vs GamepadButton.
40+
ret += get_throttle_state(mapping);
41+
}
42+
return std::clamp(ret, -1.0f, 1.0f);
43+
}
44+
45+
} // namespace dog
+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
#pragma once
2+
#include <bave/app.hpp>
3+
#include <bave/core/string_hash.hpp>
4+
#include <unordered_map>
5+
#include <vector>
6+
7+
namespace dog {
8+
class PlayerController {
9+
10+
public:
11+
struct Throttle {
12+
bave::Key lo{}; // -1
13+
bave::Key hi{}; // +1
14+
};
15+
16+
explicit PlayerController(bave::NotNull<bave::App const*> app);
17+
18+
void bind_throttle(std::string_view id, Throttle throttle);
19+
void bind_key(std::string_view id, bave::Key key);
20+
21+
float get_state(std::string_view id) const;
22+
23+
private:
24+
bave::NotNull<bave::App const*> m_app;
25+
26+
using Mapping = Throttle; // later to be a variant of Throttle / GamepadAxis / GamepadButton.
27+
28+
std::unordered_map<std::string, std::vector<Mapping>, bave::StringHash, std::equal_to<>> m_mappings{};
29+
};
30+
} // namespace dog

0 commit comments

Comments
 (0)