Air-Trap 1.0.0
A multiplayer R-Type clone game engine built with C++23 and ECS architecture
Loading...
Searching...
No Matches
InputSystem.cpp
Go to the documentation of this file.
1
11#include <SFML/Graphics.hpp>
12#include <SFML/Window/Joystick.hpp>
13
14namespace rtp::client {
15
17 // Public API
19
21 ecs::Registry& uiRegistry,
22 Settings& settings,
24 sf::RenderWindow& window)
25 : _r(r), _uiRegistry(uiRegistry), _settings(settings), _net(net), _window(window) {}
26
28 {
29 if (!_window.hasFocus())
30 return;
31 if (!_net.isUdpReady())
32 return;
33
34 if (auto inputsOpt = _uiRegistry.get<ecs::components::ui::TextInput>()) {
35 auto &inputs = inputsOpt.value().get();
36 for (const auto &e : inputs.entities()) {
37 if (inputs[e].isFocused) {
38 if (_lastMask != 0) {
40 net::InputPayload payload{0};
41 p << payload;
43 _lastMask = 0;
44 }
45 return;
46 }
47 }
48 }
49
50 uint8_t mask = 0;
51
52 // Keyboard input
53 if (sf::Keyboard::isKeyPressed(_settings.getKey(KeyAction::MoveUp)))
54 mask |= InputBits::MoveUp;
55 if (sf::Keyboard::isKeyPressed(_settings.getKey(KeyAction::MoveDown)))
56 mask |= InputBits::MoveDown;
57 if (sf::Keyboard::isKeyPressed(_settings.getKey(KeyAction::MoveLeft)))
58 mask |= InputBits::MoveLeft;
59 if (sf::Keyboard::isKeyPressed(_settings.getKey(KeyAction::MoveRight)))
61
62 bool shootPressed = sf::Keyboard::isKeyPressed(_settings.getKey(KeyAction::Shoot));
63 if (shootPressed)
64 mask |= InputBits::Shoot;
65
66 if (sf::Keyboard::isKeyPressed(_settings.getKey(KeyAction::Reload)))
67 mask |= InputBits::Reload;
68 if (sf::Keyboard::isKeyPressed(sf::Keyboard::Key::P)) // Debug: P for powerup
70
71 // Gamepad input (if enabled)
72 if (_settings.getGamepadEnabled() && sf::Joystick::isConnected(0)) {
73 float deadzone = _settings.getGamepadDeadzone();
74
75 // Left stick for movement (axes X and Y)
76 float axisX = sf::Joystick::getAxisPosition(0, sf::Joystick::Axis::X);
77 float axisY = sf::Joystick::getAxisPosition(0, sf::Joystick::Axis::Y);
78
79 if (axisY < -deadzone)
80 mask |= InputBits::MoveUp;
81 if (axisY > deadzone)
82 mask |= InputBits::MoveDown;
83 if (axisX < -deadzone)
84 mask |= InputBits::MoveLeft;
85 if (axisX > deadzone)
87
88 // D-pad for movement (PovX and PovY)
89 float povX = sf::Joystick::getAxisPosition(0, sf::Joystick::Axis::PovX);
90 float povY = sf::Joystick::getAxisPosition(0, sf::Joystick::Axis::PovY);
91
92 if (povY > 50)
93 mask |= InputBits::MoveUp;
94 if (povY < -50)
95 mask |= InputBits::MoveDown;
96 if (povX < -50)
97 mask |= InputBits::MoveLeft;
98 if (povX > 50)
100
101 // Buttons: Configurable
102 if (sf::Joystick::isButtonPressed(0, _settings.getGamepadShootButton())) {
103 shootPressed = true;
104 mask |= InputBits::Shoot;
105 }
106 if (sf::Joystick::isButtonPressed(0, _settings.getGamepadReloadButton()))
107 mask |= InputBits::Reload;
108 }
109
110 if ((mask & InputBits::Shoot) && !(_lastMask & InputBits::Shoot)) {
112 }
113
114 if (mask == _lastMask)
115 return;
116
117 _lastMask = mask;
118
119 log::info("Sending InputTick with mask: {}", (int)mask);
120
122 net::InputPayload payload{ mask };
123 p << payload;
124
126 }
127
129 {
130 auto entityRes = _r.spawn();
131 if (!entityRes) {
132 log::error("Failed to spawn sound event entity");
133 return;
134 }
135 ecs::Entity soundEntity = entityRes.value();
137 shootSound.soundPath = "assets/sounds/shoot.wav";
138 shootSound.volume = _settings.getSfxVolume() * 100.0f;
139 _r.add<ecs::components::audio::SoundEvent>(soundEntity, shootSound);
140 }
141
142} // namespace rtp::client
void sendPacket(const net::Packet &packet, net::NetworkMode mode)
Send a packet to the server.
bool isUdpReady(void) const
Check if UDP socket is ready.
uint8_t _lastMask
Last sent input mask.
InputSystem(ecs::Registry &r, ecs::Registry &uiRegistry, Settings &settings, ClientNetwork &net, sf::RenderWindow &window)
Constructor for InputSystem.
void update(float) override
Update input system logic for one frame.
ecs::Registry & _uiRegistry
Reference to the UI registry.
ClientNetwork & _net
Reference to the client network manager.
ecs::Registry & _r
Reference to the entity registry.
Settings & _settings
Reference to the client settings.
sf::RenderWindow & _window
Reference to the SFML render window.
@ MoveUp
Bitmask for input directions.
@ DebugPowerup
Debug key to spawn powerup.
Manages game settings and preferences.
Definition Settings.hpp:67
unsigned int getGamepadReloadButton() const
Definition Settings.hpp:204
sf::Keyboard::Key getKey(KeyAction action) const
Definition Settings.cpp:171
bool getGamepadEnabled() const
Definition Settings.hpp:174
unsigned int getGamepadShootButton() const
Definition Settings.hpp:194
float getSfxVolume() const
Definition Settings.hpp:89
float getGamepadDeadzone() const
Definition Settings.hpp:184
Represents an entity in the ECS (Entity-Component-System) architecture.
Definition Entity.hpp:63
auto spawn(void) -> std::expected< Entity, rtp::Error >
Definition Registry.cpp:51
auto add(Entity entity, Args &&...args) -> std::expected< std::reference_wrapper< T >, rtp::Error >
auto get(this const Self &self) -> std::expected< std::reference_wrapper< ConstLike< Self, SparseArray< T > > >, rtp::Error >
Network packet with header and serializable body.
Definition Packet.hpp:471
File : Network.hpp License: MIT Author : Elias Josué HAJJAR LLAUQUEN elias-josue.hajjar-llauquen@epit...
R-Type client namespace.
@ Reload
Action for reloading.
@ MoveRight
Action for moving right.
@ MoveDown
Action for moving down.
@ MoveUp
Action for moving up.
@ Shoot
Action for shooting.
@ MoveLeft
Action for moving left.
void error(LogFmt< std::type_identity_t< Args >... > fmt, Args &&...args) noexcept
Log an error message.
void info(LogFmt< std::type_identity_t< Args >... > fmt, Args &&...args) noexcept
Log an informational message.
@ InputTick
Client input state.
Component for triggering one-time sound effects (SFX)
float volume
Volume level (0.0 - 1.0)
std::string soundPath
Path to the sound file.
Client input state data.
Definition Packet.hpp:460