Skip to main content

TwinStickInputSystem.ixx File

Input component for twin-stick gamepad controls. More...

Included Headers

Namespaces Index

namespacehelios
namespaceengine

Main engine module aggregating core infrastructure and game systems. More...

namespacemechanics

High-level gameplay systems and components for game logic. More...

namespaceinput

Input handling systems for game entities. More...

namespacesystems

Input processing systems that translate device input into game commands. More...

Classes Index

classTwinStickInputSystem

Input component for twin-stick gamepad control schemes. More...

Description

Input component for twin-stick gamepad controls.

File Listing

The file content with the documentation metadata removed is:

1/**
2 * @file TwinStickInputSystem.ixx
3 * @brief Input component for twin-stick gamepad controls.
4 */
5module;
6
7#include <memory>
8
9export module helios.engine.mechanics.input.systems.TwinStickInputSystem;
10
11import helios.math.types;
12import helios.math.utils;
13import helios.engine.ecs.GameObject;
14import helios.engine.runtime.world.UpdateContext;
15
16
17import helios.engine.state.Bindings;
18import helios.engine.runtime.messaging.command.EngineCommandBuffer;
19
20import helios.engine.mechanics.lifecycle.components.DeadTagComponent;
21
22import helios.engine.modules.physics.motion.commands.Move2DCommand;
23import helios.engine.modules.physics.motion.commands.SteeringCommand;
24import helios.engine.mechanics.combat.commands.Aim2DCommand;
25import helios.engine.mechanics.combat.commands.ShootCommand;
26
28
29import helios.engine.common.tags.SystemRole;
30
32
33 /**
34 * @brief Input component for twin-stick gamepad control schemes.
35 *
36 * @details Translates gamepad analog stick input into movement and aiming commands.
37 * The left stick controls movement direction and speed, while the right stick
38 * controls aiming direction and intensity.
39 *
40 * Each frame, this component reads the current input snapshot and generates
41 * Move2DCommand, SteeringCommand and Aim2DCommand instances that are queued in the CommandBuffer
42 * for later execution.
43 *
44 * @note Requires the owning GameObject to have Move2DComponent and Aim2DComponent
45 * attached for the generated commands to have any effect.
46 */
48
49 /**
50 * @brief Flag to indicate whether shoot commands should be derived
51 * from the aim component.
52 *
53 * If true, ShootCommands will be created from dedicated input.
54 */
55 bool useDedicatedShootInput_ = false;
56
57 /**
58 * @brief Reference to the GameObject this system reads input for.
59 */
61
62 public:
63
65
66 /**
67 * @brief Constructs a TwinStickInputSystem for the specified GameObject.
68 *
69 * @param gameObject Reference to the GameObject to generate input commands for.
70 */
72 gameObject_(gameObject) {}
73
74 /**
75 * @brief Processes gamepad input and generates movement/aiming commands.
76 *
77 * @param updateContext Context containing input snapshot and command buffer.
78 */
80
81 auto& inputSnapshot = updateContext.inputSnapshot();
82
83 // Left stick: movement
84 const auto leftStick = inputSnapshot.gamepadState().left();
85 float finalSpeed = 0.0f;
86 float speed = leftStick.length();
87 auto ldir = helios::math::vec2f{0.0f, 0.0f};
88
89 // Right stick: aiming
90 const auto rightStick = inputSnapshot.gamepadState().right();
91 float freq = rightStick.length();
92 float finalFreq = 0.0f;
93 auto rdir = helios::math::vec2f{0.0f, 0.0f};
94
95 if (gameObject_.has<DeadTagComponent>()) {
97 gameObject_.entityHandle(), ldir, finalSpeed
98 );
100 gameObject_.entityHandle(), rdir, finalFreq
101 );
102 return;
103 }
104
105 if (speed > helios::math::EPSILON_LENGTH) {
106 ldir = leftStick.normalize();
107 finalSpeed = speed;
108 }
109 /**
110 * @todo DO NOT POST IF input is already inactive in shootComponent
111 * and no input was detected (after normalizing)
112 */
114 gameObject_.entityHandle(), ldir, finalSpeed
115 );
116
118 gameObject_.entityHandle(), ldir, finalSpeed
119 );
120
122 rdir = rightStick.normalize();
123 finalFreq = freq;
124 }
125
127 gameObject_.entityHandle(), rdir, finalFreq
128 );
129
130 if (useDedicatedShootInput_) {
131 // right trigger: shooting
132 const auto rightTrigger = inputSnapshot.gamepadState().triggerRight();
133 if (rightTrigger > 0.0f) {
135 gameObject_.entityHandle(), rightTrigger
136 );
137 }
138 } else {
139 if (finalFreq > 0.0f) {
141 gameObject_.entityHandle(), finalFreq
142 );
143 }
144 }
145
146
147
148 }
149
150 /**
151 * @brief Enables or disables dedicated shoot input mode.
152 *
153 * @param useDedicatedInput If true, ShootCommands use the right trigger.
154 * If false, the aim stick magnitude is used.
155 */
156 void setUseDedicatedShootInput(bool useDedicatedInput) noexcept {
157 useDedicatedShootInput_ = useDedicatedInput;
158 }
159
160 /**
161 * @brief Returns whether dedicated shoot input mode is enabled.
162 *
163 * @return True if ShootCommands use the right trigger, false if aim magnitude is used.
164 */
165 [[nodiscard]] bool useDedicatedShootInput() const noexcept {
166 return useDedicatedShootInput_;
167 }
168
169 };
170
171
172}

Generated via doxygen2docusaurus 2.0.0 by Doxygen 1.15.0.