mcDungeons.cpp 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. #include "mcDungeonsgameplay.h"
  2. void McDungeonsGameplay::resolveConstrains(PhysicsComponent &player)
  3. {
  4. glm::ivec2 mapSize = {150,150};
  5. bool upTouch = 0;
  6. bool downTouch = 0;
  7. bool leftTouch = 0;
  8. bool rightTouch = 0;
  9. glm::vec2 &pos = player.position;
  10. float distance = glm::length(player.lastPos - pos);
  11. const float BLOCK_SIZE = 1.f;
  12. if (distance < BLOCK_SIZE)
  13. {
  14. checkCollisionBrute(player,
  15. pos,
  16. player.lastPos,
  17. upTouch,
  18. downTouch,
  19. leftTouch,
  20. rightTouch
  21. );
  22. }
  23. else
  24. {
  25. glm::vec2 newPos = player.lastPos;
  26. glm::vec2 delta = pos - player.lastPos;
  27. delta = glm::normalize(delta);
  28. delta *= 0.9 * BLOCK_SIZE;
  29. do
  30. {
  31. newPos += delta;
  32. glm::vec2 posTest = newPos;
  33. checkCollisionBrute(player,
  34. newPos,
  35. player.lastPos,
  36. upTouch,
  37. downTouch,
  38. leftTouch,
  39. rightTouch);
  40. if (newPos != posTest)
  41. {
  42. pos = newPos;
  43. goto end;
  44. }
  45. } while (glm::length((newPos + delta) - pos) > 1.0f * BLOCK_SIZE);
  46. checkCollisionBrute(player,
  47. pos,
  48. player.lastPos,
  49. upTouch,
  50. downTouch,
  51. leftTouch,
  52. rightTouch);
  53. }
  54. end:
  55. //clamp the box if needed
  56. //if (pos.x < 0) { pos.x = 0; leftTouch = true; }
  57. //if (pos.x + player.size.x > (mapSize.x) * BLOCK_SIZE)
  58. //{
  59. // pos.x = ((mapSize.x) * BLOCK_SIZE) - player.size.x; rightTouch = true;
  60. //}
  61. return;
  62. }
  63. void McDungeonsGameplay::checkCollisionBrute(PhysicsComponent &player, glm::vec2 &pos, glm::vec2 lastPos
  64. , bool &upTouch, bool &downTouch, bool &leftTouch, bool &rightTouch)
  65. {
  66. glm::vec2 delta = pos - lastPos;
  67. const float BLOCK_SIZE = 1.f;
  68. glm::vec2 &dimensions = player.size;
  69. glm::ivec2 mapSize = {150,150};
  70. if (
  71. (pos.y < -dimensions.y)
  72. || (pos.x < -dimensions.x)
  73. || (pos.y > mapSize.x * BLOCK_SIZE)
  74. || (pos.x > mapSize.y * BLOCK_SIZE)
  75. )
  76. {
  77. return;
  78. }
  79. glm::vec2 newPos = performCollision(player, {pos.x, lastPos.y}, {dimensions.x, dimensions.y}, {delta.x, 0},
  80. upTouch, downTouch, leftTouch, rightTouch);
  81. pos = performCollision(player, {newPos.x, pos.y}, {dimensions.x, dimensions.y}, {0, delta.y},
  82. upTouch, downTouch, leftTouch, rightTouch);
  83. }
  84. const int playerPosY = 13;
  85. glm::vec2 McDungeonsGameplay::performCollision(PhysicsComponent &player, glm::vec2 pos, glm::vec2 size,
  86. glm::vec2 delta, bool &upTouch, bool &downTouch, bool &leftTouch, bool &rightTouch)
  87. {
  88. auto aabb = [](glm::vec4 b1, glm::vec4 b2, float delta)
  89. {
  90. b2.x += delta;
  91. b2.y += delta;
  92. b2.z -= delta * 2;
  93. b2.w -= delta * 2;
  94. if (((b1.x - b2.x < b2.z)
  95. && b2.x - b1.x < b1.z
  96. )
  97. && ((b1.y - b2.y < b2.w)
  98. && b2.y - b1.y < b1.w
  99. )
  100. )
  101. {
  102. return 1;
  103. }
  104. return 0;
  105. };
  106. glm::ivec2 mapSize = {150,150};
  107. int minX = 0;
  108. int minY = 0;
  109. int maxX = mapSize.x;
  110. int maxY = mapSize.y;
  111. auto &dimensions = player.size;
  112. const float BLOCK_SIZE = 1.f;
  113. minX = (pos.x - abs(delta.x) - BLOCK_SIZE - size.x/2.f) / BLOCK_SIZE;
  114. maxX = ceil((pos.x + abs(delta.x) + BLOCK_SIZE + size.x / 2.f) / BLOCK_SIZE);
  115. minY = (pos.y - abs(delta.y) - BLOCK_SIZE - size.y / 2.f) / BLOCK_SIZE;
  116. maxY = ceil((pos.y + abs(delta.y) + BLOCK_SIZE + size.y/2.f) / BLOCK_SIZE);
  117. minX = std::max(0, minX);
  118. minY = std::max(0, minY);
  119. maxX = std::min(mapSize.x, maxX);
  120. maxY = std::min(mapSize.y, maxY);
  121. for (int y = minY; y < maxY; y++)
  122. for (int x = minX; x < maxX; x++)
  123. {
  124. if (
  125. getBlockUnsafe(x, playerPosY, y) != 0 ||
  126. getBlockUnsafe(x, playerPosY + 1, y) != 0 ||
  127. getBlockUnsafe(x, playerPosY-1, y) ==0
  128. )
  129. {
  130. if (aabb({pos - dimensions / 2.f,dimensions}, {x * BLOCK_SIZE - BLOCK_SIZE / 2.f, y * BLOCK_SIZE - BLOCK_SIZE / 2.f, BLOCK_SIZE, BLOCK_SIZE}, 0.0001f))
  131. {
  132. if (delta.x != 0)
  133. {
  134. if (delta.x < 0) // moving left
  135. {
  136. leftTouch = 1;
  137. pos.x = x * BLOCK_SIZE + BLOCK_SIZE/2.f + dimensions.x/2.f;
  138. goto end;
  139. }
  140. else
  141. {
  142. rightTouch = 1;
  143. pos.x = x * BLOCK_SIZE - BLOCK_SIZE / 2.f - dimensions.x / 2.f;
  144. goto end;
  145. }
  146. }
  147. else if (delta.y != 0)
  148. {
  149. if (delta.y < 0) //moving up
  150. {
  151. upTouch = 1;
  152. pos.y = y * BLOCK_SIZE + BLOCK_SIZE / 2.f + dimensions.y / 2.f;
  153. goto end;
  154. }
  155. else
  156. {
  157. downTouch = 1;
  158. pos.y = y * BLOCK_SIZE - BLOCK_SIZE / 2.f - dimensions.y/2.f;
  159. goto end;
  160. }
  161. }
  162. }
  163. }
  164. }
  165. end:
  166. return pos;
  167. }