R-Type  2
Doom but in better
Loading...
Searching...
No Matches
Orchestrator.cpp
Go to the documentation of this file.
1/*
2** EPITECH PROJECT, 2024
3** rtype (Workspace)
4** File description:
5** Orchestrator.cpp
6*/
7
15
16GUI::ECS::Demo::Orchestrator::Orchestrator(const std::uint32_t entityId)
17 : EntityNode(entityId)
18{
19};
20
21void GUI::ECS::Demo::Orchestrator::initialiseClass(std::unordered_map<std::type_index, std::vector<std::any>> &ecsEntities)
22{
23 PRETTY_DEBUG << "Resetting the values stored in the class" << std::endl;
24 _ecsEntities = ecsEntities;
25 _event.reset();
26 _window.reset();
27 _spriteBullet.reset();
28 _spritePlayer.reset();
29 _spriteEnemy.reset();
30 _playerBrain.reset();
31 PRETTY_DEBUG << "The values stored in the class have been reset" << std::endl;
32
33 PRETTY_DEBUG << "Fetching the window manager" << std::endl;
34 std::any win = _ecsEntities[typeid(GUI::ECS::Systems::Window)][0];
35 const std::optional<std::shared_ptr<GUI::ECS::Systems::Window>> window_ptr = Utilities::unCast<std::shared_ptr<GUI::ECS::Systems::Window>>(win, false);
36 if (!window_ptr.has_value()) {
37 PRETTY_ERROR << "The window manager has not been found" << std::endl;
38 throw CustomExceptions::NoWindow("<No window to draw on>");
39 }
40 _window = window_ptr.value();
41 PRETTY_DEBUG << "The window manager has been fetched" << std::endl;
42
43 PRETTY_DEBUG << "Fetching the event manager" << std::endl;
44 std::any evt = _ecsEntities[typeid(GUI::ECS::Systems::EventManager)][0];
45 const std::optional<std::shared_ptr<GUI::ECS::Systems::EventManager>> event_ptr = Utilities::unCast<std::shared_ptr<GUI::ECS::Systems::EventManager>>(evt, false);
46 if (!event_ptr.has_value()) {
47 PRETTY_ERROR << "The event has been found" << std::endl;
48 throw CustomExceptions::NoEventManager("<No events to listen on>");
49 }
50 _event = event_ptr.value();
51 PRETTY_DEBUG << "The event manager has been fetched" << std::endl;
52
53 PRETTY_DEBUG << "Fetching the sprites contained in the ecs array (if present)" << std::endl;
54 const std::vector<std::any> sprites = _ecsEntities[typeid(GUI::ECS::Components::SpriteComponent)];
55
56 for (std::any node : sprites) {
57 const std::optional<std::shared_ptr<GUI::ECS::Components::SpriteComponent>> sprite = Utilities::unCast<std::shared_ptr<GUI::ECS::Components::SpriteComponent>>(node, false);
58 if (!sprite.has_value()) {
59 PRETTY_WARNING << "Sprite uncasting failed" << std::endl;
60 }
61 std::string name = sprite.value()->getName();
62 std::string applicationContext = sprite.value()->getApplication();
63
64 PRETTY_DEBUG << "Current sprite info { name: '" << name << "', application context: '" << applicationContext << "' }" << std::endl;
65
66 if (
67 applicationContext == "sprite42" || name == "r-typesheet42" ||
68 applicationContext == "sprite42" || name == "r-typesheet42"
69 ) {
70 PRETTY_DEBUG << "Sprite player has been found" << std::endl;
71 _spritePlayer = sprite.value();
72 PRETTY_DEBUG << "Sprite player content:\n" << *_spritePlayer << std::endl;
73 // } else if (
74 // applicationContext == "sprite43_laser" || name == "sprite43_laser" ||
75 // applicationContext == "sprite43_laser" || name == "sprite43_laser"
76 // ) {
77 // PRETTY_DEBUG << "Sprite bullet found" << std::endl;
78 // _spriteBullet = sprite.value();
79 // // _spriteBullet->forceTick();
80 // PRETTY_DEBUG << "Sprite bullet content:\n" << *_spriteBullet << std::endl;
81 // } else if (
82 // applicationContext == "sprite30a" || name == "sprite30a" ||
83 // applicationContext == "typesheet30a" || name == "typesheet30a"
84 // ) {
85 // PRETTY_DEBUG << "Sprite bullet found" << std::endl;
86 // _spriteBullet = sprite.value();
87 // // _spriteBullet->setDimension({ 0.5,0.5 });
88 // // _spriteBullet->forceTick();
89 // PRETTY_DEBUG << "Sprite bullet content:\n" << *_spriteBullet << std::endl;
90 // } else if (
91 // applicationContext == "sprite30b" || name == "sprite30b" ||
92 // applicationContext == "typesheet30b" || name == "typesheet30b"
93 // ) {
94 // PRETTY_DEBUG << "Sprite bullet found" << std::endl;
95 // _spriteBullet = sprite.value();
96 // // _spriteBullet->setDimension({ 0.5,0.5 });
97 // _spriteBullet->forceTick();
98 // PRETTY_DEBUG << "Sprite bullet content:\n" << *_spriteBullet << std::endl;
99 } else if (
100 applicationContext == "sprite30c" || name == "sprite30c" ||
101 applicationContext == "typesheet30c" || name == "typesheet30c"
102 ) {
103 PRETTY_DEBUG << "Sprite bullet found" << std::endl;
104 _spriteBullet = sprite.value();
105 // _spriteBullet->setDimension({ 0.5,0.5 });
106 _spriteBullet->forceTick();
107 PRETTY_DEBUG << "Sprite bullet content:\n" << *_spriteBullet << std::endl;
108 // } else if (
109 // applicationContext == "sprite3" || name == "sprite3" ||
110 // applicationContext == "r-typesheet3" || name == "r-typesheet3"
111 // ) {
112 // PRETTY_DEBUG << "Sprite bullet enemy found" << std::endl;
113 // _spriteBulletEnemy = sprite.value();
114 // _spriteBulletEnemy->setDimension({ 0.5,0.5 });
115 // _spriteBulletEnemy->forceTick();
116 // PRETTY_DEBUG << "Sprite bullet enemy content:\n" << *_spriteBulletEnemy << std::endl;
117 // } else if (
118 // applicationContext == "sprite3b" || name == "sprite3b" ||
119 // applicationContext == "r-typesheet3b" || name == "r-typesheet3b"
120 // ) {
121 // PRETTY_DEBUG << "Sprite bullet enemy found" << std::endl;
122 // _spriteBulletEnemy = sprite.value();
123 // // _spriteBulletEnemy->setDimension({ 0.5,0.5 });
124 // _spriteBullet->forceTick();
125 // PRETTY_DEBUG << "Sprite bullet enemy content:\n" << *_spriteBulletEnemy << std::endl;
126 } else if (
127 applicationContext == "sprite3c" || name == "sprite3c" ||
128 applicationContext == "r-typesheet3c" || name == "r-typesheet3c"
129 ) {
130 PRETTY_DEBUG << "Sprite bullet enemy found" << std::endl;
131 _spriteBulletEnemy = sprite.value();
132 PRETTY_DEBUG << "Sprite bullet enemy content:\n" << *_spriteBulletEnemy << std::endl;
133 } else if (
134 applicationContext == "r-typesheet13" || name == "r-typesheet13" ||
135 applicationContext == "sprite13" || name == "sprite13"
136 ) {
137 PRETTY_DEBUG << "Sprite enemy found" << std::endl;
138 _spriteEnemy = sprite.value();
139 PRETTY_DEBUG << "Sprite enemy content:\n" << *_spriteEnemy << std::endl;
140 }
141 }
142 PRETTY_DEBUG << "The sprite player has been fetched" << std::endl;
143
144 PRETTY_DEBUG << "Checking if the elements are loaded or not" << std::endl;
145 if (_spriteBullet == nullptr || _spritePlayer == nullptr || _spriteEnemy == nullptr || _spriteBulletEnemy == nullptr) {
146 PRETTY_ERROR << "The sprite player, bullet, enemy or bullet enemy has not been found" << std::endl;
147 throw CustomExceptions::NoSprite("<One of the sprites that the program attempted to load was missing>");
148 }
149 PRETTY_DEBUG << "The elements are loaded" << std::endl;
150 _setTheScene();
151 _setTextComponents();
152 PRETTY_DEBUG << "Fetching a background for the game" << std::endl;
153 const std::vector<std::any> backgrounds = _ecsEntities[typeid(GUI::ECS::Components::ImageComponent)];
154 PRETTY_DEBUG << "Declaring the ressource required for the settings menu to have a background" << std::endl;
155 std::optional<std::shared_ptr<GUI::ECS::Components::ImageComponent>> backgroundItem;
156 PRETTY_DEBUG << "Declared the ressource required for the settings menu to have a background" << std::endl;
157
158 for (std::any backgroundCast : backgrounds) {
159 std::optional<std::shared_ptr<GUI::ECS::Components::ImageComponent>> backgroundCapsule = Utilities::unCast<std::shared_ptr<GUI::ECS::Components::ImageComponent>>(backgroundCast, false);
160 if (!backgroundCapsule.has_value()) {
161 continue;
162 }
163 if (
164 backgroundCapsule.value()->getApplication() == "space" || backgroundCapsule.value()->getName() == "space" ||
165 backgroundCapsule.value()->getApplication() == "Space" || backgroundCapsule.value()->getName() == "Space"
166 ) {
167 backgroundItem.emplace(backgroundCapsule.value());
168 }
169 }
170};
171
173{
174 PRETTY_DEBUG << "The start function has been called" << std::endl;
175 _playing = true;
176 _gameOver = false;
177 _gameWon = false;
178};
179
181{
182 PRETTY_DEBUG << "The stop function has been called" << std::endl;
183 _playing = false;
184 _gameOver = false;
185 _gameWon = false;
186};
187
189{
190 PRETTY_DEBUG << "The reset function has been called" << std::endl;
191 _gameOver = false;
192 _gameWon = false;
193 _kill();
194 _setTheScene();
195 stop();
196};
197
199{
200 // Check if the class is set to calculate it's move
201 if (!_playing) {
202 PRETTY_DEBUG << "Skipping tick because we are not playing" << std::endl;
203 return;
204 }
205
206 PRETTY_DEBUG << "Orchestrator dump (before tick):\n" << getInfo(0) << std::endl;
207
208 // Declaring a list to contain the bullets to remove
209 std::vector<unsigned int> bulletsToRemove;
210
211 // Tick the player logic
212 _playerBrain->tick();
213
214 // Tick the enemy logic
215 PRETTY_DEBUG << "Ennemies on screen: " << _enemyBrain.size() << std::endl;
216 for (unsigned int index = 0; index < _enemyBrain.size(); index++) {
217 PRETTY_DEBUG << "Ticking the enemy, index: " << index << ", name: " << _enemyBrain[index]->getSprite().getName() << std::endl;
218 std::optional<GUI::ECS::Demo::Bullet> shot = _enemyBrain[index]->tick();
219 if (shot.has_value()) {
220 PRETTY_DEBUG << "Enemy shot a bullet, index: " << index << ", name: " << shot.value().getSprite().getName() << std::endl;
221 shot.value().setSize({ 0.5,0.5 });
222 PRETTY_DEBUG << "Enemy shot details: " << shot.value() << std::endl;
223 _bullets.push_back(shot.value());
224 }
225 if (_enemyBrain[index]->isColliding(_playerBrain->getCollision())) {
226 _playerBrain->setHealth(0);
227 _deadSound();
228 _gameOver = true;
229 return;
230 }
231 }
232
233 // Update player movements
234 if (_event->getKeys().size() > 0) {
235 std::pair<float, float> position = _playerBrain->getCollision().getPosition();
236
237 // Handle movement
238 if (_event->isKeyPressed(GUI::ECS::Systems::Key::Up) && position.second > 0) {
239 position.second += _stepUp;
240 } else if (_event->isKeyPressed(GUI::ECS::Systems::Key::Down) && position.second < _window->getDimensions().second - _screenPosYOffset) {
241 position.second += _stepDown;
242 } else if (_event->isKeyPressed(GUI::ECS::Systems::Key::Left) && position.first > 0) {
243 position.first += _stepLeft;
244 } else if (_event->isKeyPressed(GUI::ECS::Systems::Key::Right) && position.first < _window->getDimensions().first - _screenPosXOffset) {
245 position.first += _stepRight;
246 }
247
248 // Handle shooting
249 if (_event->isKeyPressed(GUI::ECS::Systems::Key::Space)) {
250 GUI::ECS::Demo::Bullet shot = _playerBrain->shoot();
251 shot.setSize({ 0.5,0.5 });
252 PRETTY_DEBUG << "Player shot details: " << shot << std::endl;
253 _bullets.push_back(shot);
254 _shootSound();
255 }
256
257 // Update player position
258 _playerBrain->setPosition(position);
259 }
260
261
262 // Bullets collisions
263 PRETTY_DEBUG << "Bullet count : " << _bullets.size() << std::endl;
264 for (unsigned int index = 0; index < _bullets.size(); index++) {
265 PRETTY_DEBUG << "Ticking bullet" << std::endl;
266 _bullets[index].tick();
267 PRETTY_DEBUG << "bullet: index: " << index << ", visible: " << Recoded::myToString(_bullets[index].isVisible()) << ", enemy: " << Recoded::myToString(_bullets[index].isEnemy()) << std::endl;
268 // Skipping because the bullet is not visible
269 if (!_bullets[index].isVisible()) {
270 bulletsToRemove.push_back(index);
271 continue;
272 }
273 // Checking if the bullets aren't out of bounds
274 float bulletPosX = _bullets[index].getCollision().getPositionX();
275 float bulletPosY = _bullets[index].getCollision().getPositionY();
276 if (
277 bulletPosX <= 0 || bulletPosX >= _window->getDimensions().first ||
278 bulletPosY <= 0 || bulletPosY >= _window->getDimensions().second
279 ) {
280 PRETTY_DEBUG << "Adding bullet index: " << index << " to the list of items to remove, is enemy: " << Recoded::myToString(_bullets[index].isEnemy()) << ", bullet pos: " << _bullets[index].getCollision() << std::endl;
281 bulletsToRemove.push_back(index);
282 continue;
283 }
284 // The bullet is comming from a player, if so check the enemies
285 if (!_bullets[index].isEnemy()) {
286 for (unsigned int eIndex = 0; eIndex < _enemyBrain.size(); eIndex++) {
287 // Check if the bullet has hit it's target and that the enemy is still alive
288 if (_bullets[index].isColliding(_enemyBrain[eIndex]->getCollision())) {
289 // hide the bullet an check the health
290 _bullets[index].setVisible(false);
291 if (_enemyBrain[eIndex]->getHealth() <= 0) {
292 _enemyBrain[eIndex]->setVisible(false);
293 _activeEnemies -= 1;
294 } else {
295 _enemyBrain[eIndex]->setHealth(_enemyBrain[eIndex]->getHealth() - _bullets[index].getDamage());
296 }
297 }
298 }
299 } else {
300 if (_playerBrain->isColliding(_bullets[index].getCollision())) {
301 _playerBrain->setHealth(_playerBrain->getHealth() - _bullets[index].getDamage());
302 _bullets[index].setVisible(false);
303 _damageSound();
304 }
305 }
306 }
307
308 // Removing bullets that are not rendered anymore
309 PRETTY_DEBUG << "Bullets to be removed: list size: " << bulletsToRemove.size() << std::endl;
310 for (unsigned int index = 0; index < bulletsToRemove.size(); index++) {
311 PRETTY_DEBUG << "Bullet " << index << " removed" << std::endl;
312 _bullets.erase(_bullets.begin() + bulletsToRemove[index]);
313 }
314
315 // Check if all the enemies are dead
316 unsigned int index = 0;
317 _activeEnemies = 0;
318 for (; index < _enemyBrain.size(); index++) {
319 if (_enemyBrain[index]->isVisible()) {
320 _activeEnemies += 1;
321 }
322 }
323 if (_activeEnemies <= 0) {
324 PRETTY_DEBUG << "All the enemies are dead, the game is won" << std::endl;
325 _gameWon = true;
326 }
327
328 // Check if the player is dead.
329 if (_playerBrain->getHealth() <= 0) {
330 _gameOver = true;
331 _gameWon = false;
332 }
333
334 // Updating the health text component (if present)
335 if (_titleHealth.has_value()) {
336 _titleHealth.value()->setText("Player health: " + Recoded::myToString(_playerBrain->getHealth()));
337 }
338
339 // Updating the enemy count component (if present)
340 if (_remainingEnemies.has_value()) {
341 _remainingEnemies.value()->setText("Remaining ennemies: " + Recoded::myToString(_activeEnemies));
342 }
343
344 PRETTY_DEBUG << "Orchestrator dump (after tick): \n" << getInfo(0) << std::endl;
345};
346
348{
349 PRETTY_DEBUG << "In the render function" << std::endl;
350 PRETTY_DEBUG << "Displaying the background image (if present)" << std::endl;
351 if (_backgroundItem.has_value()) {
352 PRETTY_DEBUG << "The background is present, displaying" << std::endl;
353 _window->draw(*(_backgroundItem.value()));
354 }
355 PRETTY_DEBUG << "Displayed the background image (if present)" << std::endl;
356 std::string name = _playerBrain->getSprite().getName();
357 std::pair<float, float> pos = _playerBrain->getCollision().getPosition();
358 std::pair<float, float> dim = _playerBrain->getCollision().getDimension();
359 bool visible = _playerBrain->isVisible();
360 PRETTY_DEBUG << "_playerBrain: " << Recoded::myToString(visible) << ", _enemy size: " << _enemyBrain.size() << ", _bullets size: " << _bullets.size() << std::endl;
361 PRETTY_DEBUG << "_playerBrain[" << name << "]<" << pos << ">%" << dim << "%:" << Recoded::myToString(visible) << std::endl;
362 _window->draw(_playerBrain->render());
363 PRETTY_DEBUG << "Going to render the ennemies" << std::endl;
364 unsigned int index = 0;
365 for (std::shared_ptr<GUI::ECS::Demo::EnemyBrain> item : _enemyBrain) {
366 std::string name = item->getSprite().getName();
367 std::pair<float, float> pos = item->getCollision().getPosition();
368 std::pair<float, float> dim = item->getCollision().getDimension();
369 bool visible = item->isVisible();
370 PRETTY_DEBUG << "_enemyBrain[" << name << index << "]<" << pos << ">%" << dim << "%:" << Recoded::myToString(visible) << std::endl;
371 _window->draw(item->render());
372 index++;
373 }
374 PRETTY_DEBUG << "Ennemies rendered" << std::endl;
375 PRETTY_DEBUG << "Going to render the bullets" << std::endl;
376 index = 0;
377 for (GUI::ECS::Demo::Bullet item : _bullets) {
378 std::string name = item.getSprite().getName();
379 std::pair<float, float> pos = item.getCollision().getPosition();
380 std::pair<float, float> dim = item.getCollision().getDimension();
381 bool enemy = item.isEnemy();
382 bool visible = item.isVisible();
383 PRETTY_DEBUG << "_bullets[" << name << index << "]<" << pos << ">%" << dim << "%(" << Recoded::myToString(enemy) << "):" << Recoded::myToString(visible) << std::endl;
384 _window->draw(item.render());
385 index++;
386 }
387 PRETTY_DEBUG << "Bullets rendred" << std::endl;
388 PRETTY_DEBUG << "Rendering the overlay text (if present)" << std::endl;
389 if (_titleHealth.has_value()) {
390 PRETTY_DEBUG << "Title health has a value, displaying" << std::endl;
391 _window->draw(*(_titleHealth.value()));
392 }
393 if (_remainingEnemies.has_value()) {
394 PRETTY_DEBUG << "Remaining ennemies has a value, displaying" << std::endl;
395 _window->draw(*(_remainingEnemies.value()));
396 }
397 PRETTY_DEBUG << "Displayed the overlay text (if present)" << std::endl;
398 PRETTY_DEBUG << "Out of render()" << std::endl;
399};
400
402{
403 return _gameOver;
404}
405
407{
408 return _gameWon;
409}
410
411
412const std::string GUI::ECS::Demo::Orchestrator::getInfo(const unsigned int indent) const
413{
414
415 std::string indentation = "";
416 for (unsigned int i = 0; i < indent; ++i) {
417 indentation += "\t";
418 }
419 std::string result = indentation + "Player brain:\n";
420 result += indentation + "- Entity Id: " + Recoded::myToString(getEntityNodeId()) + "\n";
421 result += indentation + "- Playing: '" + Recoded::myToString(_playing) + "'\n";
422 result += indentation + "- Game Won: '" + Recoded::myToString(_gameWon) + "'\n";
423 result += indentation + "- Game Over: '" + Recoded::myToString(_gameOver) + "'\n";
424 result += indentation + "- Step Up: '" + Recoded::myToString(_stepUp) + "'\n";
425 result += indentation + "- Step Down: '" + Recoded::myToString(_stepDown) + "'\n";
426 result += indentation + "- Step Left: '" + Recoded::myToString(_stepLeft) + "'\n";
427 result += indentation + "- Step Right: '" + Recoded::myToString(_stepRight) + "'\n";
428 result += indentation + "- Screen Position X Offset: '" + Recoded::myToString(_screenPosXOffset) + "'\n";
429 result += indentation + "- Screen Position Y Offset: '" + Recoded::myToString(_screenPosYOffset) + "'\n";
430 result += indentation + "- Active Enemies: '" + Recoded::myToString(_activeEnemies) + "'\n";
431 result += indentation + "- Title health (has value): '" + Recoded::myToString(_titleHealth.has_value()) + "'\n";
432 if (_titleHealth.has_value()) {
433 result += indentation + "- Title health: {\n" + _titleHealth.value()->getInfo(indent + 1) + indentation + "}\n";
434 }
435 result += indentation + "- Remaining enemies (has value): '" + Recoded::myToString(_remainingEnemies.has_value()) + "'\n";
436 if (_remainingEnemies.has_value()) {
437 result += indentation + "- Remaining enemies: {\n" + _remainingEnemies.value()->getInfo(indent + 1) + indentation + "}\n";
438 }
439 result += indentation + "- background item (has value): '" + Recoded::myToString(_backgroundItem.has_value()) + "'\n";
440 if (_backgroundItem.has_value()) {
441 result += indentation + "- background item: {\n" + _backgroundItem.value()->getInfo(indent + 1) + indentation + "}\n";
442 }
443 result += indentation + "- Sprite Bullet: {\n" + _spriteBullet->getInfo(indent + 1) + indentation + "}\n";
444 result += indentation + "- Sprite Bullet Enemy: {\n" + _spriteBulletEnemy->getInfo(indent + 1) + indentation + "}\n";
445 result += indentation + "- Sprite Player: {\n" + _spritePlayer->getInfo(indent + 1) + indentation + "}\n";
446 result += indentation + "- Sprite Enemy: {\n" + _spriteEnemy->getInfo(indent + 1) + indentation + "}\n";
447 result += indentation + "- Bullets: {\n";
448 for (unsigned int index = 0; index < _bullets.size(); index++) {
449 result += indentation + "\t" + Recoded::myToString(index) + ": {\n";
450 result += _bullets[index].getInfo(indent + 2);
451 result += indentation + "\t}\n";
452 }
453 result += indentation + "}\n";
454 result += indentation + "- Window: {\n" + _window->getInfo(indent + 1) + indentation + "}\n";
455 result += indentation + "- Event: {\n" + _event->getInfo(indent + 1) + indentation + "}\n";
456 result += indentation + "- Player Brain: {\n" + _playerBrain->getInfo(indent + 1) + indentation + "}\n";
457 result += indentation + "- Enemy Brains: {\n";
458 for (unsigned int index = 0; index < _enemyBrain.size(); index++) {
459 result += indentation + "\t" + Recoded::myToString(index) + ": {\n";
460 result += _enemyBrain[index]->getInfo(indent + 2);
461 result += indentation + "\t}\n";
462 }
463 result += indentation + "}\n";
464 return result;
465}
466
467
468void GUI::ECS::Demo::Orchestrator::_spawn()
469{
470 PRETTY_DEBUG << "In _spawn function in charge of creating the user" << std::endl;
471 if (_spritePlayer == nullptr) {
472 PRETTY_ERROR << "The _spritePlayer is set to nullptr" << std::endl;
473 throw CustomExceptions::NoSprite("<Sprite player not found>");
474 }
475 if (_spriteBullet == nullptr) {
476 PRETTY_ERROR << "The _spriteBullet is set to nullptr" << std::endl;
477 throw CustomExceptions::NoSprite("<Sprite bullet not found>");
478 }
479 PRETTY_DEBUG << "The _playerBrain shared pointer is going to be created" << std::endl;
480 _playerBrain = std::make_shared<GUI::ECS::Demo::PlayerBrain>();
481 PRETTY_DEBUG << "The _playerBrain shared pointer has been created" << std::endl;
482 _playerBrain->setSprite(_spritePlayer, _spriteBullet);
483 PRETTY_DEBUG << "The _playerBrain has been set with the sprites of bullet and player" << std::endl;
484 _playerBrain->setDimension({ 2,2 });
485 _playerBrain->setPosition({ 10, 60 });
486 _playerBrain->setBulletSize({ 0.5,0.5 });
487}
488
489void GUI::ECS::Demo::Orchestrator::_kill()
490{
491 PRETTY_DEBUG << "The _kill function has been called" << std::endl;
492 _playerBrain.reset();
493 for (unsigned int index = 0; index < _enemyBrain.size(); index++) {
494 PRETTY_DEBUG << "Resetting enemy: " << index << std::endl;
495 _enemyBrain[index].reset();
496 }
497 PRETTY_DEBUG << "Clearing enemy vector" << std::endl;
498 _enemyBrain.clear();
499 PRETTY_DEBUG << "Enemies cleared, size: " << _enemyBrain.size() << std::endl;
500 PRETTY_DEBUG << "Clearing remaining bullets" << std::endl;
501 unsigned int bIndex = 0;
502 while (_bullets.size() > 0) {
503 PRETTY_DEBUG << "Removing bullet: " << bIndex << ", bullet enemy: " << Recoded::myToString(_bullets[_bullets.size() - 1].isEnemy()) << std::endl;
504 _bullets.pop_back();
505 bIndex++;
506 }
507 PRETTY_DEBUG << "Removed the bullets" << std::endl;
508 PRETTY_DEBUG << "A the end of the kill function" << std::endl;
509};
510
511void GUI::ECS::Demo::Orchestrator::_spawnEnemy(const std::pair<float, float> pos)
512{
513 PRETTY_DEBUG << "In spawn enemy" << std::endl;
514 if (_spriteEnemy == nullptr) {
515 PRETTY_ERROR << "The _spriteEnemy is set to nullptr" << std::endl;
516 throw CustomExceptions::NoSprite("<Sprite enemy not found>");
517 }
518 if (_spriteBulletEnemy == nullptr) {
519 PRETTY_ERROR << "The _spriteBulletEnemy is set to nullptr" << std::endl;
520 throw CustomExceptions::NoSprite("<Sprite bullet enemy not found>");
521 }
522 PRETTY_DEBUG << "The _enemyBrain shared pointer is going to be created" << std::endl;
523 std::shared_ptr<GUI::ECS::Demo::EnemyBrain> enemy = std::make_shared<GUI::ECS::Demo::EnemyBrain>();
524 PRETTY_DEBUG << "The _enemyBrain shared pointer has been created" << std::endl;
525 enemy->setSprite(_spriteEnemy, _spriteBulletEnemy);
526 PRETTY_DEBUG << "The sprite enemy and sprite bullet enemy has been set" << std::endl;
527 enemy->setPosition(pos);
528 PRETTY_DEBUG << "The enemy has been set with the position: " << pos << std::endl;
529 enemy->setVisible(true);
530 enemy->setDimension({ 4,4 });
531 enemy->setBulletSize({ 0.5, 0.5 });
532 PRETTY_DEBUG << "The enemy is visible" << std::endl;
533 _enemyBrain.push_back(enemy);
534 PRETTY_DEBUG << "The enemy has been added to the _enemyBrain" << std::endl;
535}
536
537const int GUI::ECS::Demo::Orchestrator::_randInt(int min, int max)
538{
539 static std::random_device rd;
540 static std::mt19937 gen(rd());
541 std::uniform_int_distribution<> dist(min, max);
542 return dist(gen);
543}
544
545void GUI::ECS::Demo::Orchestrator::_setTheScene()
546{
547 PRETTY_DEBUG << "Resetting the victory and loss variables" << std::endl;
548 _gameOver = false;
549 _gameWon = false;
550 PRETTY_DEBUG << "Reset the victory and loss variables" << std::endl;
551 PRETTY_DEBUG << "Resetting the position of the items on screen" << std::endl;
552 std::pair<float, float> pos = { 1,1 };
553 _spriteBullet->setPosition(pos);
554 _spriteBulletEnemy->setPosition(pos);
555 _spriteEnemy->setPosition(pos);
556 _spritePlayer->setPosition(pos);
557 PRETTY_DEBUG << "Reset the position of the items on screen" << std::endl;
558 PRETTY_DEBUG << "Spawning the player in the screen" << std::endl;
559 _spawn();
560 PRETTY_DEBUG << "The player has been spawned" << std::endl;
561
562 PRETTY_DEBUG << "Spawning the enemies" << std::endl;
563 const float spriteHeight = _spriteEnemy->getCollision().getHeight();
564 const float spriteWidth = _spriteEnemy->getCollision().getWidth();
565 const int windowWidth = _window->getDimensions().first;
566 const int windowHeight = _window->getDimensions().second;
567 PRETTY_DEBUG << "window height: " << windowHeight << ", window width: " << windowWidth << std::endl;
568 PRETTY_DEBUG << "Sprite height: " << spriteHeight << ", sprite width: " << spriteWidth << std::endl;
569 PRETTY_DEBUG << "_screenPosXOffset: " << _screenPosXOffset << ", _screenPosYOffset: " << _screenPosYOffset << std::endl;
570 float posX = windowWidth;
571 PRETTY_DEBUG << "posX = windowWidth (" << windowWidth << ") = " << posX << std::endl;
572 PRETTY_DEBUG << "posX (" << posX << ") -= (spriteWidth (" << spriteWidth << ") + _screenPosXOffset (" << _screenPosXOffset << ")) (" << (spriteWidth + _screenPosXOffset) << ") = " << posX - (spriteWidth + _screenPosXOffset) << std::endl;
573 posX -= (spriteWidth + _screenPosXOffset);
574 float posY = spriteHeight;
575 PRETTY_DEBUG << "posX: " << posX << ", posY: " << posY << std::endl;
576 unsigned int index = 0;
577 for (; index < 4; index++) {
578 std::pair<float, float> pos = { posX - _randInt(0, spriteWidth * 4), posY };
579 PRETTY_DEBUG << "Spawning enemy : " << index << ", pos: " << pos << std::endl;
580 _spawnEnemy(pos);
581 posY += _randInt(spriteHeight * 3, spriteHeight * 4);
582 }
583 _activeEnemies = index;
584 PRETTY_DEBUG << "The enemies have been spawned" << std::endl;
585}
586
587void GUI::ECS::Demo::Orchestrator::_setTextComponents()
588{
589
590 PRETTY_DEBUG << "Setting the health value of the player" << std::endl;
591 const std::vector<std::any> fonts = _ecsEntities[typeid(GUI::ECS::Systems::Font)];
592
593 PRETTY_DEBUG << "Declaring font holder instances" << std::endl;
594 std::optional<std::shared_ptr<GUI::ECS::Systems::Font>> defaultFont;
595 std::optional<std::shared_ptr<GUI::ECS::Systems::Font>> titleFont;
596 std::optional<std::shared_ptr<GUI::ECS::Systems::Font>> bodyFont;
597 std::optional<std::shared_ptr<GUI::ECS::Systems::Font>> buttonFont;
598 PRETTY_DEBUG << "Declared font holder instances" << std::endl;
599 PRETTY_DEBUG << "Fetching the fonts that will be used in the window" << std::endl;
600 unsigned int index = 0;
601 unsigned int titleFontIndex = 0;
602 unsigned int bodyFontIndex = 0;
603 unsigned int defaultFontIndex = 0;
604 unsigned int buttonFontIndex = 0;
605 for (std::any fontCast : fonts) {
606 std::optional<std::shared_ptr<GUI::ECS::Systems::Font>> fontCapsule = Utilities::unCast<std::shared_ptr<GUI::ECS::Systems::Font>>(fontCast, false);
607 if (!fontCapsule.has_value()) {
608 continue;
609 }
610 std::string applicationContext = fontCapsule.value()->getApplication();
611 if (applicationContext == "title") {
612 titleFontIndex = index;
613 } else if (applicationContext == "body") {
614 bodyFontIndex = index;
615 } else if (applicationContext == "default") {
616 defaultFontIndex = index;
617 } else if (applicationContext == "button") {
618 buttonFontIndex = index;
619 } else {
620 index++;
621 continue;
622 }
623 index++;
624 }
625 const std::optional<std::shared_ptr<GUI::ECS::Systems::Font>> titleFontCapsule = Utilities::unCast<std::shared_ptr<GUI::ECS::Systems::Font>>(fonts[titleFontIndex], false);
626 const std::optional<std::shared_ptr<GUI::ECS::Systems::Font>> bodyFontCapsule = Utilities::unCast<std::shared_ptr<GUI::ECS::Systems::Font>>(fonts[bodyFontIndex], false);
627 const std::optional<std::shared_ptr<GUI::ECS::Systems::Font>> defaultFontCapsule = Utilities::unCast<std::shared_ptr<GUI::ECS::Systems::Font>>(fonts[defaultFontIndex], false);
628 const std::optional<std::shared_ptr<GUI::ECS::Systems::Font>> buttonFontCapsule = Utilities::unCast<std::shared_ptr<GUI::ECS::Systems::Font>>(fonts[buttonFontIndex], false);
629 if (!defaultFontCapsule.has_value()) {
630 PRETTY_DEBUG << "No default font found, aborting program" << std::endl;
631 throw CustomExceptions::NoFont("<Default font not found>");
632 }
633 defaultFont.emplace(defaultFontCapsule.value());
634 titleFont.emplace(defaultFontCapsule.value());
635 bodyFont.emplace(defaultFontCapsule.value());
636 buttonFont.emplace(defaultFontCapsule.value());
637 if (titleFontCapsule.has_value()) {
638 PRETTY_SUCCESS << "Title font found, not defaulting to the default font." << std::endl;
639 titleFont.emplace(titleFontCapsule.value());
640 }
641 if (bodyFontCapsule.has_value()) {
642 PRETTY_SUCCESS << "Body font found, not defaulting to the default font." << std::endl;
643 bodyFont.emplace(bodyFontCapsule.value());
644 }
645 if (buttonFontCapsule.has_value()) {
646 PRETTY_SUCCESS << "Button font found, not defaulting to the default font." << std::endl;
647 buttonFont.emplace(buttonFontCapsule.value());
648 }
649 PRETTY_DEBUG << "Fetched the fonts that will be used in the window" << std::endl;
650 PRETTY_DEBUG << "Creating the text to display the user's health" << std::endl;
651 const unsigned int size = 20;
652 const std::pair<float, float> posTitle = { 10,10 };
653 const std::uint32_t entityId = 0;
654 std::shared_ptr<GUI::ECS::Components::TextComponent> text = std::make_shared<GUI::ECS::Components::TextComponent>(
655 entityId,
656 *(bodyFont.value()),
657 "Player health: ",
658 size,
662 posTitle
663 );
664 _titleHealth.emplace(text);
665 const std::pair<float, float> posEnnemies = { 10, 40 };
666 std::shared_ptr<GUI::ECS::Components::TextComponent> textEnnemies = std::make_shared<GUI::ECS::Components::TextComponent>(
667 entityId,
668 *(bodyFont.value()),
669 "Remaining ennemies: ",
670 size,
674 posEnnemies
675 );
676 _remainingEnemies.emplace(textEnnemies);
677 PRETTY_DEBUG << "Fonts gathered" << std::endl;
678
679}
680
681
690void GUI::ECS::Demo::Orchestrator::_shootSound()
691{
692 if (_ecsEntities[typeid(SoundLib)].size() == 0) {
693 std::cout << "Sound is empty" << std::endl;
694 PRETTY_WARNING << "Skipping audio playing because the sound library is missing" << std::endl;
695 return;
696 }
697 std::optional<std::shared_ptr<SoundLib>> soundLib = Utilities::unCast<std::shared_ptr<SoundLib>>(_ecsEntities[typeid(SoundLib)][0], false);
698 if (!soundLib.has_value()) {
699 std::cout << "Sound lib not found" << std::endl;
700 PRETTY_WARNING << "The library to find the found player is missing, skipping sound" << std::endl;
701 return;
702 }
703 std::cout << "Calling shoot" << std::endl;
704 soundLib.value()->shootSound();
705}
706
715void GUI::ECS::Demo::Orchestrator::_damageSound()
716{
717 if (_ecsEntities[typeid(SoundLib)].size() == 0) {
718 PRETTY_WARNING << "Skipping audio playing because the sound library is missing" << std::endl;
719 return;
720 }
721 std::optional<std::shared_ptr<SoundLib>> soundLib = Utilities::unCast<std::shared_ptr<SoundLib>>(_ecsEntities[typeid(SoundLib)][0], false);
722 if (!soundLib.has_value()) {
723 PRETTY_WARNING << "The library to find the found player is missing, skipping sound" << std::endl;
724 return;
725 }
726 soundLib.value()->damageSound();
727}
728
737void GUI::ECS::Demo::Orchestrator::_deadSound()
738{
739 if (_ecsEntities[typeid(SoundLib)].size() == 0) {
740 PRETTY_WARNING << "Skipping audio playing because the sound library is missing" << std::endl;
741 return;
742 }
743 std::optional<std::shared_ptr<SoundLib>> soundLib = Utilities::unCast<std::shared_ptr<SoundLib>>(_ecsEntities[typeid(SoundLib)][0], false);
744 if (!soundLib.has_value()) {
745 PRETTY_WARNING << "The library to find the found player is missing, skipping sound" << std::endl;
746 return;
747 }
748 soundLib.value()->deadSound();
749}
750
759void GUI::ECS::Demo::Orchestrator::_buttonSound()
760{
761 if (_ecsEntities[typeid(SoundLib)].size() == 0) {
762 PRETTY_WARNING << "Skipping audio playing because the sound library is missing" << std::endl;
763 return;
764 }
765 std::optional<std::shared_ptr<SoundLib>> soundLib = Utilities::unCast<std::shared_ptr<SoundLib>>(_ecsEntities[typeid(SoundLib)][0], false);
766 if (!soundLib.has_value()) {
767 PRETTY_WARNING << "The library to find the found player is missing, skipping sound" << std::endl;
768 return;
769 }
770 soundLib.value()->buttonSound();
771}
772
781void GUI::ECS::Demo::Orchestrator::_gameOverSound()
782{
783 if (_ecsEntities[typeid(SoundLib)].size() == 0) {
784 PRETTY_WARNING << "Skipping audio playing because the sound library is missing" << std::endl;
785 return;
786 }
787 std::optional<std::shared_ptr<SoundLib>> soundLib = Utilities::unCast<std::shared_ptr<SoundLib>>(_ecsEntities[typeid(SoundLib)][0], false);
788 if (!soundLib.has_value()) {
789 PRETTY_WARNING << "The library to find the found player is missing, skipping sound" << std::endl;
790 return;
791 }
792 soundLib.value()->gameOverSound();
793}
794
803void GUI::ECS::Demo::Orchestrator::_winSound()
804{
805 if (_ecsEntities[typeid(SoundLib)].size() == 0) {
806 PRETTY_WARNING << "Skipping audio playing because the sound library is missing" << std::endl;
807 return;
808 }
809 std::optional<std::shared_ptr<SoundLib>> soundLib = Utilities::unCast<std::shared_ptr<SoundLib>>(_ecsEntities[typeid(SoundLib)][0], false);
810 if (!soundLib.has_value()) {
811 PRETTY_WARNING << "The library to find the found player is missing, skipping sound" << std::endl;
812 return;
813 }
814 soundLib.value()->winSound();
815}
816
817std::ostream &GUI::ECS::Demo::operator<<(std::ostream &os, const GUI::ECS::Demo::Orchestrator &item)
818{
819 os << item.getInfo();
820 return os;
821}
Declaration of the Orchestrator class and its related functionality.
#define PRETTY_ERROR
Error log with details and colour.
#define PRETTY_DEBUG
Debug log with details and colour.
#define PRETTY_WARNING
Warning log with details and colour.
#define PRETTY_SUCCESS
Success log with details and colour.
std::random_device rd
Definition Random.cpp:4
This is the class in charge of informing the user that they tried to access a non-existant Event Mana...
Definition No.hpp:87
This is the class in charge of informing the user that they tried to access a non-existant font insta...
Definition No.hpp:358
This is the class in charge of informing the user that they tried to access a non-existant animation ...
Definition No.hpp:298
This is the class in charge of informing the user that they tried to access a non-existant window.
Definition No.hpp:57
Represents an image component in the GUI ECS system.
Represents a drawable and interactive sprite in the ECS system.
Represents a bullet entity in the game.
Definition Bullet.hpp:31
void setSize(const std::pair< float, float > &dimension)
Sets the size of the bullet.
Definition Bullet.cpp:78
The Orchestrator class manages the overall game state, including entity creation, updates,...
void render()
Renders the game entities to the window.
void tick()
Updates the game state for the current frame.
void stop()
Stops the game logic and resets the playing state.
const bool isGameOver() const
Checks if the game is over.
const bool isGameWon() const
Checks if the game has been won.
void start()
Starts the game logic and sets the game to a playing state.
void initialiseClass(std::unordered_map< std::type_index, std::vector< std::any > > &ecsEntities)
Initializes the ECS entities managed by the orchestrator.
const std::string getInfo(const unsigned int indent=0) const
This is a function meant for debugging purposes It will dump the current state of the variables upon ...
Orchestrator(const std::uint32_t entityId=0)
Default constructor.
void reset()
Resets the game state, clearing all entities and resetting conditions.
static const Colour Cyan
Definition Colour.hpp:524
static const Colour Red
Definition Colour.hpp:322
Manages input events such as mouse movements, key presses, and window interactions.
Manages font entities in the GUI ECS.
Definition Font.hpp:45
Manages an SFML-based graphical window and handles rendering of ECS components.
Definition Window.hpp:67
The SoundLib class manages sound effects and interactions with ECS entities.
Definition SoundLib.hpp:35
std::ostream & operator<<(std::ostream &os, const Bullet &item)
Outputs the sprite's info to a stream.
Definition Bullet.cpp:259
const std::string myToString(const Rect< RectType > &rectangle)
Converts a Rect<T> object to its string representation.
Definition Rect.hpp:223
std::optional< T > unCast(const std::any &classNode, const bool raiseOnError=true, const std::string customErrorMessage="")
Casts the content of a std::any back to its original type.
Definition UnCast.hpp:65