A 2D tile-based sandbox game.
Du kannst nicht mehr als 25 Themen auswählen Themen müssen mit entweder einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

BodyTrait.cc 2.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. #include "traits/BodyTrait.h"
  2. #include <math.h>
  3. #include <array>
  4. #include <algorithm>
  5. #include "WorldPlane.h"
  6. #include "Win.h"
  7. namespace Swan {
  8. namespace BodyTrait {
  9. static float epsilon = 0.0001;
  10. void PhysicsBody::friction(Vec2 coef) {
  11. force_ += -vel_ * coef;
  12. }
  13. void PhysicsBody::gravity(Vec2 g) {
  14. force_ += g * mass_;
  15. }
  16. void PhysicsBody::collideX(WorldPlane &plane) {
  17. auto bounds = getBounds();
  18. bool collided = false;
  19. for (int y = (int)floor(bounds.top() + epsilon); y <= (int)floor(bounds.bottom() - epsilon); ++y) {
  20. int lx = (int)floor(bounds.left() + epsilon);
  21. Tile &left = plane.getTile({ lx, y });
  22. if (left.is_solid_) {
  23. bounds.pos.x = (float)lx + 1.0;
  24. collided = true;
  25. break;
  26. }
  27. int rx = (int)floor(bounds.right() - epsilon);
  28. Tile &right = plane.getTile({ rx, y });
  29. if (right.is_solid_) {
  30. bounds.pos.x = (float)rx - bounds.size.x;
  31. collided = true;
  32. break;
  33. }
  34. }
  35. if (collided) {
  36. pos_.x = bounds.pos.x;
  37. vel_.x *= -bounciness_;
  38. if (abs(vel_.x) < mushyness_)
  39. vel_.x = 0;
  40. }
  41. }
  42. void PhysicsBody::collideY(WorldPlane &plane) {
  43. auto bounds = getBounds();
  44. bool collided = false;
  45. on_ground_ = false;
  46. for (int x = (int)floor(bounds.left() + epsilon); x <= (int)floor(bounds.right() - epsilon); ++x) {
  47. int by = (int)floor(bounds.bottom() - epsilon);
  48. Tile &bottom = plane.getTile({ x, by });
  49. if (bottom.is_solid_) {
  50. bounds.pos.y = (float)by - bounds.size.y;
  51. collided = true;
  52. on_ground_ = true;
  53. break;
  54. }
  55. int ty = (int)floor(bounds.top() + epsilon);
  56. Tile &top = plane.getTile({ x, ty });
  57. if (top.is_solid_) {
  58. bounds.pos.y = (float)ty + 1.0;
  59. collided = true;
  60. break;
  61. }
  62. }
  63. if (collided) {
  64. pos_.y = bounds.pos.y;
  65. vel_.y *= -bounciness_;
  66. if (abs(vel_.y) < mushyness_)
  67. vel_.y = 0;
  68. }
  69. }
  70. void PhysicsBody::outline(Win &win) {
  71. win.drawRect(pos_, size_);
  72. }
  73. void PhysicsBody::update(WorldPlane &plane, float dt) {
  74. vel_ += (force_ / mass_) * dt;
  75. force_ = { 0, 0 };
  76. pos_.x += vel_.x * dt;
  77. collideX(plane);
  78. pos_.y += vel_.y * dt;
  79. collideY(plane);
  80. }
  81. void PhysicsBody::updateWithoutCollision(float dt) {
  82. vel_ += (force_ / mass_) * dt;
  83. pos_ += vel_ * dt;
  84. force_ = { 0, 0 };
  85. }
  86. }
  87. }