43 const std::shared_ptr<eng::IAudio> &audio,
bool &showDebug,
int skinIndex,
44 const std::string &playerName)
45 : AScene(assignedId), m_renderer(renderer), m_audio(audio), m_showDebug(showDebug), m_skinIndex(skinIndex),
46 m_playerName(playerName)
48 auto ®istry = AScene::getRegistry();
50 registry.onComponentAdded(
51 [&renderer, &audio, ®istry](
const ecs::Entity e,
const std::type_info &type)
53 const auto *audioComp = registry.getComponent<
ecs::Audio>(e);
54 const auto *colorComp = registry.getComponent<
ecs::Color>(e);
55 const auto *fontComp = registry.getComponent<
ecs::Font>(e);
56 const auto *rectComp = registry.getComponent<
ecs::Rect>(e);
57 const auto *scaleComp = registry.getComponent<
ecs::Scale>(e);
58 const auto *textComp = registry.getComponent<
ecs::Text>(e);
59 const auto *textureComp = registry.getComponent<
ecs::Texture>(e);
61 const auto *hitBox = registry.getComponent<
ecs::Hitbox>(e);
63 if (hitBox && transform)
68 const auto *texture = registry.getComponent<
ecs::Texture>(e);
69 if (texture && (texture->id.find(
"pipe") != std::string::npos))
77 renderer->createCircleShape({.name =
"hitbox_" + std::to_string(e),
78 .radius = hitBox->radius,
79 .color = {.r = 255, .g = 0, .b = 0, .a = 100},
80 .
x = transform->x + hitBox->offsetX,
81 .
y = transform->y + hitBox->offsetY,
82 .outline_thickness = 1.0f,
83 .outline_color = {.r = 255, .g = 0, .b = 0, .a = 200}});
89 if (textComp && transform && fontComp)
91 renderer->createFont(fontComp->
id, fontComp->path);
93 {.font_name = fontComp->
id,
94 .color = {.r = colorComp->r, .g = colorComp->g, .b = colorComp->b, .a = colorComp->a},
95 .content = textComp->content,
96 .size = textComp->font_size,
99 .name = textComp->
id});
104 const float scale_x = scaleComp ? scaleComp->x : 1.F;
105 const float scale_y = scaleComp ? scaleComp->y : 1.F;
107 renderer->createTexture(textureComp->
id, textureComp->path);
109 if (transform && textureComp)
113 renderer->createSprite(textureComp->
id + std::to_string(e), textureComp->
id, transform->x,
114 transform->y, scale_x, scale_y,
static_cast<int>(rectComp->pos_x),
115 static_cast<int>(rectComp->pos_y), rectComp->size_x, rectComp->size_y);
119 renderer->createSprite(textureComp->
id + std::to_string(e), textureComp->
id, transform->x,
128 audio->createAudio(audioComp->path, audioComp->volume, audioComp->loop,
129 audioComp->id + std::to_string(e));
138 .with<ecs::Transform>(
"transform_player_name", 200.0F, 160.0F, 0.F)
153 .with<ecs::Transform>(
"transform_score", 50.0F, 50.0F, 0.F)
157 .with<ecs::Text>(
"id_score", std::string(
"Score: 0"), 32U)
161 registry.createEntity()
163 .with<ecs::Transform>(
"transform_loose", 0.0F, height / 2.0F, 0.F)
166 .with<ecs::Text>(
"id_loose", std::string(
"You loose, press R to restart"), 24U)
180 auto ®istry = AScene::getRegistry();
181 auto *transformLooseText = registry.getComponent<
ecs::Transform>(m_looseText);
182 auto *soundLoose = registry.getComponent<
ecs::Audio>(m_looseSound);
184 transformLooseText->x = 90000.0F;
188 transformLooseText->x = 100.0F;
189 if (!m_gameOverShown)
191 soundLoose->play =
true;
192 m_gameOverShown =
true;
197 checkCollisions(registry);
198 checkScore(registry);
202 drawDebugRectangles(registry);
205 auto *transform = registry.getComponent<
ecs::Transform>(m_playerEntity);
206 auto *velocity = registry.getComponent<
ecs::Velocity>(m_playerEntity);
207 auto *playerNameTransform = registry.getComponent<
ecs::Transform>(m_playerNameEntity);
209 if (transform && velocity)
211 constexpr float gravity = 900.f;
212 velocity->
y += gravity * dt;
215 if (playerNameTransform)
217 playerNameTransform->
x = transform->x;
218 playerNameTransform->
y = transform->y - 40.0F;
220 transform->y += velocity->
y * dt;
222 if (transform->y > size.
height - 50)
224 transform->y = size.
height - 50;
228 if (transform->y < 0)
234 m_renderer->setSpritePosition(
"player_texture" + std::to_string(m_playerEntity), transform->x, transform->y);
237 for (std::size_t i = 0; i < m_pipes.size(); ++i)
239 auto &[topPipe, bottomPipe] = m_pipes[i];
240 auto *topTransform = registry.getComponent<
ecs::Transform>(topPipe);
241 auto *botTransform = registry.getComponent<
ecs::Transform>(bottomPipe);
242 const auto *topVel = registry.getComponent<
ecs::Velocity>(topPipe);
244 if (
const auto *botVel = registry.getComponent<
ecs::Velocity>(bottomPipe);
245 topTransform && botTransform && topVel && botVel)
247 topTransform->
x += topVel->
x * dt;
248 botTransform->
x += botVel->x * dt;
250 if (topTransform->x < -150)
252 topTransform->x = size.
width + 200.f;
253 botTransform->
x = size.
width + 200.f;
257 const float gapY =
static_cast<float>(100 + rand() % (size.
height - 100 -
static_cast<int>(gapSize)));
259 const float scale =
static_cast<float>(size.
width) / 1920.f;
260 const float pipeHeight = 153.f * scale * 3.f;
261 topTransform->y = gapY - pipeHeight / 2.f;
262 botTransform->
y = gapY + gapSize + pipeHeight / 2.f;
264 if (i < m_pipeScored.size())
266 m_pipeScored[i] =
false;
270 m_renderer->setSpritePosition(
"pipe_top_texture" + std::to_string(topPipe), topTransform->x,
272 m_renderer->setSpritePosition(
"pipe_bottom_texture" + std::to_string(bottomPipe), botTransform->
x,
321 auto [width, height] = m_renderer->getWindowSize();
322 const float scale = width / 1920.f;
323 const float pipeOriginalWidth = 153.f;
324 const float pipeOriginalHeight = 22.f;
325 const float pipeScaledWidth = pipeOriginalWidth * scale * 3.f;
326 const float pipeScaledHeight = pipeOriginalHeight * scale * 3.f;
327 const float pipeRadius = pipeScaledWidth / 2.f * 1.2f;
331 .with<ecs::Velocity>(
"pipe_top_velocity", -200.f * scale, 0.f)
332 .with<
ecs::Scale>(
"pipe_top_scale", scale * 3.f, scale * 3.f)
333 .with<ecs::Texture>(
"pipe_top_texture",
"assets/sprites/flappybird-pipe-xl.png")
334 .with<
ecs::Hitbox>(
"pipe_top_hitbox", pipeRadius, 0.f, 0.f)
337 m_renderer->setSpriteRotation(
"pipe_top_texture" + std::to_string(topPipe), -90.f);
338 m_renderer->setSpriteOrigin(
"pipe_top_texture" + std::to_string(topPipe));
342 .with<
ecs::Velocity>(
"pipe_bottom_velocity", -200.f * scale, 0.f)
343 .with<ecs::Scale>(
"pipe_bottom_scale", scale * 3.f, scale * 3.f)
344 .with<
ecs::Texture>(
"pipe_bottom_texture",
"assets/sprites/flappybird-pipe-xl.png")
345 .with<ecs::Hitbox>(
"pipe_bottom_hitbox", pipeRadius, 0.f, 0.f)
348 m_renderer->setSpriteRotation(
"pipe_bottom_texture" + std::to_string(bottomPipe), 90.f);
349 m_renderer->setSpriteOrigin(
"pipe_bottom_texture" + std::to_string(bottomPipe));
351 return {topPipe, bottomPipe};
356 auto ®istry = AScene::getRegistry();
357 auto *playerTransform = registry.getComponent<
ecs::Transform>(m_playerEntity);
359 if (
auto *playerVel = registry.getComponent<
ecs::Velocity>(m_playerEntity);
360 (playerTransform !=
nullptr) && playerVel)
362 playerTransform->
x = 200.f;
363 playerTransform->y = 200.f;
367 auto [width, height] = m_renderer->getWindowSize();
368 const float scale = width / 1920.f;
369 float startX = width + 200.f;
371 for (std::size_t i = 0; i < m_pipes.size(); ++i)
373 auto &[topPipe, bottomPipe] = m_pipes[i];
374 auto *topTransform = registry.getComponent<
ecs::Transform>(topPipe);
375 if (
auto *botTransform = registry.getComponent<
ecs::Transform>(bottomPipe); topTransform && botTransform)
377 topTransform->
x = startX;
378 botTransform->x = startX;
381 const float gapY =
static_cast<float>(100 + rand() % (height - 100 -
static_cast<int>(gapSize)));
383 const float pipeHeight = 153.f * scale * 3.f;
384 topTransform->y = gapY - pipeHeight / 2.f;
385 botTransform->y = gapY + gapSize + pipeHeight / 2.f;
388 if (i < m_pipeScored.size())
390 m_pipeScored[i] =
false;
395 m_gameOverShown =
false;
397 if (
auto *scoreText = registry.getComponent<
ecs::Text>(m_scoreEntity))
399 scoreText->content =
"Score: 0";
400 m_renderer->setTextContent(
"id_score",
"Score: 0");
434 if (!playerTransform || !playerHitbox)
437 const float playerX = playerTransform->x + playerHitbox->offsetX;
438 const float playerY = playerTransform->
y + playerHitbox->offsetY;
439 const float playerRadius = playerHitbox->radius;
441 auto [width, height] = m_renderer->getWindowSize();
442 const float scale = width / 1920.f;
443 const float pipeOriginalWidth = 153.f;
444 const float pipeOriginalHeight = 22.f;
445 const float pipeScaledWidth = pipeOriginalWidth * scale * 3.f;
446 const float pipeScaledHeight = pipeOriginalHeight * scale * 3.f;
448 for (
const auto &[topPipe, bottomPipe] : m_pipes)
453 if (!topTransform || !botTransform)
456 const float topRectX = topTransform->
x - pipeScaledHeight / 2.f;
457 const float topRectY = topTransform->y - pipeScaledWidth / 2.f;
458 const float topRectW = pipeScaledHeight;
459 const float topRectH = pipeScaledWidth;
461 const float botRectX = botTransform->
x - pipeScaledHeight / 2.f;
462 const float botRectY = botTransform->
y - pipeScaledWidth / 2.f;
463 const float botRectW = pipeScaledHeight;
464 const float botRectH = pipeScaledWidth;
466 if (checkCircleRectCollision(playerX, playerY, playerRadius, topRectX, topRectY, topRectW, topRectH) ||
467 checkCircleRectCollision(playerX, playerY, playerRadius, botRectX, botRectY, botRectW, botRectH))
481 if (!playerTransform)
484 const float playerX = playerTransform->
x;
486 for (std::size_t i = 0; i < m_pipes.size(); ++i)
488 if (i >= m_pipeScored.size())
494 auto &[topPipe, bottomPipe] = m_pipes[i];
500 if (playerX > topTransform->x + 100.f)
502 m_pipeScored[i] =
true;
506 scoreText->content =
"Score: " + std::to_string(m_score);
507 m_renderer->setTextContent(
"id_score",
"Score: " + std::to_string(m_score));
515 auto [width, height] = m_renderer->getWindowSize();
516 const float scale = width / 1920.f;
517 const float pipeOriginalWidth = 153.f;
518 const float pipeOriginalHeight = 22.f;
519 const float pipeScaledWidth = pipeOriginalWidth * scale * 3.f;
520 const float pipeScaledHeight = pipeOriginalHeight * scale * 3.f;
522 const eng::Color debugColor = {.
r = 0, .g = 255, .b = 0, .a = 200};
524 for (
const auto &[topPipe, bottomPipe] : m_pipes)
529 if (!topTransform || !botTransform)
532 const float topRectX = topTransform->
x - pipeScaledHeight / 2.f;
533 const float topRectY = topTransform->y - pipeScaledWidth / 2.f;
534 const float topRectW = pipeScaledHeight;
535 const float topRectH = pipeScaledWidth;
537 const float botRectX = botTransform->
x - pipeScaledHeight / 2.f;
538 const float botRectY = botTransform->
y - pipeScaledWidth / 2.f;
539 const float botRectW = pipeScaledHeight;
540 const float botRectH = pipeScaledWidth;
542 const float step = 2.f;
543 for (
float x = topRectX; x <= topRectX + topRectW; x += step)
545 m_renderer->drawPoint(x, topRectY, debugColor);
546 m_renderer->drawPoint(x, topRectY + topRectH, debugColor);
548 for (
float y = topRectY; y <= topRectY + topRectH; y += step)
550 m_renderer->drawPoint(topRectX, y, debugColor);
551 m_renderer->drawPoint(topRectX + topRectW, y, debugColor);
554 for (
float x = botRectX; x <= botRectX + botRectW; x += step)
556 m_renderer->drawPoint(x, botRectY, debugColor);
557 m_renderer->drawPoint(x, botRectY + botRectH, debugColor);
559 for (
float y = botRectY; y <= botRectY + botRectH; y += step)
561 m_renderer->drawPoint(botRectX, y, debugColor);
562 m_renderer->drawPoint(botRectX + botRectW, y, debugColor);
constexpr auto TEXTURE_PLAYER