A 2D tile-based sandbox game.
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

Body.cc 2.2KB

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