11 const std::shared_ptr<eng::IAudio> &audio)
12 : AScene(assignedId), m_renderer(renderer), m_audio(audio)
14 auto ®istry = AScene::getRegistry();
16 registry.onComponentAdded(
17 [&renderer, ®istry, &audio](
const ecs::Entity e,
const std::type_info &type)
19 const auto *audioComp = registry.getComponent<
ecs::Audio>(e);
20 const auto *colorComp = registry.getComponent<
ecs::Color>(e);
21 const auto *fontComp = registry.getComponent<
ecs::Font>(e);
22 const auto *scaleComp = registry.getComponent<
ecs::Scale>(e);
23 const auto *textComp = registry.getComponent<
ecs::Text>(e);
24 const auto *textureComp = registry.getComponent<
ecs::Texture>(e);
26 const auto *rectComp = registry.getComponent<
ecs::Rect>(e);
30 if (textComp && transform && fontComp)
32 renderer->createFont(fontComp->
id, fontComp->path);
34 {.font_name = fontComp->
id,
35 .color = {.r = colorComp->r, .g = colorComp->g, .b = colorComp->b, .a = colorComp->a},
36 .content = textComp->content,
37 .size = textComp->font_size,
40 .name = textComp->
id});
45 const float scale_x = scaleComp ? scaleComp->x : 1.F;
46 const float scale_y = scaleComp ? scaleComp->y : 1.F;
48 renderer->createTexture(textureComp->
id, textureComp->path);
50 if (transform && textureComp)
54 renderer->createSprite(textureComp->
id + std::to_string(e), textureComp->
id, transform->x,
55 transform->y, scale_x, scale_y,
static_cast<int>(rectComp->pos_x),
56 static_cast<int>(rectComp->pos_y), rectComp->size_x, rectComp->size_y);
60 renderer->createSprite(textureComp->
id + std::to_string(e), textureComp->
id, transform->x,
69 audio->createAudio(audioComp->path, audioComp->volume, audioComp->loop,
70 audioComp->id + std::to_string(e));
75 auto [width, height] = renderer->getWindowSize();
78 registry.createEntity().with<
ecs::Audio>(
"victory_sound",
"assets/audio/coin.mp3", 30.0F,
false,
true).build();
81 registry.createEntity()
83 .with<ecs::Transform>(
"title_transform", width * 0.32F, height * 0.25F, 0.F)
86 .with<ecs::Text>(
"title_text", std::string(
"VICTORY!"), 96U)
91 .with<ecs::Transform>(
"subtitle_transform", width * 0.28F, height * 0.45F, 0.F)
94 .with<ecs::Text>(
"subtitle_text", std::string(
"Mission Accomplished"), 42U)
98 registry.createEntity()
100 .with<ecs::Transform>(
"instruction_transform", width * 0.25F, height * 0.75F, 0.F)
104 .with<ecs::Text>(
"instruction_text", std::string(
"Press ENTER to quit"), 28U)
108 .with<
ecs::Transform>(
"icon_transform", width * 0.45F, height * 0.55F)
109 .with<ecs::Scale>(
"icon_scale", 0.5F, 0.5F)
118 auto ® = getRegistry();
120 m_titlePulseTime += dt;
121 m_particleSpawnTimer += dt;
123 if (
auto *titleColor = reg.getComponent<
ecs::Color>(m_titleEntity))
125 if (m_elapsedTime < 0.5F)
127 titleColor->a =
static_cast<uint8_t
>(std::min(255.0F, (m_elapsedTime / 0.5F) * 255.0F));
131 const float pulse = (std::sin(m_titlePulseTime * 3.0F) + 1.0F) * 0.5F;
139 if (
auto *titleTransform = reg.getComponent<
ecs::Transform>(m_titleEntity))
141 if (m_elapsedTime > 0.5F)
143 titleTransform->y = size.
height * 0.25F + std::sin(m_titlePulseTime * 1.5F) * 8.0F;
147 if (
auto *subtitleColor = reg.getComponent<
ecs::Color>(m_subtitleEntity))
149 if (m_elapsedTime > 0.8F && m_elapsedTime < 1.5F)
151 const float t = (m_elapsedTime - 0.8F) / 0.7F;
152 subtitleColor->a =
static_cast<uint8_t
>(std::min(255.0F, t * 255.0F));
154 else if (m_elapsedTime >= 1.5F)
156 subtitleColor->a = 255;
160 if (
auto *iconColor = reg.getComponent<
ecs::Color>(m_iconEntity))
162 if (m_elapsedTime > 1.0F && m_elapsedTime < 2.0F)
164 const float t = (m_elapsedTime - 1.0F);
165 iconColor->a =
static_cast<uint8_t
>(std::min(255.0F, t * 255.0F));
167 if (
auto *iconScale = reg.getComponent<
ecs::Scale>(m_iconEntity))
169 const float scale = 0.5F + std::sin(t * 3.14159F) * 0.2F;
170 iconScale->x = scale;
171 iconScale->y = scale;
174 else if (m_elapsedTime >= 2.0F)
177 if (
auto *iconScale = reg.getComponent<
ecs::Scale>(m_iconEntity))
179 const float breathe = 0.5F + std::sin(m_titlePulseTime * 0.8F) * 0.1F;
180 iconScale->x = breathe;
181 iconScale->y = breathe;
186 if (
auto *instructionColor = reg.getComponent<
ecs::Color>(m_instructionEntity))
188 if (m_elapsedTime > 2.5F)
190 const float blink = (std::sin(m_titlePulseTime * 2.0F) + 1.0F) * 0.5F;
191 instructionColor->a =
static_cast<uint8_t
>(150.0F + blink * 105.0F);
195 if (m_elapsedTime > 1.0F && m_particleSpawnTimer > 0.3F && m_particles.size() < 50)
197 m_particleSpawnTimer = 0.0F;
199 std::random_device rd;
200 std::mt19937 gen(rd());
201 std::uniform_real_distribution<float> angleDist(0.0F, 6.28318F);
202 std::uniform_real_distribution<float> speedDist(50.0F, 150.0F);
203 std::uniform_real_distribution<float> lifetimeDist(1.0F, 3.0F);
205 const float angle = angleDist(gen);
206 const float speed = speedDist(gen);
207 const float lifetime = lifetimeDist(gen);
212 p.
vx = std::cos(angle) * speed;
213 p.
vy = std::sin(angle) * speed;
217 p.
entity = reg.createEntity()
219 .with<ecs::Scale>(
"particle_scale", 0.15F, 0.15F)
226 m_particles.push_back(p);
229 for (
auto it = m_particles.begin(); it != m_particles.end();)
232 it->x += it->vx * dt;
233 it->y += it->vy * dt;
235 if (
auto *transform = reg.getComponent<
ecs::Transform>(it->entity))
237 transform->x = it->x;
238 transform->y = it->y;
241 if (
auto *color = reg.getComponent<
ecs::Color>(it->entity))
243 const float alpha = 1.0F - (it->lifetime / it->maxLifetime);
244 color->
a =
static_cast<uint8_t
>(std::max(0.0F, alpha * 255.0F));
247 if (it->lifetime >= it->maxLifetime)
249 it = m_particles.erase(it);