A 2D tile-based sandbox game.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. #pragma once
  2. #include "../common.h"
  3. #include "../Vector2.h"
  4. namespace Swan {
  5. class WorldPlane;
  6. class Win;
  7. namespace BodyTrait {
  8. class Body;
  9. class HasBody {
  10. public:
  11. virtual ~HasBody() = default;
  12. virtual Body &getBody() = 0;
  13. };
  14. struct Bounds {
  15. Vec2 pos;
  16. Vec2 size;
  17. float left() { return pos.x; }
  18. float right() { return pos.x + size.x; }
  19. float midX() { return pos.x + size.x / 2; }
  20. float top() { return pos.y; }
  21. float bottom() { return pos.y + size.y; }
  22. float midY() { return pos.y + size.y / 2; }
  23. Vec2 topLeft() { return { left(), top() }; }
  24. Vec2 midLeft() { return { left(), midY() }; }
  25. Vec2 bottomLeft() { return { left(), bottom() }; }
  26. Vec2 topMid() { return { midX(), top() }; }
  27. Vec2 center() { return { midX(), midY() }; }
  28. Vec2 bottomMid() { return { midX(), bottom() }; }
  29. Vec2 topRight() { return { right(), top() }; }
  30. Vec2 midRight() { return { right(), midY() }; }
  31. Vec2 bottomRight() { return { right(), bottom() }; }
  32. };
  33. class Body {
  34. public:
  35. virtual ~Body() = default;
  36. virtual Bounds getBounds() = 0;
  37. virtual void move(Vec2 rel) = 0;
  38. virtual void moveTo(Vec2 pos) = 0;
  39. };
  40. // PhysicsBody is a BodyTrait::Body which implements
  41. // a bunch of physics stuff.
  42. class PhysicsBody: public Body {
  43. public:
  44. PhysicsBody(Vec2 size, float mass, Vec2 pos = Vec2::ZERO):
  45. size_(size), mass_(mass), pos_(pos) {};
  46. BodyTrait::Bounds getBounds() override { return BodyTrait::Bounds{ pos_, size_ }; }
  47. void move(Vec2 rel) override { pos_ += rel; }
  48. void moveTo(Vec2 pos) override { pos_ = pos; }
  49. void friction(Vec2 coef = Vec2(400, 50));
  50. void gravity(Vec2 g = Vec2(0, 20));
  51. void standardForces() { friction(); gravity(); }
  52. void outline(Win &win);
  53. void update(const Swan::Context &ctx, float dt);
  54. void updateWithoutCollision(float dt);
  55. Vec2 force_ = { 0, 0 };
  56. Vec2 vel_ = { 0, 0 };
  57. bool on_ground_ = false;
  58. Vec2 size_;
  59. float mass_;
  60. Vec2 pos_;
  61. float bounciness_ = 0;
  62. float mushyness_ = 2;
  63. private:
  64. void collideX(WorldPlane &plane);
  65. void collideY(WorldPlane &plane);
  66. };
  67. // StaticBody is a BodyTrait::Body which just has a static
  68. // position and size.
  69. class StaticBody: public Body {
  70. public:
  71. StaticBody(Vec2 size, Vec2 pos):
  72. size_(size), pos_(pos) {}
  73. BodyTrait::Bounds getBounds() override { return BodyTrait::Bounds{ pos_, size_ }; }
  74. void move(Vec2 rel) override { pos_ += rel; }
  75. void moveTo(Vec2 pos) override { pos_ = pos; }
  76. Vec2 size_;
  77. Vec2 pos_;
  78. };
  79. }
  80. }