Collision.h 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. /*
  2. * 2D Game Engine
  3. * Collision.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 15/02/2021.
  8. */
  9. #ifndef GAMEENGINE_COLLISION_H
  10. #define GAMEENGINE_COLLISION_H
  11. #include <ECS.h>
  12. #include <Logger.h>
  13. #include <SDL.h>
  14. #include <Components/Transform.h>
  15. #include <Components/BoxCollider.h>
  16. class CollisionSystem: public System
  17. {
  18. class BoxRect
  19. {
  20. double x0, y0, x1, y1;
  21. public:
  22. BoxRect(TransformComponent tc, BoxColliderComponent bc)
  23. {
  24. this->x0 = tc.position.x + bc.offset.x;
  25. this->x1 = this->x0 + bc.width;
  26. this->y0 = tc.position.y + bc.offset.y;
  27. this->y1 = this->y0 + bc.height;
  28. }
  29. bool collideWith(BoxRect &b) const
  30. {
  31. return ((this->x0 < b.x1) && (this->x1 > b.x0) && (this->y0 < b.y1) && (this->y1 > b.y0));
  32. }
  33. };
  34. public:
  35. CollisionSystem()
  36. {
  37. this->requireComponent<TransformComponent>();
  38. this->requireComponent<BoxColliderComponent>();
  39. }
  40. void update()
  41. {
  42. auto entities = this->getSystemEntities();
  43. for(auto entity: entities)
  44. {
  45. auto &collider = entity.getComponent<BoxColliderComponent>();
  46. collider.isColliding = false;
  47. collider.collidingList.clear();
  48. }
  49. for(auto i = entities.begin(); i != entities.end(); i++)
  50. {
  51. for(auto j = (i + 1); j != entities.end(); j++)
  52. {
  53. auto &collideA = i->getComponent<BoxColliderComponent>();
  54. auto &collideB = j->getComponent<BoxColliderComponent>();
  55. BoxRect boxA = BoxRect(i->getComponent<TransformComponent>(), collideA);
  56. BoxRect boxB = BoxRect(j->getComponent<TransformComponent>(), collideB);
  57. if (boxA.collideWith(boxB))
  58. {
  59. Logger::Debug("Entity #%d collided with #%d!", i->getId(), j->getId());
  60. collideB.isColliding = true;
  61. collideA.isColliding = true;
  62. collideA.collidingList.push_back(*j);
  63. collideB.collidingList.push_back(*i);
  64. }
  65. }
  66. }
  67. }
  68. void debugRender(SDL_Renderer *renderer)
  69. {
  70. for(auto entity: this->getSystemEntities())
  71. {
  72. auto collider = entity.getComponent<BoxColliderComponent>();
  73. auto transform = entity.getComponent<TransformComponent>();
  74. SDL_Rect rect;
  75. rect.x = static_cast<int>(transform.position.x + collider.offset.x);
  76. rect.y = static_cast<int>(transform.position.y + collider.offset.y);
  77. rect.w = static_cast<int>(collider.width);
  78. rect.h = static_cast<int>(collider.height);
  79. if (collider.isColliding)
  80. {
  81. SDL_SetRenderDrawColor(renderer, 255, 64, 16, 255);
  82. }
  83. else
  84. {
  85. SDL_SetRenderDrawColor(renderer, 64, 255, 21, 255);
  86. }
  87. SDL_RenderDrawRect(renderer, &rect);
  88. }
  89. }
  90. };
  91. #endif /* GAMEENGINE_COLLISION_H */