r-type  0.0.0
R-Type main
Loading...
Searching...
No Matches
menu.cpp
Go to the documentation of this file.
1#include <cmath>
2
4#include "ECS/Component.hpp"
5#include "Utils/Common.hpp"
6
7cli::Menu::Menu(const eng::id assignedId, const std::shared_ptr<eng::IRenderer> &renderer) : AScene(assignedId)
8{
9 auto &registry = AScene::getRegistry();
10
11 registry.onComponentAdded(
12 [&renderer, &registry](const ecs::Entity e, const std::type_info &type)
13 {
14 const auto *colorComp = registry.getComponent<ecs::Color>(e);
15 const auto *fontComp = registry.getComponent<ecs::Font>(e);
16 const auto *rectComp = registry.getComponent<ecs::Rect>(e);
17 const auto *scaleComp = registry.getComponent<ecs::Scale>(e);
18 const auto *textComp = registry.getComponent<ecs::Text>(e);
19 const auto *textureComp = registry.getComponent<ecs::Texture>(e);
20 const auto *transform = registry.getComponent<ecs::Transform>(e);
21
22 if (type == typeid(ecs::Text))
23 {
24 if (textComp && transform && fontComp)
25 {
26 renderer->createFont(fontComp->id, fontComp->path);
27 renderer->createText(
28 {.font_name = fontComp->id,
29 .color = {.r = colorComp->r, .g = colorComp->g, .b = colorComp->b, .a = colorComp->a},
30 .content = textComp->content,
31 .size = textComp->font_size,
32 .x = transform->x,
33 .y = transform->y,
34 .name = textComp->id});
35 }
36 }
37 else if (type == typeid(ecs::Texture))
38 {
39 const float scale_x = scaleComp ? scaleComp->x : 1.F;
40 const float scale_y = scaleComp ? scaleComp->y : 1.F;
41
42 renderer->createTexture(textureComp->id, textureComp->path);
43
44 if (transform && textureComp)
45 {
46 if (rectComp)
47 {
48 renderer->createSprite(textureComp->id + std::to_string(e), textureComp->id, transform->x,
49 transform->y, scale_x, scale_y, static_cast<int>(rectComp->pos_x),
50 static_cast<int>(rectComp->pos_y), rectComp->size_x, rectComp->size_y);
51 }
52 else
53 {
54 renderer->createSprite(textureComp->id + std::to_string(e), textureComp->id, transform->x,
55 transform->y);
56 }
57 }
58 }
59 });
60
62 registry.createEntity()
63 .with<ecs::Font>("main_font", utl::Path::Font::FONTS_RTYPE)
64 .with<ecs::Transform>("transform_title", 100.F, 60.F, 0.F)
67 .with<ecs::Text>("id", std::string("RTYPE"), 72U)
68 .build();
69
70 for (size_t i = 0; i < m_menuOptions.size(); ++i)
71 {
72 registry.createEntity()
73 .with<ecs::Font>("main_font", utl::Path::Font::FONTS_RTYPE)
74 .with<ecs::Transform>("transform_menu", 100.F, 200.F + i * 60.F, 0.F)
78 .with<ecs::Text>("menu_" + m_menuOptions[i], m_menuOptions[i], 32U)
79 .build();
80 }
81
82 std::string contributorsText = "Contributors ";
83 for (size_t i = 0; i < m_contributors.size(); ++i)
84 {
85 contributorsText += m_contributors[i];
86 if (i < m_contributors.size() - 1)
87 {
88 contributorsText += " ";
89 }
90 }
92 registry.createEntity()
93 .with<ecs::Font>("main_font", utl::Path::Font::FONTS_RTYPE)
94 .with<ecs::Transform>("transform_contributors", renderer->getWindowSize().width * 0.9F,
95 renderer->getWindowSize().height * 0.9F)
96 .with<ecs::Color>("color_contributors", utl::Config::Color::GRAY_BLUE_SUBTLE.r,
99 .with<ecs::Text>("contributors_text", contributorsText, 24U)
100 .build();
101
102 m_selectedIndex = 2;
103}
104
105void cli::Menu::update(const float dt, const eng::WindowSize &size)
106{
107 auto &reg = getRegistry();
108
109 auto &transforms = reg.getAll<ecs::Transform>();
110 auto &colors = reg.getAll<ecs::Color>();
111 m_animationTime += dt;
112 m_titlePulseTime += dt;
113
114 if (auto *titleColor = reg.getComponent<ecs::Color>(m_titleEntity))
115 {
116 const float pulse = (std::sin(m_titlePulseTime * 1.2f) + 1.0f) * 0.5f;
117 titleColor->r = static_cast<uint8_t>(utl::Config::Color::CYAN_ELECTRIC.r * (0.8f + pulse * 0.2f));
118 titleColor->g = static_cast<uint8_t>(utl::Config::Color::CYAN_ELECTRIC.g * (0.8f + pulse * 0.2f));
119 titleColor->b = static_cast<uint8_t>(utl::Config::Color::CYAN_ELECTRIC.b * (0.9f + pulse * 0.1f));
120 }
121
122 if (auto *titleTransform = reg.getComponent<ecs::Transform>(m_titleEntity))
123 {
124 titleTransform->y = 60.0f + std::sin(m_titlePulseTime * 0.8f) * 2.0f;
125 }
126
127 auto &texts = reg.getAll<ecs::Text>();
128 size_t i = 0;
129 for (auto &[entity, text] : texts)
130 {
131 if (text.content == "Solo" || text.content == "Multi" || text.content == "Settings")
132 {
133 auto &color = colors.at(entity);
134
135 if (i == m_selectedIndex)
136 {
137 const float glowIntensity = std::sin(m_animationTime * 2.5f);
138 color.r = 0U;
139 color.g = static_cast<unsigned char>(191U + (glowIntensity * 50));
140 color.b = 255U;
141 }
142 else
143 {
147 }
148
149 i++;
150 }
151 }
152 m_contributorsOffset += dt * 50.0f;
153 if (auto *contributorsTransform = reg.getComponent<ecs::Transform>(m_contributorsEntity))
154 {
155 contributorsTransform->x = (size.width * 0.9f) - m_contributorsOffset;
156
157 if (contributorsTransform->x < -(size.width * 0.9F))
158 {
159 m_contributorsOffset = 0.0f;
160 contributorsTransform->x = size.width * 0.9f;
161 }
162 }
163}
164
165void cli::Menu::event(const eng::Event &event)
166{
167 switch (event.type)
168 {
170 {
171 const int previousIndex = m_selectedIndex;
172 bool handledNavigation = false;
173
174 if (event.key == eng::Key::Up)
175 {
176 handledNavigation = true;
177 if (m_selectedIndex == 2)
178 {
179 m_selectedIndex = 0;
180 }
181 else
182 {
183 m_selectedIndex++;
184 }
185 }
186 else if (event.key == eng::Key::Down)
187 {
188 handledNavigation = true;
189 if (m_selectedIndex == 0)
190 {
191 m_selectedIndex = 2;
192 }
193 else
194 {
195 m_selectedIndex--;
196 }
197 }
198 else if (event.key == eng::Key::Enter)
199 {
200 const std::string &selectedOption =
201 m_menuOptions[static_cast<int>(m_menuOptions.size()) - 1 - m_selectedIndex];
202 if (onOptionSelected)
203 {
204 onOptionSelected(selectedOption);
205 }
206 }
207
208 if (handledNavigation && m_selectedIndex != previousIndex)
209 {
210 m_playMusic = true;
211 }
212 break;
213 }
214
216 if (event.key == eng::Key::Up)
217 {
218 m_keysPressed[eng::Key::Up] = false;
219 }
220 if (event.key == eng::Key::Down)
221 {
222 m_keysPressed[eng::Key::Down] = false;
223 }
224 if (event.key == eng::Key::Left)
225 {
226 m_keysPressed[eng::Key::Left] = false;
227 }
228 if (event.key == eng::Key::Right)
229 {
230 m_keysPressed[eng::Key::Right] = false;
231 }
232 if (event.key == eng::Key::Space)
233 {
234 m_keysPressed[eng::Key::Space] = false;
235 }
236 break;
237
238 default:
239 break;
240 }
241}
This file contains the component definitions.
This file contains the menu scene.
Menu(eng::id assignedId, const std::shared_ptr< eng::IRenderer > &renderer)
Definition menu.cpp:7
void event(const eng::Event &event) override
Definition menu.cpp:165
ecs::Entity m_contributorsEntity
Definition Menu.hpp:49
const std::vector< std::string > m_menuOptions
Definition Menu.hpp:41
ecs::Entity m_titleEntity
Definition Menu.hpp:46
const std::vector< std::string > m_contributors
Definition Menu.hpp:48
void update(float dt, const eng::WindowSize &size) override
Definition menu.cpp:105
int m_selectedIndex
Definition Menu.hpp:43
This file contains common definitions and constants.
std::uint32_t Entity
Definition Entity.hpp:13
unsigned int id
Definition IScene.hpp:20
static constexpr eng::Color GRAY_BLUE_SUBTLE
Definition Common.hpp:57
static constexpr eng::Color CYAN_ELECTRIC
Definition Common.hpp:56
constexpr auto FONTS_RTYPE
Definition Common.hpp:97
unsigned char r
Definition Component.hpp:26
std::string id
Definition Component.hpp:15
unsigned char r
Definition IRenderer.hpp:17
unsigned char a
Definition IRenderer.hpp:20
unsigned char g
Definition IRenderer.hpp:18
unsigned char b
Definition IRenderer.hpp:19
EventType type
unsigned int width