r-type  0.0.0
R-Type main
Loading...
Searching...
No Matches
Starfield.hpp
Go to the documentation of this file.
1///
2/// @file Starfield.hpp
3/// @brief Starfield System for managing background stars and visual effects
4/// @namespace ecs
5///
6
7#pragma once
8
9#include <cmath>
10#include <ranges>
11
12#include "ECS/Component.hpp"
14#include "ECS/Registry.hpp"
16#include "Utils/Common.hpp"
17
18namespace ecs
19{
20
21 class StarfieldSystem final : public ASystem
22 {
23 public:
24 explicit StarfieldSystem(const std::shared_ptr<eng::IRenderer> &renderer, Registry &registry)
25 : m_renderer(renderer)
26 {
28 }
29 ~StarfieldSystem() override = default;
30
35
36 void update(Registry &registry, const float dt) override
37 {
38 auto [width, height] = m_renderer->getWindowSize();
39 const float screenWidth = static_cast<float>(width);
40 const float screenHeight = static_cast<float>(height);
41
43
44 eng::Color cachedColor{};
45 bool isStar = false;
46 bool isNear = false;
47 bool isMid = false;
48
49 for (auto &pair : registry.getAll<Pixel>())
50 {
51 const auto entity = pair.first;
52 auto *transform = registry.getComponent<Transform>(entity);
53 if (!transform)
54 continue;
55
56 const auto *velocity = registry.getComponent<Velocity>(entity);
57 if (velocity)
58 {
59 transform->x += velocity->x * dt;
60 transform->y += velocity->y * dt;
61
62 if (transform->x < -10.0f || transform->x > screenWidth + 10.0f || transform->y < -10.0f ||
63 transform->y > screenHeight + 10.0f)
64 {
65 transform->x = screenWidth + std::rand() % 200;
66 transform->y = static_cast<float>(std::rand() % static_cast<int>(screenHeight));
67 }
68 }
69
70 const auto *color = registry.getComponent<Color>(entity);
71 if (!color)
72 continue;
73
74 const Pixel *pixel = registry.getComponent<Pixel>(entity);
75 if (!pixel)
76 continue;
77
78 const std::string &pixelId = pixel->id;
79 isStar = (pixelId == "star_far" || pixelId == "star_mid" || pixelId == "star_near");
80 isNear = (pixelId == "star_near");
81 isMid = (pixelId == "star_mid");
82
83 unsigned char finalAlpha = color->a;
84 if (isStar)
85 {
86 float starPhase = (transform->x * 0.1f + transform->y * 0.15f + m_timeAccumulator * 0.8f);
87 float twinkle = (std::sin(starPhase) + 1.0f) * 0.5f;
88 finalAlpha = static_cast<unsigned char>(color->a * (0.5f + twinkle * 0.5f));
89 }
90
91 cachedColor = {.r = color->r, .g = color->g, .b = color->b, .a = finalAlpha};
92
93 m_renderer->drawPoint(transform->x, transform->y, cachedColor);
94
95 if (isNear)
96 {
97 cachedColor.a = static_cast<unsigned char>(finalAlpha * 0.8f);
98 m_renderer->drawPoint(transform->x + 0.8f, transform->y, cachedColor);
99 }
100 else if (isMid)
101 {
102 cachedColor.a = static_cast<unsigned char>(finalAlpha * 0.7f);
103 m_renderer->drawPoint(transform->x + 0.5f, transform->y, cachedColor);
104 }
105 }
106 }
107
108 private:
109 const std::shared_ptr<eng::IRenderer> &m_renderer;
110 float m_timeAccumulator = 0.0f;
111
112 static void createStarfield(Registry &registry, const eng::WindowSize &windowSize)
113 {
114 createStars(registry, 60, windowSize.width, windowSize.height, utl::Config::Color::WHITE_TRANS, -20.0f,
115 "star_far");
116 createStars(registry, 35, windowSize.width, windowSize.height, utl::Config::Color::BLUE, -40.0f,
117 "star_mid");
118 createStars(registry, 25, windowSize.width, windowSize.height, utl::Config::Color::YELLOW, -80.0f,
119 "star_near");
120 createStarsVaried(registry, 15, windowSize.width, windowSize.height, -25.0f, "star_far");
121 createStarsVaried(registry, 12, windowSize.width, windowSize.height, -50.0f, "star_mid");
122 createShootingStars(registry, 8, windowSize.width, windowSize.height);
123 createPlanets(registry, 4, windowSize.width, windowSize.height);
124 createNebulae(registry, 3, windowSize.width, windowSize.height);
125 createComets(registry, 6, windowSize.width, windowSize.height);
126 }
127 static void createStars(Registry &registry, const int count, const unsigned int screenWidth,
128 const unsigned int screenHeight, const eng::Color &color, float velocity,
129 const std::string &id)
130 {
131 for (int i = 0; i < count; ++i)
132 {
133 registry.createEntity()
134 .with<Pixel>(id)
135 .with<Transform>(id + "_transform", static_cast<float>(std::rand() % screenWidth),
136 static_cast<float>(std::rand() % screenHeight), 0.0f)
137 .with<Color>(id + "_color", color.r, color.g, color.b, color.a)
138 .with<Velocity>(id + "_vel", velocity, 0.0f)
139 .build();
140 }
141 }
142 static void createShootingStars(Registry &registry, const int count, const unsigned int screenWidth,
143 const unsigned int screenHeight)
144 {
145 for (int i = 0; i < count; ++i)
146 {
147 registry.createEntity()
148 .with<Pixel>("star_shooting")
149 .with<Transform>("star_shooting_transform", static_cast<float>(std::rand() % screenWidth),
150 static_cast<float>(std::rand() % screenHeight), 0.0f)
151 .with<Color>("star_shooting_color", utl::Config::Color::GREEN.r, utl::Config::Color::GREEN.g,
153 .with<Velocity>("star_shooting_vel", -120.0f, static_cast<float>((std::rand() % 20) - 10))
154 .build();
155 }
156 }
157 static void createPlanets(Registry &registry, const int count, const unsigned int screenWidth,
158 const unsigned int screenHeight)
159 {
160 for (int i = 0; i < count; ++i)
161 {
162 registry.createEntity()
163 .with<Pixel>("planet_far")
164 .with<Transform>("planet_far_transform", static_cast<float>(std::rand() % screenWidth),
165 static_cast<float>(std::rand() % screenHeight), 0.0f)
168 .with<Velocity>("planet_far_vel", -5.0f, 0.0f)
169 .build();
170 }
171 }
172 static void createNebulae(Registry &registry, const int count, const unsigned int screenWidth,
173 const unsigned int screenHeight)
174 {
175 for (int i = 0; i < count; ++i)
176 {
177 registry.createEntity()
178 .with<Pixel>("nebula")
179 .with<Transform>("nebula_transform", static_cast<float>(std::rand() % screenWidth),
180 static_cast<float>(std::rand() % screenHeight), 0.0f)
181 .with<Color>("nebula_color", utl::Config::Color::BLUE_SECOND.r,
184 .with<Velocity>("nebula_vel", -8.0f, 0.0f)
185 .build();
186 }
187 }
188 static void createComets(Registry &registry, const int count, const unsigned int screenWidth,
189 const unsigned int screenHeight)
190 {
191 for (int i = 0; i < count; ++i)
192 {
193 registry.createEntity()
194 .with<Pixel>("comet")
195 .with<Transform>("comet_transform", static_cast<float>(std::rand() % screenWidth),
196 static_cast<float>(std::rand() % screenHeight), 0.0f)
199 .with<Velocity>("comet_vel", -60.0f, static_cast<float>((std::rand() % 40) - 20))
200 .build();
201 }
202 }
203
204 static void createStarsVaried(Registry &registry, const int count, const unsigned int screenWidth,
205 const unsigned int screenHeight, float velocity, const std::string &baseId)
206 {
207 for (int i = 0; i < count; ++i)
208 {
209 int colorType = std::rand() % 4;
210 unsigned char r, g, b, a;
211
212 switch (colorType)
213 {
214 case 0: // Blanc froid
215 r = 200;
216 g = 220;
217 b = 255;
218 a = 180;
219 break;
220 case 1: // Cyan
221 r = 150;
222 g = 230;
223 b = 255;
224 a = 200;
225 break;
226 case 2: // Bleu doux
227 r = 100;
228 g = 150;
229 b = 255;
230 a = 160;
231 break;
232 default: // Jaune pâle
233 r = 255;
234 g = 250;
235 b = 200;
236 a = 170;
237 break;
238 }
239
240 registry.createEntity()
241 .with<Pixel>(baseId)
242 .with<Transform>(baseId + "_transform", static_cast<float>(std::rand() % screenWidth),
243 static_cast<float>(std::rand() % screenHeight), 0.0f)
244 .with<Color>(baseId + "_color", r, g, b, a)
245 .with<Velocity>(baseId + "_vel", velocity, 0.0f)
246 .build();
247 }
248 }
249 }; // class StarfieldSystem
250} // namespace ecs
This file contains the component definitions.
This file contains the IRenderer class declaration.
This file contains the interface for systems.
This file contains the Registry class declaration.
Abstract class for system.
Definition ISystems.hpp:34
EntityBuilder & with(Args &&...args)
Definition Registry.hpp:40
Class for managing entities and their components.
Definition Registry.hpp:25
EntityBuilder createEntity()
Definition Registry.hpp:53
std::unordered_map< Entity, T > & getAll()
Definition Registry.hpp:77
T * getComponent(Entity e)
Definition Registry.hpp:71
StarfieldSystem & operator=(const StarfieldSystem &)=delete
static void createStars(Registry &registry, const int count, const unsigned int screenWidth, const unsigned int screenHeight, const eng::Color &color, float velocity, const std::string &id)
static void createNebulae(Registry &registry, const int count, const unsigned int screenWidth, const unsigned int screenHeight)
static void createComets(Registry &registry, const int count, const unsigned int screenWidth, const unsigned int screenHeight)
~StarfieldSystem() override=default
static void createStarfield(Registry &registry, const eng::WindowSize &windowSize)
void update(Registry &registry, const float dt) override
Definition Starfield.hpp:36
static void createShootingStars(Registry &registry, const int count, const unsigned int screenWidth, const unsigned int screenHeight)
static void createStarsVaried(Registry &registry, const int count, const unsigned int screenWidth, const unsigned int screenHeight, float velocity, const std::string &baseId)
StarfieldSystem(const std::shared_ptr< eng::IRenderer > &renderer, Registry &registry)
Definition Starfield.hpp:24
StarfieldSystem(const StarfieldSystem &)=delete
StarfieldSystem & operator=(StarfieldSystem &&)=delete
static void createPlanets(Registry &registry, const int count, const unsigned int screenWidth, const unsigned int screenHeight)
const std::shared_ptr< eng::IRenderer > & m_renderer
StarfieldSystem(StarfieldSystem &&)=delete
virtual WindowSize getWindowSize()=0
virtual void drawPoint(float x, float y, Color color)=0
This file contains common definitions and constants.
static constexpr eng::Color PURPLE
Definition Common.hpp:70
static constexpr eng::Color BLUE_SECOND
Definition Common.hpp:69
static constexpr eng::Color WHITE_TRANS
Definition Common.hpp:67
static constexpr eng::Color BLUE
Definition Common.hpp:68
static constexpr eng::Color YELLOW
Definition Common.hpp:60
static constexpr eng::Color GREEN
Definition Common.hpp:71
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
unsigned int width
unsigned int height