BlockLayer.hpp 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. #pragma once
  2. #include <SFML/Graphics.hpp>
  3. #include <nlohmann/json.hpp>
  4. #include <vector>
  5. #include <fstream>
  6. #include <array>
  7. #include <iostream>
  8. #include <sstream>
  9. #include <cmath>
  10. #include "Log.hpp"
  11. #include "Asset.hpp"
  12. #include "Collider.hpp"
  13. #include "Sand.hpp"
  14. #include "Spike.hpp"
  15. #define CW 20
  16. #define CH 12
  17. using json = nlohmann::json;
  18. using Block = std::array<sf::Vertex, 4u>;
  19. class BlockLayer final: public sf::Drawable {
  20. public:
  21. BlockLayer() = delete;
  22. BlockLayer(const std::string& filename, const std::string& tileset):
  23. m_tex(&Asset::texture(tileset)),
  24. m_tileSize(32.f) {
  25. std::ifstream ifs(filename);
  26. json j;
  27. ifs >> j;
  28. auto layer = j["layers"][2];
  29. m_size.x = layer["width"];
  30. m_size.y = layer["height"];
  31. m_blocks.reserve(m_size.x * m_size.y);
  32. for(std::size_t i = 0; i < layer["data"].size(); ++i) {
  33. int tile = layer["data"][i];
  34. size_t x = i % m_size.x;
  35. size_t y = i / m_size.x;
  36. int collide_type = Collider::AIR;
  37. switch(tile) {
  38. case 1:
  39. collide_type = Collider::SOLID;
  40. break;
  41. case 2:
  42. collide_type = Collider::SAND;
  43. break;
  44. case 3:
  45. collide_type = Collider::LEVER;
  46. break;
  47. case 4:
  48. collide_type = Collider::SPIKE;
  49. break;
  50. default:
  51. break;
  52. }
  53. m_map.push_back(collide_type);
  54. if(0 && tile == 2) {
  55. sf::Vector2f tileOffset(x * m_tileSize, y * m_tileSize);
  56. std::size_t tileIndex = tile - 1;
  57. m_blocks.emplace_back(
  58. tileOffset,
  59. sf::Color::White,
  60. sf::Vector2f(tileIndex * m_tileSize, 0.f)
  61. );
  62. m_blocks.emplace_back(
  63. tileOffset + sf::Vector2f(m_tileSize, 0.f),
  64. sf::Color::White,
  65. sf::Vector2f((tileIndex + 1) * m_tileSize, 0.f)
  66. );
  67. m_blocks.emplace_back(
  68. tileOffset + sf::Vector2f(m_tileSize, m_tileSize),
  69. sf::Color::White,
  70. sf::Vector2f((tileIndex + 1) * m_tileSize,
  71. m_tileSize)
  72. );
  73. m_blocks.emplace_back(
  74. tileOffset + sf::Vector2f(0.f, m_tileSize),
  75. sf::Color::White,
  76. sf::Vector2f(tileIndex * m_tileSize,
  77. m_tileSize)
  78. );
  79. } else {
  80. for(std::size_t i = 0; i < 4; ++i) {
  81. m_blocks.emplace_back(sf::Vector2f(0.f, 0.f), sf::Color::White, sf::Vector2f(0.f, 0.f));
  82. }
  83. }
  84. }
  85. }
  86. ~BlockLayer() {
  87. /*for(std::size_t i = 0; i < m_blocks.size(); ++i) {
  88. if(m_blocks[i]) {
  89. delete m_blocks[i];
  90. }
  91. }*/
  92. }
  93. std::vector<int> rebuildCollider(int focus) {
  94. std::vector<int> res;
  95. res.reserve(CW * CH);
  96. for(int j = 0; j < CH; ++j) {
  97. for(int i = focus * CW; i < focus * CW + CW; ++i) {
  98. int curr = m_map[i + j * m_size.x];
  99. if(curr != Collider::SPIKE && curr != Collider::SAND) {
  100. res.push_back(m_map[i + j * m_size.x]);
  101. } else {
  102. res.push_back(Collider::AIR);
  103. }
  104. }
  105. }
  106. return res;
  107. }
  108. std::vector<Spike> reloadSpikes(int focus, Collider* collider) {
  109. std::vector<Spike> res;
  110. for(int j = 1; j < CH; ++j) {
  111. for(int i = focus * CW; i < focus * CW + CW; ++i) {
  112. if(m_map[i + j * m_size.x] == Collider::SPIKE) {
  113. res.emplace_back(collider, m_map[i + (j - 1) * m_size.x] == Collider::LEVER);
  114. res.back().setPosition(i * 32.f, j * 32.f);
  115. res.back().setTexture(Asset::texture("data/tileset.png"));
  116. res.back().setTextureRect(sf::IntRect(
  117. 96,
  118. 0,
  119. 32,
  120. 32
  121. ));
  122. }
  123. }
  124. }
  125. return res;
  126. }
  127. std::vector<Sand> reloadSand(int focus, Collider* collider) {
  128. std::vector<Sand> res;
  129. for(int j = 0; j < CH; ++j) {
  130. for(int i = focus * CW; i < focus * CW + CW; ++i) {
  131. if(m_map[i + j * m_size.x] == Collider::SAND) {
  132. res.emplace_back(collider);
  133. res.back().setPosition(i * 32.f, j * 32.f);
  134. res.back().setTexture(Asset::texture("data/tileset.png"));
  135. res.back().setTextureRect(sf::IntRect(
  136. 32,
  137. 0,
  138. 32,
  139. 32
  140. ));
  141. }
  142. }
  143. }
  144. return res;
  145. }
  146. std::vector<sf::Vertex> m_blocks;
  147. std::vector<int> m_map;
  148. BlockLayer(const BlockLayer&) = delete;
  149. BlockLayer& operator=(const BlockLayer&) = delete;
  150. //const sf::FloatRect& getGlobalBounds() const {
  151. // return m_globalBounds;
  152. //}
  153. private:
  154. const sf::Texture* m_tex;
  155. sf::Vector2u m_size;
  156. float m_tileSize;
  157. void draw(sf::RenderTarget& rt, sf::RenderStates states) const override {
  158. states.texture = m_tex;
  159. rt.draw(m_blocks.data(), m_blocks.size(), sf::Quads, states);
  160. }
  161. };