Grid.hpp 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. #pragma once
  2. #include <SFML/Graphics.hpp>
  3. #include "IEntity.hpp"
  4. #include "Collider.hpp"
  5. #include "Log.hpp"
  6. #include "Sand.hpp"
  7. class Grid: public sf::Drawable, public IEntity {
  8. public:
  9. Grid() = delete;
  10. Grid(Collider* collider, sf::RenderWindow* window, std::vector<Sand>* sand, std::vector<Spike>* spikes, Renderer* renderer):
  11. m_collider(collider),
  12. m_window(window),
  13. m_visible(false),
  14. m_sand(sand),
  15. m_spikes(spikes),
  16. m_renderer(renderer),
  17. m_mouseRelease(false),
  18. m_csand(nullptr),
  19. m_cspike(nullptr) {
  20. m_sprite.setTexture(Asset::texture("data/arrows.png"));
  21. setType(-1);
  22. }
  23. void reset() {
  24. setType(-1);
  25. m_csand = nullptr;
  26. m_cspike = nullptr;
  27. }
  28. void sendReleaseSignal() {
  29. m_mouseRelease = true;
  30. }
  31. void update(float delta) override {
  32. static sf::Vector2i prev_mouse(0, 0);
  33. sf::Vector2i pos;
  34. sf::Vector2i curr_mouse = sf::Mouse::getPosition(*m_window);
  35. pos.x = curr_mouse.x / 64.f;
  36. pos.y = curr_mouse.y / 64.f;
  37. int mode = m_type;
  38. if(m_cspike && !sf::Mouse::isButtonPressed(sf::Mouse::Button::Left)) {
  39. m_cspike = nullptr;
  40. }
  41. if(pos.x >= 0 && pos.x < 20 && pos.y >= 0 && pos.y < 12) {
  42. int block = m_collider->getBlock(pos.x, pos.y);
  43. if(m_cspike) {
  44. } else if(m_csand) {
  45. if(block == Collider::AIR) {
  46. mode = 2;
  47. } else {
  48. mode = -1;
  49. }
  50. } else if(block == Collider::SAND) {
  51. mode = 1;
  52. } else if(block == Collider::SPIKE
  53. && (m_collider->getBlock(pos.x, pos.y - 1) == Collider::LEVER
  54. || mode == 0)) { // not checking if y>1, not needed rn
  55. mode = 0;
  56. } else {
  57. mode = -1;
  58. }
  59. } else {
  60. mode = -1;
  61. }
  62. if(mode == 0 && sf::Mouse::isButtonPressed(sf::Mouse::Button::Left)) {
  63. float mouse_w = m_renderer->getPosition() - 320 + curr_mouse.x / 2;
  64. if(!m_cspike) {
  65. auto res = std::find_if(m_spikes->begin(), m_spikes->end(), [mouse_w](Spike& s) {
  66. return s.getPosition().x <= mouse_w && s.getPosition().x + 32.f >= mouse_w;
  67. });
  68. m_cspike = &(*res);
  69. }
  70. if(m_cspike) {
  71. float delta = (curr_mouse.y - prev_mouse.y) / 2.f;
  72. int x = (m_cspike->getPosition().x - m_renderer->getPosition() + 320.f) / 32;
  73. if(delta < 0) {
  74. if(m_collider->getBlock(x, (m_cspike->getPosition().y + delta) / 32.f) == Collider::LEVER
  75. || m_collider->getBlock(x, (m_cspike->getPosition().y + delta) / 32.f) == Collider::SPIKE) {
  76. m_cspike->move(delta);
  77. m_sprite.move(0.f, delta);
  78. } else {
  79. mode = 0;
  80. }
  81. } else {
  82. if(m_collider->getBlock(x, (m_cspike->getPosition().y + 32.f + delta) / 32.f) == Collider::LEVER
  83. || m_collider->getBlock(x, (m_cspike->getPosition().y + 32.f + delta) / 32.f) == Collider::SPIKE
  84. || m_collider->getBlock(x, (m_cspike->getPosition().y + 32.f + delta) / 32.f) == Collider::AIR) {
  85. m_cspike->move(delta);
  86. m_sprite.move(0.f, delta);
  87. } else {
  88. mode = 0;
  89. }
  90. }
  91. }
  92. } else {
  93. for(Spike& s: *m_spikes) {
  94. s.release();
  95. }
  96. if(mode >= 0) {
  97. m_sprite.setPosition(pos.x * 32.f, pos.y * 32.f);
  98. }
  99. setType(mode);
  100. }
  101. if(m_mouseRelease) {
  102. if(mode == 1) {
  103. float mouse_w = m_renderer->getPosition() - 320.f + curr_mouse.x / 2.f;
  104. float mouse_h = curr_mouse.y / 2.f;
  105. auto res = std::find_if(m_sand->begin(), m_sand->end(), [mouse_w, mouse_h](Sand& s) {
  106. return s.getPosition().y <= mouse_h && s.getPosition().y + 32.f >= mouse_h
  107. && s.getPosition().x <= mouse_w && s.getPosition().x + 32.f >= mouse_w;
  108. });
  109. if(res != m_sand->end()) {
  110. res->setPosition(-32.f, -32.f);
  111. m_csand = &(*res);
  112. mode = 2;
  113. }
  114. } else if(mode == 2) {
  115. m_csand->setPosition(m_renderer->getPosition() - 320.f + pos.x * 32.f, pos.y * 32.f);
  116. mode = -1;
  117. m_csand = nullptr;
  118. }
  119. m_mouseRelease = false;
  120. }
  121. prev_mouse = curr_mouse;
  122. }
  123. private:
  124. void setType(int type) {
  125. if(type >= 0) {
  126. m_sprite.setTextureRect(sf::IntRect(
  127. type * 32,
  128. 0,
  129. 32,
  130. 32
  131. ));
  132. m_visible = true;
  133. } else {
  134. m_visible = false;
  135. }
  136. m_type = type;
  137. }
  138. void draw(sf::RenderTarget& rt, sf::RenderStates states) const override {
  139. if(m_visible) {
  140. rt.draw(m_sprite, states);
  141. }
  142. }
  143. Collider* m_collider;
  144. sf::RenderWindow* m_window;
  145. bool m_visible;
  146. std::vector<Sand>* m_sand;
  147. std::vector<Spike>* m_spikes;
  148. Renderer* m_renderer;
  149. sf::Sprite m_sprite;
  150. int m_type;
  151. bool m_mouseRelease;
  152. Sand* m_csand;
  153. Spike* m_cspike;
  154. };