ProjectileEmit.h 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. /*
  2. * 2D Game Engine
  3. * ProjectileEmit.h:
  4. * Based on pikuma.com 2D game engine in C++ and Lua course
  5. * Copyright (c) 2021 986-Studio. All rights reserved.
  6. *
  7. * Created by Manoël Trapier on 27/02/2021.
  8. */
  9. #ifndef GAMEENGINE_SOURCE_INCLUDE_SYSTEMS_PROJECTILEEMIT_H
  10. #define GAMEENGINE_SOURCE_INCLUDE_SYSTEMS_PROJECTILEEMIT_H
  11. #include <SDL.h>
  12. #include <ECS.h>
  13. #include <Components/ProjectileEmitter.h>
  14. #include <Components/RigidBody.h>
  15. #include <Components/Sprite.h>
  16. #include <Components/Transform.h>
  17. #include <Components/BoxCollider.h>
  18. #include <Components/Projectile.h>
  19. #include <Components/CameraFollow.h>
  20. class ProjectileEmitSystem: public System
  21. {
  22. public:
  23. ProjectileEmitSystem()
  24. {
  25. this->requireComponent<ProjectileEmitterComponent>();
  26. this->requireComponent<TransformComponent>();
  27. }
  28. void subscriptToEvents(std::unique_ptr<EventBus> &eventBus)
  29. {
  30. eventBus->subscribeToEvent<KeyPressedEvent>(this, &ProjectileEmitSystem::onKeyPressed);
  31. }
  32. void onKeyPressed(KeyPressedEvent &event)
  33. {
  34. if (event.keyCode == SDLK_SPACE)
  35. {
  36. for (auto entity: this->getSystemEntities())
  37. {
  38. if (entity.hasComponent<CameraFollowComponent>())
  39. {
  40. auto &emitter = entity.getComponent<ProjectileEmitterComponent>();
  41. const auto transform = entity.getComponent<TransformComponent>();
  42. const auto rigidBody = entity.getComponent<RigidBodyComponent>();
  43. Entity projectile = entity.registry->createEntity();
  44. glm::vec2 projectilePosition = transform.position;
  45. if ( entity.hasComponent<SpriteComponent>() )
  46. {
  47. auto sprite = entity.getComponent<SpriteComponent>();
  48. projectilePosition.x += (transform.scale.x * sprite.width) / 2.;
  49. projectilePosition.y += (transform.scale.y * sprite.height) / 2.;
  50. }
  51. glm::vec2 projectileVelocity = glm::vec2(0, 0);
  52. if (rigidBody.velocity.x != 0)
  53. {
  54. projectileVelocity.x = (rigidBody.velocity.x > 0) ? emitter.projectileVelocity.x : -emitter.projectileVelocity.x;
  55. }
  56. if (rigidBody.velocity.y != 0)
  57. {
  58. projectileVelocity.y = (rigidBody.velocity.y > 0) ? emitter.projectileVelocity.y : -emitter.projectileVelocity.y;
  59. }
  60. projectile.addComponent<TransformComponent>(projectilePosition, glm::vec2(1, 1), 0);
  61. projectile.addComponent<RigidBodyComponent>(projectileVelocity);
  62. projectile.addComponent<SpriteComponent>("bullet-image", 4, 4, 4);
  63. projectile.addComponent<BoxColliderComponent>(4, 4);
  64. projectile.addComponent<ProjectileComponent>(emitter.projectileDuration, emitter.hitPercentDamage, emitter.isFriendly);
  65. emitter.lastEmissionTime = SDL_GetTicks();
  66. }
  67. }
  68. }
  69. }
  70. void update(std::unique_ptr<Registry> &registry)
  71. {
  72. for(auto entity: this->getSystemEntities())
  73. {
  74. auto &emitter = entity.getComponent<ProjectileEmitterComponent>();
  75. const auto transform = entity.getComponent<TransformComponent>();
  76. if ((emitter.repeatFrequency > 0) && ((SDL_GetTicks() - emitter.lastEmissionTime) > emitter.repeatFrequency))
  77. {
  78. Entity projectile = registry->createEntity();
  79. glm::vec2 projectilePosition = transform.position;
  80. if ( entity.hasComponent<SpriteComponent>() )
  81. {
  82. auto sprite = entity.getComponent<SpriteComponent>();
  83. projectilePosition.x += (transform.scale.x * sprite.width) / 2.;
  84. projectilePosition.y += (transform.scale.y * sprite.height) / 2.;
  85. }
  86. projectile.addComponent<TransformComponent>(projectilePosition, glm::vec2(1, 1), 0);
  87. projectile.addComponent<RigidBodyComponent>(emitter.projectileVelocity);
  88. projectile.addComponent<SpriteComponent>("bullet-image", 4, 4, 4);
  89. projectile.addComponent<BoxColliderComponent>(4, 4);
  90. projectile.addComponent<ProjectileComponent>(emitter.projectileDuration, emitter.hitPercentDamage, emitter.isFriendly);
  91. emitter.lastEmissionTime = SDL_GetTicks();
  92. }
  93. }
  94. }
  95. };
  96. #endif /* GAMEENGINE_SOURCE_INCLUDE_SYSTEMS_PROJECTILEEMIT_H */